diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d17347a0ad7..68fe9de68d6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -116,13 +116,13 @@ a process to follow to optimize the chance to have PRs merged efficiently... Also, some code changes need a prior approbation: -* if you want to include a new external library (into htdocs/includes directory), please ask before to the core project manager (mention @dolibarr-yoda in your issue) to see if such a library can be accepted. +* if you want to include a new external library (into htdocs/includes directory), please ask before to the core project manager (mention @dolibarr-jedi in your issue) to see if such a library can be accepted. -* if you add a new table, you must first create a page on https://wiki.dolibarr.org/index.php/Category:Table_SQL (copy an existing page changing its name to see it into this index page). Then ask the project manager (@dolibarr-yoda) if the new data model you plan to add is compatible with curent and future works in progress and can be accepted as you suggest. +* if you add a new tables or fields, you MUST first submit a standalone PR with the data structure changes you plan to add/modify (and only data structure changes). Start development only once this data structure has been accepted. Once a PR has been submitted, you may need to wait for its integration. It is common that the project leader let the PR open for a long delay to allow every developer discuss about the PR (A label is added in such a case). -If the label of PR start with "Draft" or "WIP" (Work In Progress), it will not be analyzed for merging until you change the label of PR (but it can be analyzed for discussion). +If the label of PR start with "Draft" or "WIP" (Work In Progress), it will not be analyzed for merging until you change the label of the PR (but it can be analyzed for discussion). If your PR has errors reported by the Continuous Integration Platform, it means your PR is not valid and nothing will be done with it. It will be kept open to allow developers to fix this, or it may be closed several month later. Don't expect anything on your PR if you have such errors, you MUST first fix the Continuous Integration error to have it taken into consideration. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 84deea18f00..13a3e6fa77b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,18 +1,18 @@ # Instructions *This is a template to help you make good pull requests. You may use [Github Markdown](https://help.github.com/articles/getting-started-with-writing-and-formatting-on-github/) syntax to format your issue report.* *Please:* -- *only keep the "Fix", "Close" or "New" section* +- *only keep the "FIX", "CLOSE" or "NEW" section* (use uppercase to have the PR appears into the ChangeLog, lowercase will not appears) - *follow the project [contributing guidelines](/.github/CONTRIBUTING.md)* - *replace the bracket enclosed texts with meaningful information* -# Fix #[*issue_number Short description*] +# FIX|Fix #[*issue_number Short description*] [*Long description*] -# Close #[*issue_number Short description*] +# CLOSE|Close #[*issue_number Short description*] [*Long description*] -# New [*Short description*] +# NEW|New [*Short description*] [*Long description*] diff --git a/ChangeLog b/ChangeLog index cd9397939f5..1c0e96fc27c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,233 @@ English Dolibarr ChangeLog -------------------------------------------------------------- + +***** ChangeLog for 15.0.0 compared to 14.0.0 ***** + +For users: +--------------- + +NEW: Online proposal signature +NEW: Can define some max limit on expense report (per period, per type or expense, ...) +NEW: Allow the use of __NEWREF__ to get for example the new reference a draft order will get after validation. +NEW: Add option to disable globaly some notifications emails. +NEW: #18326 Workflow: Close order on shipment closing. +NEW: #18401 Add __NEWREF__ subtitute to get new object reference. +NEW: #18403 Add __URL_SHIPMENT__ substitute to get the URL of a shipment +NEW: #18689 REST API module: add api key generate / modify right. +NEW: #18663 Make "L'Annuaire des Entreprises" the default provider for SIREN verification for French thirdparties. +NEW: #18046 Add tags on ticket/categories +NEW: #18326 Workflow: Close order on shipment closing. +NEW: #18770 Can enter the buying price (for Weighted Average Price update) on lines during the reception step +NEW: #18814 Add legal form for Sweden +NEW: #18820 Accountancy - Add product account in import/export of thirdparty (level 3) +NEW: Accountancy - Format FEC/FEC2 - Add column NumFacture +NEW: Add $dolibarr_main_db_readonly in conf.php for readonly access. +NEW: add auto creation of agenda event on supplier_order cancellation +NEW: Add a PDF document template for Manufacturing Orders +NEW: Add budget field into task #18986 +NEW: add cancel button to `classify reception` form on supplier_orders +NEW: Added address field into contacts list +NEW: Added documents page and send mail possibility in payments +NEW: Add edit option in propal +NEW: Added linked files page and send mail possibility in payments +NEW: Add field date from/to in customer and supplier payment list +NEW: Add filter from date to date into action/evt list +NEW: Add import / export of MO and BOMLines - Close #18499 +NEW: Adding accounting export model for iSuite Expert +NEW: add link to an element by ref +NEW: add missing printFieldListFrom hook call on several lists +NEW: add MRP into Object Linked Box +NEW: Add option to hide customer code on PDF documents +NEW: Add param $nolog to avoid logging into dol_delete_recursive_dir() +NEW: Add sale representative in order and invoice list +NEW: add a setting to create PDF in PDF/A - 1b format #18990 +NEW: Add `SOCIETE_SHOW_VAT_IN_LIST` to display VAT number in combo list of thirdparties +NEW: Add sortorder on units list +NEW: Adds PDF_HIDE_PRODUCT_LABEL_IN_SUPPLIER_LINES to hide product label in supplier order lines +NEW: Add STOCK_MOVEMENT_LIST_HIDE_UNIT_PRICE to hide unit price on some pages +NEW: add support for zstd compression +NEW: Allow drag and drop on kits +NEW: Allow exporting supplier order validation date + validation user +NEW: Allows product ref generation after the form is validated with PRODUCT_GENERATE_REF_AFTER_FORM +NEW: autocomplete account group when editing an account card +NEW: Auto create invoice for payment done on an order with online payment link of order +NEW: Can edit fields of proposal when proposal is not yet signed +NEW: Can edit the translation key of an overwrote translation key. +NEW: can enable/disable external calendar by default +NEW: Can hide sender name on PDF documents +NEW: Can select lot from a combo list of existing batch numbers (in MRP consumtion) +NEW: Can set the default BOM on a product +NEW: Can set/unset the usual working day of the week (friday, saturday, sunday) +NEW: Can show progression of task into combo list of tasks +NEW: can upload the odt file for the product doc template +NEW: Contract - Add From/to input on search date +NEW: Customer Display with TakePOS +NEW: Split Sale in TakePOS +NEW: Customer invoice template list - Add input date from/to +NEW: date filter on project list and task list From->To +NEW: display shipping method and tracking url on shipment list +NEW: expense reports: conf to force amounts to be entered only including taxes +NEW: expense reports: conf to pre-fill start/end dates with bounds of current month +NEW: expense reports: show link to already existing overlapping expense report +NEW: expense reports: can make project field mandatory on lines +NEW: Expose bank account holder, label and number +NEW: feature #18986 +NEW: field and behavior in product object +NEW: generate intervention from time spent +NEW: holiday: handle monthly balance updates with cronjob +NEW: HRM integration, source code +NEW: HRM admin - Add tabs +NEW: HRM - Include more options to manage/custom dashboard +NEW: Increase size of params of actions for emailcollector +NEW: Invoice list - Use complete country select field with EEC or not +NEW: mass action delete, no more break if at least one object has child +NEW: mass action paid on customer invoice list +NEW: massaction validate on supplier orders list +NEW: Mass action send email to all attendees of an event. +NEW: expense reports: conf to pre-fill start/end dates with bounds of current month +NEW: Option "Add a link on the PDF to make the online payment" +NEW: More options to generate PDF (show Frame option, width of picture option) +NEW: Preview of pdf files of expense report lines +NEW: print without details +NEW: project time spent: conf to prevent recording time after X months +NEW: rewrite bind accountancy code finding on customer and sales invoice +NEW: Societe - Add perentity functionality on customer/supplier accountancy auxiliary account +NEW: Survey - Add a clickable link in email send +NEW: Social Contributions - Add from/to filter on list +NEW: Supplier order and proposal - Add From/to input on search date +NEW: Task - Add From/to input on search date +NEW: Add theme option THEME_ELDY_USEBORDERONTABLE +NEW: The Anti-CSRF protection MAIN_SECURITY_CSRF_WITH_TOKEN is on to value 1 by default +NEW: Update SQL : install and migration +NEW: Use an ajax call for the clicktodial feature instead of href link. +NEW: when multiple order linked to facture, show list into note. +NEW: when we delete several objects with massaction, if somes object has child we must see which objects are concerned and nevertheless delete objects which can be deleted +NEW: Editing a page in website module keep old page with name .back + + +For developers: +--------------- + +NEW: Introduce method hasRight +NEW: Can use textarea field into a confirm popup. +NEW: Can use the result_mode of mysqli driver. Save memory for list count +NEW: #18319 REST API - Shipment: Add 'close' action / endpoint / POST method. +NEW: add action trigger for member excluded +NEW: add option MAIN_IBAN_IS_NEVER_MANDATORY, MAIN_IBAN_NOT_MANDATORY, PROPAL_NOT_BILLABLE, PROPAL_REOPEN_UNSIGNED_ONLY, PROPOSAL_ARE_NOT_BILLABLE, TICKETS_MESSAGE_FORCE_MAIL +NEW: Add code codebar column on serial/lot structure +NEW: Add date_valid and date_approve columns in the list of supplier orders +NEW: add hook `beforeBodyClose` +NEW: Add hook hookGetEntity. +NEW: add hookmanager on note pages +NEW: add hook 'menuLeftMenuItems' to filter the leftmenu items +NEW: Add the property "copytoclipboard" in modulebuilder +NEW: api for knowledgemanagement +NEW: API get list of legal form of business +NEW: API list of staff units +NEW: hook after rank update +NEW: printFieldListFrom hook call on several lists +NEW: Use lang selector when using a field key 'lang' in modulebuilder +NEW: we need to be able to put more filters on deleteByParentField() function +NEW: make it easier to set the `keyword`, `keywords` and `description` attributes of an ecm file object + + + +Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: +* Update hook 'printOriginObjectLine', removed check on product type and special code. Need now reshook. +* Old deprecated module "SimplePOS" has been completely removed. Use module "TakePOS" is you need a Point Of Sale. +* The method static ActionComm::getActions($db, ...) is no more static. Use $actioncomm->getActions(...) instead (without $db param). +* The 'action=delete&file=...' has been replaced with 'action=deletefile&file=...' to avoid confusion with deletion of object lines. +* Method getDictvalue has been renamed into getDictionaryValue to match camel case rule. + + + +***** ChangeLog for 14.0.3 compared to 14.0.2 ***** + +FIX: #18698 Supplier invoice list - "alert" checkbox not working +FIX: #18735 +FIX: #18767 : Member delete +FIX: #18854 +FIX: #18910 : MRP List SQL query syntax error with more than one extrafileds. +FIX: Accountancy - Format Quadra export - Missing line type C to create automaticly a subledger account with label +FIX: Accountancy - Missing specific filename for export on format FEC2, Ciel & repare it +FIX: Accountancy - Option of export popup are inverted +FIX: Accountancy - Some correction on export name +FIX: Accountancy - Trunc code_journal to 2 in format XIMPORT (Ciel, Sage50) +FIX: add warehouse in projects' overview count +FIX: autocalculation of the supplier price in main currency. +FIX: avoid warning if $categories is an id +FIX: Bad use of a forced contact of another company on PDF/ODT documents +FIX: Button text on proposal card to create a invoice +FIX: calculateCosts of BOM must not be included into fetch +FIX: check if greater 0 +FIX: default language defined for IN country +FIX: fetch of product with modulebuilder load too much data +FIX: Filter on categories +FIX: indentation +FIX: init hookmanager after loading $conf values +FIX: legal issue on expense report pdf (must also show price without tax) +FIX: missing filter status=1 on rss feeds +FIX: move fetch_optionnal into $ac_static->fetch() +FIX: payment using wrong type in takepos when too many payment mode +FIX: Product accountancy affectation with product_perentity activated (PR #18620) +FIX: products/services card: hidden extrafields were overridden +FIX: Propal list - Problem of pagination on date +FIX: selected lines on supplier invoice create +FIX: Selection of type "people" for membership must hide the company +FIX: select list of orders not complete when field type of company is on +FIX: support of localtax on expense report +FIX: task time: can't filter by user with pgsql + show error message +FIX: task time: keep on using natural_search +FIX: Test when date of invoie is in future (pb with TZ and offset) +FIX: translation into email for member at membership validation. +FIX: unprivileged user can see task associated with a not allowed project +FIX: user without permission can set ticket subject + +***** ChangeLog for 14.0.2 compared to 14.0.1 ***** + +FIX: #18353 Invoice list translation issue +FIX: #18375 SQL Error on tasks statistics +FIX: #18465 +FIX: #18484 +FIX: #18531 +FIX: #18542 REST API: set global $user variable to DolibarrApiAccess::user. +FIX: #18544 Shipment REST API: load thirdparty object into the shipment before validating. +FIX: #18544 Shipment rest api: load thirdparty object when validating +FIX: #18565 +FIX: #18589 #18617 +FIX: #18591 : Remove double quotes of SQL Queries for postgresql compatibility +FIX: #18666 Order / Shipment list: Don't SQL JOIN category table when not necessary. +FIX: Accountancy - Some problems of length with general & subledger account +FIX: add DISTINCT +FIX: Add option $noescapecommand in executeCLI for better compatibility +FIX: Add token to remove error when removing widget +FIX: Add token when remove the last widget on home page +FIX: an approved holiday can be canceled by an admin. +FIX: better sql request +FIX: change LOG_DEBUG with LOG_WARNING in syslog and remove sql error in syslog (already done) +FIX: Collapsing of extrafields has disappeared. +FIX: Date of payment of subscription must not be set to 1970-01-01. +FIX: Export of website generates a package that contains a sql error +FIX: Field already present in SQL request +FIX: increase maxlength of password input +FIX: invoice fetch not found syslog debug level instead of error +FIX: Invoice list - Wrong name for column total_tva +FIX: invoice validation: when checking if any vat rate has a negative amount, prevent false positives with -1E-14 amounts +FIX: Manage credit note on situation invoice for calculate margin +FIX: Menu List of project was not visible. +FIX: migration script +FIX: multicompany transverse mode compatibility +FIX: option "Default value for field 'Refuse bulk emailings'" +FIX: Recommended session.cookie_samesite must be 'Lax' not 'Strict'. +FIX: Relative discount with high nb of decimals +FIX: salary extrafields don't work and table is not well named +FIX: Supplier invoice list - Wrong language key used +FIX: wrong table_element_line +FIX: wrong users count in multicompany transverse mode +FIX: #yogosha6944 Protection against traversal path. + + ***** ChangeLog for 14.0.1 compared to 14.0.0 ***** FIX: $conf->task used but it does not exist, use $conf->projet instead @@ -42,19 +269,6 @@ FIX: using Tulip, deposit mask was not saved FIX: #yogosha6907 -***** ChangeLog for 15.0.0 compared to 14.0.0 ***** - -For developers: ---------------- - -WARNING: - -Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: -* Update hook 'printOriginObjectLine', removed check on product type and special code. Need now reshook. -* Old deprecated module "SimplePOS" has been completely removed. Use module "TakePOS" is you need a Point Of Sale. - - - ***** ChangeLog for 14.0.0 compared to 13.0.0 ***** For users: @@ -285,6 +499,37 @@ Following changes may create regressions for some external modules, but were nec * v14 seems to work correctly on PHP v8 but it generates a lot of verbose warnings. Currently, v14 i snot yet officialy supported with PHP 8. + +***** ChangeLog for 13.0.5 compared to 13.0.4 ***** + +FIX: 13.0: class CommandeFournisseurDispatch provides trigger for UPDATE but not for CREATE / DELETE +FIX: #18389 Accountancy - Bug on LDcompta10 export for supplier invoice +FIX: #18591 : Remove double quotes of SQL Queries for postgresql compatibility +FIX: Accountancy - Debug Export Sage50 / CIEL Compta / CIEL Compta Evo (Format XIMPORT) +FIX: Accountancy - Some problems of length with general & subledger account +FIX: add DISTINCT +FIX: an approved holiday can be canceled by an admin. +FIX: autocalculation of the supplier price in main currency. +FIX: better sql request +FIX: cannot add time spend when column ref is not displayed +FIX: compatibility postgre sql +FIX: holiday card: hooks uninitialized +FIX: Invoice - Missing button to reopen an abandoned situation invoice +FIX: invoice validation: when checking if any VAT rate has a negative amount, prevent false positives with -1.0E-14 amounts +FIX: list of categories in stats of supplier invoices +FIX: Manage credit note on situation invoice for calculate margin +FIX: method_exists needs object at first param +FIX: move fetch_optionnal into $ac_static->fetch() +FIX: multicompany transverse mode compatibility +FIX: on supplier order, JOIN with product fourn price table must be done with fk_soc too to avoid display several times a same line (because of same supplier product ref) +FIX: postgre filter select search extrafield +FIX: products/services card: hidden extrafields were overridden +FIX: shipping validation workflow: 'ORDER_NEW' trigger called from wrong object +FIX: task time: can't filter by user with pgsql + show error message +FIX: task time: keep on using natural_search +FIX: wrong users count in multicompany transverse mode + + ***** ChangeLog for 13.0.4 compared to 13.0.3 ***** FIX: Allow disabling of a module (not a dangerous action) even if there is problem with token (due to bugged modules). diff --git a/README-FR.md b/README-FR.md index 81fdff13047..a67bf204076 100644 --- a/README-FR.md +++ b/README-FR.md @@ -8,12 +8,10 @@ Il est simple d'utilisation et modulaire, vous permettant de n'activez que les f ![ScreenShot](https://www.dolibarr.org/medias/dolibarr_screenshot1_1920x1080.jpg) - ## LICENCE Dolibarr est distribué sous les termes de la licence GNU General Public License v3+ ou supérieure. - ## INSTALLER DOLIBARR ### Configuration simple @@ -54,7 +52,6 @@ Vous pouvez aussi utiliser un serveur Web et une base de données prise en charg - Suivez les instructions de l'installateur - ## METTRE A JOUR DOLIBARR Pour mettre à jour Dolibarr depuis une vieille version vers celle ci: @@ -65,14 +62,12 @@ Pour mettre à jour Dolibarr depuis une vieille version vers celle ci: - Au prochain accès, Dolibarr proposera la page de "mise à jour" des données (si nécessaire). Si un fichier install.lock existe pour verrouiller le processus de mise à jour, il sera demandé de le supprimer manuellement (vous devriez trouver le fichier install.lock dans le répertoire utilisé pour stocker les documents générés ou transférés sur le serveur. Dans la plupart des cas, c'est le répertoire appelé "documents") -*Note: Le processus de migration peut être lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/* - +Note: *Le processus de migration peut être lancé manuellement et plusieurs fois, sans risque, en appelant la page /install/* ## CE QUI EST NOUVEAU See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) file. - ## CE QUE DOLIBARR PEUT FAIRE ### Modules principaux (tous optionnels) @@ -122,7 +117,7 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - Peux être multi-société par ajout du module externe multi-société. - Plusieurs thèmes visuels. - Application simple à utiliser. -- Requiert PHP et MariaDb, Mysql ou Postgresql (Voir versions exactes sur https://wiki.dolibarr.org/index.php/Prérequis). +- Requiert PHP et MariaDb, Mysql ou Postgresql (Voir versions exactes sur [https://wiki.dolibarr.org/index.php/Prérequis](https://wiki.dolibarr.org/index.php/Prérequis)). - Compatible avec toutes les offres Cloud du marché respectant les prérequis de base de données et PHP. - APIs. - Génération PDF et ODT des éléments (factures, propositions commerciales, commandes, bons expéditions, etc...) @@ -142,7 +137,6 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) Dolibarr peut aussi être étendu à volonté avec l'ajout de module/applications externes développées par des développeus tiers, disponible sur [DoliStore](https://www.dolistore.com). - ## CE QUE DOLIBARR NE PEUT PAS (ENCORE) FAIRE Voici un liste de fonctionnalités pas encore gérées par Dolibarr: @@ -152,18 +146,15 @@ Voici un liste de fonctionnalités pas encore gérées par Dolibarr: - Dolibarr n'embarque pas de Webmail intégré nativement. - Dolibarr ne fait pas le café (pas encore). - ## DOCUMENTATION La documentation utilisateur, développeur et traducteur est disponible sous forme de ressources de la communauté via le site [Wiki](https://wiki.dolibarr.org). - ## CONTRIBUER Ce projet existe grâce à ses nombreux contributeurs [[Contribuer](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CONTRIBUTING.md)]. - - +[![Dolibarr](https://opencollective.com/dolibarr/contributors.svg?width=890&button=false)](https://github.com/Dolibarr/dolibarr/graphs/contributors) ## CREDITS @@ -171,7 +162,6 @@ Dolibarr est le résultat du travail de nombreux contributeurs depuis des année Voir le fichier [COPYRIGHT](https://github.com/Dolibarr/dolibarr/blob/develop/COPYRIGHT) - ## ACTUALITES ET RESEAUX SOCIAUX Suivez le projet Dolibarr project sur les réseaux francophones diff --git a/README.md b/README.md index 834cc09236e..b0f7a2c3761 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ You can use a web server and a supported database (MariaDB, MySQL or PostgreSQL) On GNU/Linux, first check if your distribution has already packaged Dolibarr. -#### Generic install steps: +#### Generic install steps - Check that your installed PHP version is supported [see PHP support](https://wiki.dolibarr.org/index.php/Releases). @@ -71,107 +71,107 @@ On GNU/Linux, first check if your distribution has already packaged Dolibarr. - Follow the installer instructions - ### Saas/Cloud setup -If you don't have time to install it yourself, you can try some commercial 'ready to use' Cloud offers (See https://saas.dolibarr.org). However, this third solution is not free. - +If you don't have time to install it yourself, you can try some commercial 'ready to use' Cloud offers (See [https://saas.dolibarr.org](https://saas.dolibarr.org)). However, this third solution is not free. ## UPGRADING Dolibarr supports upgrading, usually without the need for any (commercial) support (depending on if you use any commercial extensions). It supports upgrading all the way from any version after 2.8 without breakage. This is unique in the ERP ecosystem and a benefit our users highly appreciate! - -- At first make a backup of your Dolibarr files & than [see](https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr) + +- At first make a backup of your Dolibarr files & then [see](https://wiki.dolibarr.org/index.php/Installation_-_Upgrade#Upgrade_Dolibarr) - Check that your installed PHP version is supported by the new version [see PHP support](./doc/phpmatrix.md). - Overwrite all old files from 'dolibarr' directory with files provided into the new version's package. - At first next access, Dolibarr will redirect you to the "install/" page to follow the upgrade process.  If an `install.lock` file exists to lock any other upgrade process, the application will ask you to remove the file manually (you should find the `install.lock` file in the directory used to store generated and uploaded documents, in most cases, it is the directory called "*documents*"). - ## WHAT'S NEW See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) file. - ## FEATURES ### Main application/modules (all optional) -- Third-Parties Management: Customers, Prospects (Leads) and/or Suppliers + Contacts -- Members/Membership/Foundation management +- Third-Parties Management: Customers, Prospects (Leads) and/or Suppliers + Contacts +- Members/Membership/Foundation management - Product Management -- Products and/or Services catalog -- Stock / Warehouse management + Inventory -- Barcodes -- Batches / Lots / Serials -- Product Variants + Product Management + +- Products and/or Services catalog +- Stock / Warehouse management + Inventory +- Barcodes +- Batches / Lots / Serials +- Product Variants - Bill of Materials (BOM) -- Manufacturing Orders +- Manufacturing Orders - Customer/Sales Management -- Customers/Prospects + Contacts management -- Opportunities or Leads management -- Commercial proposals management -- Customer Orders management -- Contracts/Subscription management -- Interventions management -- Ticket System -- Shipping management -- Customer Invoices/Credit notes and payment management -- Point of Sale (POS) + Customer/Sales Management - Supplier/Purchase Management -- Suppliers/Vendors + Contacts -- Supplier (price) requests -- Purchase Orders management -- Delivery/Receiption -- Supplier Invoices/credit notes and payment management -- INCOTERMS +- Customers/Prospects + Contacts management +- Opportunities or Leads management +- Commercial proposals management +- Customer Orders management +- Contracts/Subscription management +- Interventions management +- Ticket System +- Shipping management +- Customer Invoices/Credit notes and payment management +- Point of Sale (POS) - Finance / Accounting -- Invoices / Payments -- Bank accounts management -- Direct debit orders management (European SEPA) -- Accounting management -- Donations management -- Loan management -- Margins -- Reports + Supplier/Purchase Management - Collaboration -- Shared calendar/agenda (with ical and vcal export for third party tools integration) -- Projects & Tasks management -- Ticket System +- Suppliers/Vendors + Contacts +- Supplier (price) requests +- Purchase Orders management +- Delivery/Receiption +- Supplier Invoices/credit notes and payment management +- INCOTERMS + + Finance / Accounting + +- Invoices / Payments +- Bank accounts management +- Direct debit orders management (European SEPA) +- Accounting management +- Donations management +- Loan management +- Margins +- Reports + + Collaboration + +- Shared calendar/agenda (with ical and vcal export for third party tools integration) +- Projects & Tasks management +- Ticket System - Surveys - HR -- Employee's leave requests management -- Expense reports -- Recruitment management -- Timesheets + HR +- Employee's leave requests management +- Expense reports +- Recruitment management +- Timesheets ### Other application/modules -- Electronic Document Management (EDM) +- Electronic Document Management (EDM) - Bookmarks management - Reporting - Data export/import -- Barcodes +- Barcodes - Margin calculations - LDAP connectivity - ClickToDial integration - Mass emailing - RSS integration - Skype integration -- Social platforms linking +- Social platforms linking - Payment platforms integration (PayPal, Stripe, Paybox...) - Email-Collector (around 100 modules available by default, 1000+ on the addon market place) - ### Other general features - Localization in most major languages @@ -179,41 +179,35 @@ See the [ChangeLog](https://github.com/Dolibarr/dolibarr/blob/develop/ChangeLog) - 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 - 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) - - Support a lot of country specific features: - Spanish Tax RE and ISPF - French NPR VAT rate (VAT called "Non Perçue Récupérable" for DOM-TOM) - Canadian double taxes (federal/province) and other countries using cumulative VAT - Tunisian tax stamp - Argentina invoice numbering using A,B,C... - - Compatible with [European directives] (https://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE) + - Compatible with [European directives](https://europa.eu/legislation_summaries/taxation/l31057_en.htm) (2006/112/CE ... 2010/45/UE) - Compatible with European GDPR rules - ... - Flexible PDF & ODT generation for invoices, proposals, orders... -- … - +- ... ### System Environment / Requirements - PHP -- MariaDB, MySQL or PostgreSQL +- MariaDB, MySQL or PostgreSQL - Compatible with all Cloud solutions that match PHP & MySQL or PostgreSQL prerequisites. See exact requirements on the [Wiki](https://wiki.dolibarr.org/index.php/Prerequisite) - ### Extending Dolibarr can be extended with a lot of other external application or modules from third party developers available at the [DoliStore](https://www.dolistore.com). - ## WHAT DOLIBARR CAN'T DO YET These are features that Dolibarr does **not** yet fully support: @@ -223,21 +217,18 @@ These are features that Dolibarr does **not** yet fully support: - No native embedded Webmail, but you can send email to contacts in Dolibarr with e.g. offers, invoices, etc. - Dolibarr can't do coffee (yet) - ## DOCUMENTATION Administrator, user, developer and translator's documentations are available along with other community resources in the [Wiki](https://wiki.dolibarr.org). - ## CONTRIBUTING -This project exists thanks to all the people who contribute. +This project exists thanks to all the people who contribute. Please read the instructions how to contribute (report a bug/error, a feature request, send code ...) [[Contribute](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CONTRIBUTING.md)] A view on Contributors: - - +[![Dolibarr](https://opencollective.com/dolibarr/contributors.svg?width=890&button=false)](https://github.com/Dolibarr/dolibarr/graphs/contributors) ## CREDITS @@ -245,7 +236,6 @@ Dolibarr is the work of many contributors over the years and uses some fine PHP See [COPYRIGHT](https://github.com/Dolibarr/dolibarr/blob/develop/COPYRIGHT) file. - ## NEWS AND SOCIAL NETWORKS Follow Dolibarr project on: @@ -256,8 +246,6 @@ Follow Dolibarr project on: - [YouTube](https://www.youtube.com/user/DolibarrERPCRM) - [GitHub](https://github.com/Dolibarr/dolibarr) - ### Sponsors Support this project by becoming a sponsor. Your logo will show up here. 🙏 [[Become a sponsor/backer](https://opencollective.com/dolibarr#backer)] - diff --git a/SECURITY.md b/SECURITY.md index 7d65b7e98e4..427b1cc7ae2 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,11 +4,11 @@ This file contains some policies about the security reports on Dolibarr ERP CRM ## Supported Versions for security reports -| Version | Supported | -| --------- | ------------------ | -| <= 12.* | :x: | -| >= 13.* | :white_check_mark: | - +| Version | Supported | +| ---------- | ---------------------- | +| <= 14.0.1 | :x: | +| >= 14.0.2+ | :white_check_mark: except CSRF attacks| +| >= develop | :white_check_mark: | ## Reporting a Vulnerability @@ -54,12 +54,12 @@ ONLY vulnerabilities discovered, when the following setup on test platform is us * $dolibarr_main_prod must be set to 1 into conf.php * $dolibarr_nocsrfcheck must be kept to the value 0 into conf.php (this is the default value) * $dolibarr_main_force_https must be set to something else than 0. -* The constant MAIN_SECURITY_CSRF_WITH_TOKEN must be set to 1 into backoffice menu Home - Setup - Other (this protection should be set to 1 soon by default) +* The constant MAIN_SECURITY_CSRF_WITH_TOKEN must be set to 3 into backoffice menu Home - Setup - Other (this protection should be set to 3 soon by default) * The module DebugBar and ModuleBuilder must NOT be enabled (by default, these modules are not enabled. They are developer tools) * 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. -* CSRF attacks are accepted when using a POST URL, but when using GET URL, they are validated only for creating, updating or deleting data resctricted from pages restricted to admin users. +* CSRF attacks are accepted but double check that you have set MAIN_SECURITY_CSRF_WITH_TOKEN to value 3. * Ability for a high level user to edit web site pages into the CMS by including HTML or Javascript is an expected feature. Vulnerabilities into the website module are validated only if HTML or Javascript injection can be done by a non allowed user. Scope is the web application (back office) and the APIs. @@ -90,9 +90,8 @@ Scope is the web application (back office) and the APIs. * Clickjacking/UI redressing * Physical or social engineering attempts or issues that require physical access to a victim’s computer/device * Presence of autocomplete attribute on web forms -* Vulnerabilities affecting outdated browsers or platforms +* Vulnerabilities affecting outdated browsers or platforms, or vulnerabilities inside browsers themself. * Logout and other instances of low-severity Cross-Site Request Forgery -* Missing cookie flags * Missing security-related HTTP headers which do not lead directly to a vulnerability * Reports from automated web vulnerability scanners (Acunetix, Vega, etc.) that have not been validated * Invalid or missing SPF (Sender Policy Framework) records (Incomplete or missing SPF/DKIM/DMARC) diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile index dca74e9e720..eb8e3ade6dc 100644 --- a/build/docker/Dockerfile +++ b/build/docker/Dockerfile @@ -57,7 +57,6 @@ RUN echo "host mail" >> /etc/msmtprc RUN echo "from local@localdomain.com" >> /etc/msmtprc RUN echo "domain localhost.localdomain" >> /etc/msmtprc RUN echo "sendmail_path=/usr/bin/msmtp -t" >> /usr/local/etc/php/conf.d/php-sendmail.ini -RUN echo "localhost localhost.localdomain" >> /etc/hosts EXPOSE 80 diff --git a/build/docker/docker-compose.yml b/build/docker/docker-compose.yml index 2167f069f25..b72118de5fb 100644 --- a/build/docker/docker-compose.yml +++ b/build/docker/docker-compose.yml @@ -46,6 +46,8 @@ services: networks: - internal-pod - external-pod + extra_hosts: + - "localhost.localdomain:127.0.0.1" mail: image: maildev/maildev diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index 8e7ef3ef46c..7065e20f92b 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -239,10 +239,18 @@ fclose($fp); if (empty($buildzip)) { print "File ".$outputfile." generated\n"; } else { - $result = dol_compress_file($outputfile, $outputfile.'.zip'); - if ($result > 0) { - dol_delete_file($outputfile); - print "File ".$outputfile.".zip generated\n"; + if ($buildzip == '1' || $buildzip == 'zip') { + $result = dol_compress_file($outputfile, $outputfile.'.zip', 'zip'); + if ($result > 0) { + dol_delete_file($outputfile); + print "File ".$outputfile.".zip generated\n"; + } + } elseif ($buildzip == '2' || $buildzip == 'gz') { + $result = dol_compress_file($outputfile, $outputfile.'.gz', 'gz'); + if ($result > 0) { + dol_delete_file($outputfile); + print "File ".$outputfile.".gz generated\n"; + } } } diff --git a/composer.json b/composer.json index 130fda34945..8d82f530df8 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "nnnick/chartjs" : "^2.9", "stripe/stripe-php" : "6.43.1", "maximebf/debugbar" : "1.15.1", - "symfony/var-dumper" : "3" + "symfony/var-dumper" : "3.2" }, "require-dev" : { "php-parallel-lint/php-parallel-lint" : "^0", diff --git a/composer.lock b/composer.lock index 3e867f8f186..5f761cb63fe 100644 --- a/composer.lock +++ b/composer.lock @@ -591,7 +591,7 @@ }, { "name": "symfony/var-dumper", - "version": "v3.0.0", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", @@ -616,7 +616,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 4f80f06d444..7ce22e790c3 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -168,6 +168,18 @@ In htdocs/includes/tecnickcom/tcpdf/tcpdf.php - protected $default_monospaced_font = 'courier'; + protected $default_monospaced_font = 'freemono'; +* In tecnickcom/tcpdf/include/tcpdf_static, in function intToRoman, right at the beginning + of the function, replace: + + $roman = ''; + +with: + + $roman = ''; + if ($number >= 4000) { + // do not represent numbers above 4000 in Roman numerals + return strval($number); + } @@ -188,7 +200,10 @@ with: with } elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) { - +* Fix php fatal error on php 8.0 on tcpdi.php + while (list($k, $v) = each($value[1])) { +with + foreach ($value[1] as $k => $v) { JSGANTT: -------- diff --git a/dev/examples/ldap/ldapsearch_sample1.txt b/dev/examples/ldap/ldapsearch_sample1.txt index 5f667ffd7a4..a02ad632cd0 100644 --- a/dev/examples/ldap/ldapsearch_sample1.txt +++ b/dev/examples/ldap/ldapsearch_sample1.txt @@ -3,11 +3,26 @@ # # Use this sample to search into a ldap # -# ldapsearch -h hostname -x -# ldapsearch -h hostname -x -b "ou=people,dc=teclib,dc=infra" -# ldapsearch -h hostname -x -z 0 -b "o=somecompany.com" -D "cn=manager,o=somecompany.com" -w password "(objectclass=*)" -# ldapsearch -h hostname -x -b "o=somecompany.com" -D "cn=manager,o=somecompany.com" -w password "(objectclass=*)" + +# Anonymous access +# ldapsearch -h hostname -p 389 +# +# Login access (using a Bind DN) +# ldapsearch -h hostname -p 389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password +# ldapsearch -H ldap://hostname:389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password +# ldapsearch -d1 -H ldap://hostname:389 -x -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password +# ldapsearch -H ldap://hostname:389 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password +# +# Login access in SSL (using a Bind DN) +# ldapsearch -H ldaps://hostnamme:636 -z 0 -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password -b "cn=users,dc=ldap,dc=test,dc=local +# If it fails, you may try to use "hostname" that is real name of certificate. +# You must also check that /etc/ldap/ldap.conf contains the line TLS_CACERT /etc/ssl/certs/ca-certificates.crt + +# What to search +# ldapsearch -h hostname -p 389 -x -D "uid=root,cn=users,dc=ldap,dc=test,dc=local" -w password -b "cn=users,dc=ldap,dc=test,dc=local" +# ldapsearch -h hostname -p 389 -x -D "cn=manager,o=somecompany.com" -w password -b "ou=people,dc=teclib,dc=infra" +# ldapsearch -h hostname -p 389 -x -D "cn=manager,o=somecompany.com" -w password -b "o=somecompany.com" "(objectclass=*)" # # Example to test a ldap search: -# ldapsearch -h hostname -x -z 5 -b 'OU=Collaborateurs,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -D 'CN=UserAdmin,OU=Informatique,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -w password +# ldapsearch -h hostname -p 389 -x -z 5 -b 'OU=Collaborateurs,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -D 'CN=UserAdmin,OU=Informatique,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -w password diff --git a/dev/initdemo/initdemopassword.sh b/dev/initdemo/initdemopassword.sh index 933c3b1afa2..37264fb8e4d 100755 --- a/dev/initdemo/initdemopassword.sh +++ b/dev/initdemo/initdemopassword.sh @@ -171,7 +171,10 @@ if [ $res -ne 0 ]; then fi if [ -s "$mydir/initdemopostsql.sql" ]; then + echo A file initdemopostsql.sql was found, we execute it. mysql -P$port $base < "$mydir/initdemopostsql.sql" +else + echo No file initdemopostsql.sql found, we extra sql action done. fi diff --git a/dev/initdemo/mysqldump_dolibarr_14.0.0.sql b/dev/initdemo/mysqldump_dolibarr_14.0.0.sql index 4061fb9f4cf..e619c2c8fda 100644 --- a/dev/initdemo/mysqldump_dolibarr_14.0.0.sql +++ b/dev/initdemo/mysqldump_dolibarr_14.0.0.sql @@ -2056,7 +2056,7 @@ CREATE TABLE `llx_c_holiday_types` ( `label` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `affect` int(11) NOT NULL, `delay` int(11) NOT NULL, - `newByMonth` double(8,5) NOT NULL DEFAULT 0.00000, + `newbymonth` double(8,5) NOT NULL DEFAULT 0.00000, `fk_country` int(11) DEFAULT NULL, `active` int(11) DEFAULT 1, PRIMARY KEY (`rowid`), diff --git a/dev/tools/github_authors_peryear.sh b/dev/tools/github_authors_and_commits_peryear.sh similarity index 100% rename from dev/tools/github_authors_peryear.sh rename to dev/tools/github_authors_and_commits_peryear.sh diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 930e76c7690..c2ac133069d 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -38,6 +38,7 @@ $cancel = GETPOST('cancel', 'alpha'); $id = GETPOST('id', 'int'); $rowid = GETPOST('rowid', 'int'); $massaction = GETPOST('massaction', 'aZ09'); +$optioncss = GETPOST('optioncss', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'accountingaccountlist'; // To manage different context of search $search_account = GETPOST('search_account', 'alpha'); @@ -51,14 +52,14 @@ $confirm = GETPOST('confirm', 'alpha'); $chartofaccounts = GETPOST('chartofaccounts', 'int'); -$permissiontoadd = $user->rights->accounting->chartofaccount; -$permissiontodelete = $user->rights->accounting->chartofaccount; +$permissiontoadd = !empty($user->rights->accounting->chartofaccount); +$permissiontodelete = !empty($user->rights->accounting->chartofaccount); // Security check if ($user->socid > 0) { accessforbidden(); } -if (!$user->rights->accounting->chartofaccount) { +if (empty($user->rights->accounting->chartofaccount)) { accessforbidden(); } @@ -195,7 +196,7 @@ if (empty($reshook)) { } elseif ($action == 'enable' && $permissiontoadd) { if ($accounting->fetch($id)) { $mode = GETPOST('mode', 'int'); - $result = $accounting->account_activate($id, $mode); + $result = $accounting->accountActivate($id, $mode); } $action = 'update'; if ($result < 0) { @@ -438,43 +439,37 @@ if ($resql) { print $searchpicto; print ''; print ''; - $totalarray = array(); print ''; if (!empty($arrayfields['aa.account_number']['checked'])) { print_liste_field_titre($arrayfields['aa.account_number']['label'], $_SERVER["PHP_SELF"], "aa.account_number", "", $param, '', $sortfield, $sortorder); - $totalarray['nbfield']++; } if (!empty($arrayfields['aa.label']['checked'])) { print_liste_field_titre($arrayfields['aa.label']['label'], $_SERVER["PHP_SELF"], "aa.label", "", $param, '', $sortfield, $sortorder); - $totalarray['nbfield']++; } if (!empty($arrayfields['aa.labelshort']['checked'])) { print_liste_field_titre($arrayfields['aa.labelshort']['label'], $_SERVER["PHP_SELF"], "aa.labelshort", "", $param, '', $sortfield, $sortorder); - $totalarray['nbfield']++; } if (!empty($arrayfields['aa.account_parent']['checked'])) { print_liste_field_titre($arrayfields['aa.account_parent']['label'], $_SERVER["PHP_SELF"], "aa.account_parent", "", $param, '', $sortfield, $sortorder, 'left '); - $totalarray['nbfield']++; } if (!empty($arrayfields['aa.pcg_type']['checked'])) { print_liste_field_titre($arrayfields['aa.pcg_type']['label'], $_SERVER["PHP_SELF"], 'aa.pcg_type,aa.account_number', '', $param, '', $sortfield, $sortorder, '', $arrayfields['aa.pcg_type']['help'], 1); - $totalarray['nbfield']++; } if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { if (!empty($arrayfields['aa.reconcilable']['checked'])) { print_liste_field_titre($arrayfields['aa.reconcilable']['label'], $_SERVER["PHP_SELF"], 'aa.reconcilable', '', $param, '', $sortfield, $sortorder); - $totalarray['nbfield']++; } } if (!empty($arrayfields['aa.active']['checked'])) { print_liste_field_titre($arrayfields['aa.active']['label'], $_SERVER["PHP_SELF"], 'aa.active', '', $param, '', $sortfield, $sortorder); - $totalarray['nbfield']++; } print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); print "\n"; $accountstatic = new AccountingAccount($db); $accountparent = new AccountingAccount($db); + $totalarray = array(); + $totalarray['nbfield'] = 0; $i = 0; while ($i < min($num, $limit)) { diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php index f19afb12899..97a460beaac 100644 --- a/htdocs/accountancy/admin/accountmodel.php +++ b/htdocs/accountancy/admin/accountmodel.php @@ -78,7 +78,7 @@ $search_country_id = GETPOST('search_country_id', 'int'); if ($user->socid > 0) { accessforbidden(); } -if (!$user->rights->accounting->chartofaccount) { +if (empty($user->rights->accounting->chartofaccount)) { accessforbidden(); } diff --git a/htdocs/accountancy/admin/card.php b/htdocs/accountancy/admin/card.php index 86efee3a04a..9430bf33439 100644 --- a/htdocs/accountancy/admin/card.php +++ b/htdocs/accountancy/admin/card.php @@ -48,7 +48,7 @@ $label = GETPOST('label', 'alpha'); if ($user->socid > 0) { accessforbidden(); } -if (!$user->rights->accounting->chartofaccount) { +if (empty($user->rights->accounting->chartofaccount)) { accessforbidden(); } @@ -61,7 +61,7 @@ $object = new AccountingAccount($db); */ if (GETPOST('cancel', 'alpha')) { - $urltogo = $backtopage ? $backtopage : dol_buildpath('/accountancy/admin/account.php', 1); + $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT.'/accountancy/admin/account.php'; header("Location: ".$urltogo); exit; } @@ -75,7 +75,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); $action = 'create'; } else { - $sql = 'SELECT pcg_version FROM ' . MAIN_DB_PREFIX . 'accounting_system WHERE rowid='.((int) $conf->global->CHARTOFACCOUNTS); + $sql = "SELECT pcg_version FROM " . MAIN_DB_PREFIX . "accounting_system WHERE rowid = ".((int) $conf->global->CHARTOFACCOUNTS); dol_syslog('accountancy/admin/card.php:: $sql=' . $sql); $result = $db->query($sql); @@ -121,7 +121,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) { } if (!$error) { setEventMessages("RecordCreatedSuccessfully", null, 'mesgs'); - $urltogo = $backtopage ? $backtopage : dol_buildpath('/accountancy/admin/account.php', 1); + $urltogo = $backtopage ? $backtopage : DOL_URL_ROOT.'/accountancy/admin/account.php'; header("Location: " . $urltogo); exit; } @@ -138,7 +138,7 @@ if ($action == 'add' && $user->rights->accounting->chartofaccount) { } else { $result = $object->fetch($id); - $sql = 'SELECT pcg_version FROM '.MAIN_DB_PREFIX.'accounting_system WHERE rowid='.((int) $conf->global->CHARTOFACCOUNTS); + $sql = "SELECT pcg_version FROM ".MAIN_DB_PREFIX."accounting_system WHERE rowid=".((int) $conf->global->CHARTOFACCOUNTS); dol_syslog('accountancy/admin/card.php:: $sql=' . $sql); $result2 = $db->query($sql); @@ -260,7 +260,7 @@ if ($action == 'create') { print ''; // autosuggest from existing account types if found print ''; - $sql = 'SELECT DISTINCT pcg_type FROM ' . MAIN_DB_PREFIX . 'accounting_account'; + $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 diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index 4be890de7d5..d914b825b7f 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2011-2017 Alexandre Spangaro + * Copyright (C) 2011-2021 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 @@ -91,19 +91,19 @@ $tabsql[32] = "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account $tabsqlsort = array(); $tabsqlsort[32] = "position ASC"; -// Nom des champs en resultat de select pour affichage du dictionnaire +// Name of the fields in the result of select to display the dictionary $tabfield = array(); $tabfield[32] = "code,label,range_account,category_type,formula,position,country"; -// Nom des champs d'edition pour modification d'un enregistrement +// Name of editing fields for record modification $tabfieldvalue = array(); $tabfieldvalue[32] = "code,label,range_account,category_type,formula,position,country_id"; -// Nom des champs dans la table pour insertion d'un enregistrement +// Name of the fields in the table for inserting a record $tabfieldinsert = array(); $tabfieldinsert[32] = "code,label,range_account,category_type,formula,position,fk_country"; -// Nom du rowid si le champ n'est pas de type autoincrement +// Name of the rowid if the field is not of type autoincrement // Example: "" if id field is "rowid" and has autoincrement on // "nameoffield" if id field is not "rowid" or has not autoincrement on $tabrowid = array(); @@ -151,7 +151,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($value == 'range_account' && empty($_POST['range_account'])) { continue; } - if ($value == 'country' || $value == 'country_id') { + if (($value == 'country' || $value == 'country_id') && (!empty($_POST['country_id']))) { continue; } if (!GETPOSTISSET($value) || GETPOST($value) == '') { @@ -176,6 +176,9 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { if ($fieldnamekey == 'category_type') { $fieldnamekey = 'Calculated'; } + if ($fieldnamekey == 'country') { + $fieldnamekey = 'Country'; + } setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->transnoentities($fieldnamekey)), null, 'errors'); } @@ -263,7 +266,7 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) { } } - // Si verif ok et action modify, on modifie la ligne + // If check ok and action modify, we modify the line if ($ok && GETPOST('actionmodify', 'alpha')) { if ($tabrowid[$id]) { $rowidcol = $tabrowid[$id]; @@ -430,12 +433,12 @@ print load_fiche_titre($titre, $linkback, $titlepicto); print ''.$langs->trans("AccountingAccountGroupsDesc", $langs->transnoentitiesnoconv("ByPersonalizedAccountGroups")).'

'; -// Confirmation de la suppression de la ligne +// Confirmation of the deletion of the line if ($action == 'delete') { print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.$rowid.'&code='.$code.'&id='.$id.($search_country_id > 0 ? '&search_country_id='.$search_country_id : ''), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1); } -// Complete requete recherche valeurs avec critere de tri +// Complete search query with sorting criteria $sql = $tabsql[$id]; if ($search_country_id > 0) { @@ -634,14 +637,14 @@ if ($resql) { // Title of lines print ''; foreach ($fieldlist as $field => $value) { - // Determine le nom du champ par rapport aux noms possibles - // dans les dictionnaires de donnees - $showfield = 1; // By defaut + // Determines the name of the field in relation to the possible names + // in data dictionaries + $showfield = 1; // By default $class = "left"; $sortable = 1; $valuetoshow = ''; - $valuetoshow = ucfirst($fieldlist[$field]); // By defaut + $valuetoshow = ucfirst($fieldlist[$field]); // By default $valuetoshow = $langs->trans($valuetoshow); // try to translate if ($fieldlist[$field] == 'source') { $valuetoshow = $langs->trans("Contact"); @@ -741,7 +744,7 @@ if ($resql) { print ''; } else { $tmpaction = 'view'; - $parameters = array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); $reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks $error = $hookmanager->error; $errors = $hookmanager->errors; @@ -811,7 +814,7 @@ if ($resql) { // Modify link if ($canbemodified) { - print ''.img_edit().''; + print ''.img_edit().''; } else { print ' '; } @@ -820,7 +823,7 @@ if ($resql) { if ($iserasable) { print ''; if ($user->admin) { - print ''.img_delete().''; + print ''.img_delete().''; } //else print ''.img_delete().''; // Some dictionary can be edited by other profile than admin print ''; diff --git a/htdocs/accountancy/admin/closure.php b/htdocs/accountancy/admin/closure.php index 8efb869ffaf..437ff1b7116 100644 --- a/htdocs/accountancy/admin/closure.php +++ b/htdocs/accountancy/admin/closure.php @@ -109,7 +109,7 @@ foreach ($list_account_main as $key) { print ''; // Value print ''; // Do not force class=right, or it align also the content of the select box - print $formaccounting->select_account($conf->global->$key, $key, 1, '', 1, 1); + print $formaccounting->select_account(getDolGlobalString($key), $key, 1, '', 1, 1); print ''; print ''; } diff --git a/htdocs/accountancy/admin/defaultaccounts.php b/htdocs/accountancy/admin/defaultaccounts.php index 061752c11c5..5d78036159a 100644 --- a/htdocs/accountancy/admin/defaultaccounts.php +++ b/htdocs/accountancy/admin/defaultaccounts.php @@ -186,7 +186,7 @@ foreach ($list_account as $key) { print ''.$label.''; // Value print ''; // Do not force class=right, or it align also the content of the select box - print $formaccounting->select_account($conf->global->$key, $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts'); + print $formaccounting->select_account(getDolGlobalString($key), $key, 1, '', 1, 1, 'minwidth100 maxwidth300 maxwidthonsmartphone', 'accounts'); print ''; print ''; } diff --git a/htdocs/accountancy/admin/fiscalyear.php b/htdocs/accountancy/admin/fiscalyear.php index 4338d7ad803..44c5309f531 100644 --- a/htdocs/accountancy/admin/fiscalyear.php +++ b/htdocs/accountancy/admin/fiscalyear.php @@ -52,7 +52,7 @@ $langs->loadLangs(array("admin", "compta")); if ($user->socid > 0) { accessforbidden(); } -if (!$user->rights->accounting->fiscalyear->write) { // If we can read accounting records, we should be able to see fiscal year. +if (empty($user->rights->accounting->fiscalyear->write)) { // If we can read accounting records, we should be able to see fiscal year. accessforbidden(); } diff --git a/htdocs/accountancy/admin/fiscalyear_info.php b/htdocs/accountancy/admin/fiscalyear_info.php index d472350fab7..77ec988143a 100644 --- a/htdocs/accountancy/admin/fiscalyear_info.php +++ b/htdocs/accountancy/admin/fiscalyear_info.php @@ -33,7 +33,7 @@ $langs->loadLangs(array("admin", "compta")); if ($user->socid > 0) { accessforbidden(); } -if (!$user->rights->accounting->fiscalyear->write) { +if (empty($user->rights->accounting->fiscalyear->write)) { accessforbidden(); } diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index 45b5acc7c8a..309dc094e82 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2013-2014 Florian Henry - * Copyright (C) 2013-2019 Alexandre Spangaro + * Copyright (C) 2013-2021 Alexandre Spangaro * Copyright (C) 2014-2015 Ari Elbaz (elarifr) * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent @@ -260,6 +260,22 @@ $linkback = ''; //$linkback = '' . $langs->trans("BackToModuleList") . ''; print load_fiche_titre($title, $linkback, 'accountancy'); +// Show message if accountancy hidden options are activated to help to resolve some problems +if (!$user->admin) { + if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + print '
' . $langs->trans("ConstantIsOn", "FACTURE_DEPOSITS_ARE_JUST_PAYMENTS") . '
'; + } + if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { + print '
' . $langs->trans("ConstantIsOn", "ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY") . '
'; + } + if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { + print '
' . $langs->trans("ConstantIsOn", "MAIN_COMPANY_PERENTITY_SHARED") . '
'; + } + if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { + print '
' . $langs->trans("ConstantIsOn", "MAIN_PRODUCT_PERENTITY_SHARED") . '
'; + } +} + print '
'; print ''; print ''; diff --git a/htdocs/accountancy/admin/journals_list.php b/htdocs/accountancy/admin/journals_list.php index 66e3f3b73e4..e60deef59a3 100644 --- a/htdocs/accountancy/admin/journals_list.php +++ b/htdocs/accountancy/admin/journals_list.php @@ -612,7 +612,7 @@ if ($id) { print ''; } else { $tmpaction = 'view'; - $parameters = array('var'=>$var, 'fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); + $parameters = array('fieldlist'=>$fieldlist, 'tabname'=>$tabname[$id]); $reshook = $hookmanager->executeHooks('viewDictionaryFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks $error = $hookmanager->error; $errors = $hookmanager->errors; diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index 9596cd96af8..e7616ededf3 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -41,7 +41,7 @@ $langs->loadLangs(array("companies", "compta", "accountancy", "products")); if (empty($conf->accounting->enabled)) { accessforbidden(); } -if (!$user->rights->accounting->bind->write) { +if (empty($user->rights->accounting->bind->write)) { accessforbidden(); } @@ -70,6 +70,7 @@ $search_onpurchase = GETPOST('search_onpurchase', 'alpha'); $accounting_product_mode = GETPOST('accounting_product_mode', 'alpha'); $btn_changeaccount = GETPOST('changeaccount', 'alpha'); $btn_changetype = GETPOST('changetype', 'alpha'); +$optioncss = GETPOST('optioncss', 'alpha'); if (empty($accounting_product_mode)) { $accounting_product_mode = 'ACCOUNTANCY_SELL'; @@ -186,12 +187,28 @@ if ($action == 'update') { $msg .= '
'.$langs->trans("ErrorDB").' : '.$langs->trans("Product").' '.$productid.' '.$langs->trans("NotVentilatedinAccount").' : id='.$accounting_account_id.'
'.$sql.'
'; $ko++; } else { - $db->begin(); - + $sql = ''; if (!empty($conf->global->MAIN_PRODUCT_PERENTITY_SHARED)) { - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_perentity (fk_product, entity, '".$db->escape($accountancy_field_name)."')"; - $sql .= " VALUES (".((int) $productid).", ".((int) $conf->entity).", '".$db->escape($accounting->account_number)."')"; - $sql .= " ON DUPLICATE KEY UPDATE ".$accountancy_field_name." = '".$db->escape($accounting->account_number)."'"; + $sql_exists = "SELECT rowid FROM " . MAIN_DB_PREFIX . "product_perentity"; + $sql_exists .= " WHERE fk_product = " . ((int) $productid) . " AND entity = " . ((int) $conf->entity); + $resql_exists = $db->query($sql_exists); + if (!$resql_exists) { + $msg .= '
'.$langs->trans("ErrorDB").' : '.$langs->trans("Product").' '.$productid.' '.$langs->trans("NotVentilatedinAccount").' : id='.$accounting_account_id.'
'.$resql_exists.'
'; + $ko++; + } else { + $nb_exists = $db->num_rows($resql_exists); + if ($nb_exists <= 0) { + // insert + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_perentity (fk_product, entity, " . $db->escape($accountancy_field_name) . ")"; + $sql .= " VALUES (" . ((int) $productid) . ", " . ((int) $conf->entity) . ", '" . $db->escape($accounting->account_number) . "')"; + } else { + $obj_exists = $db->fetch_object($resql_exists); + // update + $sql = "UPDATE " . MAIN_DB_PREFIX . "product_perentity"; + $sql .= " SET " . $accountancy_field_name . " = '" . $db->escape($accounting->account_number) . "'"; + $sql .= " WHERE rowid = " . ((int) $obj_exists->rowid); + } + } } else { $sql = " UPDATE ".MAIN_DB_PREFIX."product"; $sql .= " SET ".$accountancy_field_name." = '".$db->escape($accounting->account_number)."'"; @@ -199,6 +216,9 @@ if ($action == 'update') { } dol_syslog("/accountancy/admin/productaccount.php", LOG_DEBUG); + + $db->begin(); + if ($db->query($sql)) { $ok++; $db->commit(); @@ -234,35 +254,35 @@ $form = new FormAccounting($db); // so we need to get those the rowid of those default value first $accounting = new AccountingAccount($db); // TODO: we should need to check if result is already exists accountaccount rowid..... -$aarowid_servbuy = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT, 1); -$aarowid_servbuy_intra = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT, 1); -$aarowid_servbuy_export = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT, 1); -$aarowid_prodbuy = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT, 1); -$aarowid_prodbuy_intra = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT, 1); -$aarowid_prodbuy_export = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT, 1); -$aarowid_servsell = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT, 1); -$aarowid_servsell_intra = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT, 1); -$aarowid_servsell_export = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT, 1); -$aarowid_prodsell = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT, 1); -$aarowid_prodsell_intra = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT, 1); -$aarowid_prodsell_export = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT, 1); +$aarowid_servbuy = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT'), 1); +$aarowid_servbuy_intra = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT'), 1); +$aarowid_servbuy_export = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT'), 1); +$aarowid_prodbuy = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT'), 1); +$aarowid_prodbuy_intra = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT'), 1); +$aarowid_prodbuy_export = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT'), 1); +$aarowid_servsell = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT'), 1); +$aarowid_servsell_intra = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT'), 1); +$aarowid_servsell_export = $accounting->fetch('', getDolGlobalString('ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT'), 1); +$aarowid_prodsell = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT'), 1); +$aarowid_prodsell_intra = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT'), 1); +$aarowid_prodsell_export = $accounting->fetch('', getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT'), 1); -$aacompta_servbuy = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_servbuy_intra = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_servbuy_export = (!empty($conf->global->ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_prodbuy = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_prodbuy_intra = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_prodbuy_export = (!empty($conf->global->ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_servsell = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_servsell_intra = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_servsell_export = (!empty($conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_prodsell = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_prodsell_intra = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT : $langs->trans("CodeNotDef")); -$aacompta_prodsell_export = (!empty($conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT) ? $conf->global->ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT : $langs->trans("CodeNotDef")); +$aacompta_servbuy = getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_servbuy_intra = getDolGlobalString('ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_servbuy_export = getDolGlobalString('ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_prodbuy = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_prodbuy_intra = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_prodbuy_export = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_servsell = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_servsell_intra = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_servsell_export = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT', $langs->trans("CodeNotDef")); +$aacompta_prodsell = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT', $langs->trans("CodeNotDef")); +$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")); -$pcgverid = $conf->global->CHARTOFACCOUNTS; +$pcgverid = getDolGlobalString('CHARTOFACCOUNTS'); $pcgvercode = dol_getIdFromCode($db, $pcgverid, 'accounting_system', 'rowid', 'pcg_version'); if (empty($pcgvercode)) { $pcgvercode = $pcgverid; diff --git a/htdocs/accountancy/admin/subaccount.php b/htdocs/accountancy/admin/subaccount.php index ad1804048c3..cc0d4de9f31 100644 --- a/htdocs/accountancy/admin/subaccount.php +++ b/htdocs/accountancy/admin/subaccount.php @@ -36,6 +36,7 @@ $cancel = GETPOST('cancel', 'alpha'); $id = GETPOST('id', 'int'); $rowid = GETPOST('rowid', 'int'); $massaction = GETPOST('massaction', 'aZ09'); +$optioncss = GETPOST('optioncss', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'accountingsubaccountlist'; // To manage different context of search $search_subaccount = GETPOST('search_subaccount', 'alpha'); @@ -46,7 +47,7 @@ $search_type = GETPOST('search_type', 'int'); if ($user->socid > 0) { accessforbidden(); } -if (!$user->rights->accounting->chartofaccount) { +if (empty($user->rights->accounting->chartofaccount)) { accessforbidden(); } @@ -367,6 +368,7 @@ if ($resql) { print "\n"; $totalarray = array(); + $totalarray['nbfield'] = 0; $i = 0; while ($i < min($num, $limit)) { $obj = $db->fetch_object($resql); @@ -439,13 +441,13 @@ if ($resql) { $e = ''; // Customer if ($obj->type == 1) { - $e .= ''.img_edit().''; + $e .= ''.img_edit().''; } elseif ($obj->type == 2) { // Supplier - $e .= ''.img_edit().''; + $e .= ''.img_edit().''; } elseif ($obj->type == 3) { // User - $e .= ''.img_edit().''; + $e .= ''.img_edit().''; } print $e; print ''."\n"; diff --git a/htdocs/accountancy/bookkeeping/balance.php b/htdocs/accountancy/bookkeeping/balance.php index 126f61e272c..80dddd28edb 100644 --- a/htdocs/accountancy/bookkeeping/balance.php +++ b/htdocs/accountancy/bookkeeping/balance.php @@ -430,7 +430,7 @@ if ($action != 'export_csv') { print ''; print ''.$accounting_account.''; if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { - print ''.price($opening_balance).''; + print ''.price(price2num($opening_balance, 'MT')).''; } $urlzoom = ''; @@ -444,9 +444,9 @@ if ($action != 'export_csv') { } } // Debit - print ''.price($line->debit).''; + print ''.price(price2num($line->debit, 'MT')).''; // Credit - print ''.price($line->credit).''; + print ''.price(price2num($line->credit, 'MT')).''; if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { print ''.price(price2num($opening_balance + $line->debit - $line->credit, 'MT')).''; @@ -467,10 +467,10 @@ if ($action != 'export_csv') { if (!empty($show_subgroup)) { print ''.$langs->trans("SubTotal").':'; if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { - print ''.price($sous_total_opening_balance).''; + print ''.price(price2num($sous_total_opening_balance, 'MT')).''; } - print ''.price($sous_total_debit).''; - print ''.price($sous_total_credit).''; + print ''.price(price2num($sous_total_debit, 'MT')).''; + print ''.price(price2num($sous_total_credit, 'MT')).''; if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { print '' . price(price2num($sous_total_opening_balance + $sous_total_debit - $sous_total_credit, 'MT')) . ''; } else { @@ -482,10 +482,10 @@ if ($action != 'export_csv') { print ''.$langs->trans("AccountBalance").':'; if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { - print ''.price($total_opening_balance).''; + print ''.price(price2num($total_opening_balance, 'MT')).''; } - print ''.price($total_debit).''; - print ''.price($total_credit).''; + print ''.price(price2num($total_debit, 'MT')).''; + print ''.price(price2num($total_credit, 'MT')).''; if (!empty($conf->global->ACCOUNTANCY_SHOW_OPENING_BALANCE)) { print '' . price(price2num($total_opening_balance + $total_debit - $total_credit, 'MT')) . ''; } else { diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 1fab2cbf894..b772da3ce08 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -433,7 +433,7 @@ if ($action == 'create') { print $langs->trans('Docdate'); print ''; if ($action != 'editdate') { - print 'piece_num.'&mode='.$mode.'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).''; + print 'piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('SetDate'), 1).''; } print ''; print ''; @@ -460,7 +460,7 @@ if ($action == 'create') { print $langs->trans('Codejournal'); print ''; if ($action != 'editjournal') { - print 'piece_num.'&mode='.$mode.'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).''; + print 'piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).''; } print ''; print ''; @@ -487,7 +487,7 @@ if ($action == 'create') { print $langs->trans('Piece'); print ''; if ($action != 'editdocref') { - print 'piece_num.'&mode='.$mode.'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).''; + print 'piece_num).'&mode='.urlencode($mode).'">'.img_edit($langs->transnoentitiesnoconv('Edit'), 1).''; } print ''; print ''; @@ -512,10 +512,10 @@ if ($action == 'create') { print ''; - print '
'; + print '
'; print '
'; - print ''; + print '
'; // Doc type if (!empty($object->doc_type)) { @@ -591,7 +591,7 @@ if ($action == 'create') { */ print "
\n"; - print '
'; + print '
'; print dol_get_fiche_end(); diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index 73c23e4d63b..1b2f376c33f 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -591,7 +591,7 @@ if ($action == 'export_fileconfirm' && $user->rights->accounting->mouvements->ex if (!empty($accountancyexport->errors)) { setEventMessages('', $accountancyexport->errors, 'errors'); - } elseif (!$notifiedexportdate || !$notifiedvalidationdate) { + } elseif (!empty($notifiedexportdate) || !empty($notifiedvalidationdate)) { // Specify as export : update field date_export or date_validated $error = 0; $db->begin(); @@ -602,17 +602,18 @@ if ($action == 'export_fileconfirm' && $user->rights->accounting->mouvements->ex $sql = " UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping"; $sql .= " SET"; - if (!$notifiedexportdate && !$notifiedvalidationdate) { + if (!empty($notifiedexportdate) && !empty($notifiedvalidationdate)) { $sql .= " date_export = '".$db->idate($now)."'"; $sql .= ", date_validated = '".$db->idate($now)."'"; - } elseif (!$notifiedexportdate) { + } elseif (!empty($notifiedexportdate)) { $sql .= " date_export = '".$db->idate($now)."'"; - } elseif (!$notifiedvalidationdate) { + } elseif (!empty($notifiedvalidationdate)) { $sql .= " date_validated = '".$db->idate($now)."'"; } $sql .= " WHERE rowid = ".((int) $movement->id); - dol_syslog("/accountancy/bookeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG); + dol_syslog("/accountancy/bookkeeping/list.php Function export_file Specify movements as exported", LOG_DEBUG); + $result = $db->query($sql); if (!$result) { $error++; @@ -1250,7 +1251,7 @@ while ($i < min($num, $limit)) { } if (empty($line->date_validation)) { if ($user->rights->accounting->mouvements->supprimer) { - print ''.img_delete().''; + print ''.img_delete().''; } } print ''; @@ -1274,7 +1275,7 @@ print ''; // TODO Replace this with mass delete action if ($user->rights->accounting->mouvements->supprimer_tous) { print ''; } diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 27f23d36a74..22ba2d3f0b1 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -904,7 +904,7 @@ while ($i < min($num, $limit)) { } if (empty($line->date_validation)) { if ($user->rights->accounting->mouvements->supprimer) { - print ''.img_delete().''; + print ''.img_delete().''; } } print ''; @@ -957,7 +957,7 @@ print ''; // TODO Replace this with mass delete action if ($user->rights->accounting->mouvements->supprimer_tous) { print ''; } diff --git a/htdocs/accountancy/bookkeeping/listbysubaccount.php b/htdocs/accountancy/bookkeeping/listbysubaccount.php index 5e83c729fb1..101a8897bb5 100644 --- a/htdocs/accountancy/bookkeeping/listbysubaccount.php +++ b/htdocs/accountancy/bookkeeping/listbysubaccount.php @@ -915,7 +915,7 @@ while ($i < min($num, $limit)) { } if (empty($line->date_validation)) { if ($user->rights->accounting->mouvements->supprimer) { - print ''.img_delete().''; + print ''.img_delete().''; } } print ''; @@ -968,7 +968,7 @@ print ''; // TODO Replace this with mass delete action if ($user->rights->accounting->mouvements->supprimer_tous) { print ''; } diff --git a/htdocs/accountancy/class/accountancyexport.class.php b/htdocs/accountancy/class/accountancyexport.class.php index d46580b98b2..07d28b7abdb 100644 --- a/htdocs/accountancy/class/accountancyexport.class.php +++ b/htdocs/accountancy/class/accountancyexport.class.php @@ -87,11 +87,11 @@ class AccountancyExport * * @param DoliDb $db Database handler */ - public function __construct(DoliDB &$db) + public function __construct(DoliDB $db) { global $conf; - $this->db = &$db; + $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"); } @@ -121,8 +121,8 @@ class AccountancyExport self::$EXPORT_TYPE_CHARLEMAGNE => $langs->trans('Modelcsv_charlemagne'), self::$EXPORT_TYPE_LDCOMPTA => $langs->trans('Modelcsv_LDCompta'), self::$EXPORT_TYPE_LDCOMPTA10 => $langs->trans('Modelcsv_LDCompta10'), - self::$EXPORT_TYPE_GESTIMUMV3 => $langs->trans('Modelcsv_Gestinum_v3'), - self::$EXPORT_TYPE_GESTIMUMV5 => $langs->trans('Modelcsv_Gestinum_v5'), + self::$EXPORT_TYPE_GESTIMUMV3 => $langs->trans('Modelcsv_Gestinumv3'), + self::$EXPORT_TYPE_GESTIMUMV5 => $langs->trans('Modelcsv_Gestinumv5'), self::$EXPORT_TYPE_FEC => $langs->trans('Modelcsv_FEC'), self::$EXPORT_TYPE_FEC2 => $langs->trans('Modelcsv_FEC2'), self::$EXPORT_TYPE_ISUITEEXPERT => 'Export iSuite Expert', @@ -479,7 +479,7 @@ class AccountancyExport /** * Export format : CIEL (Format XIMPORT) * Format since 2003 compatible CIEL version > 2002 / Sage50 - * Last review for this format : 2021/07/28 Alexandre Spangaro (aspangaro@open-dsi.fr) + * Last review for this format : 2021-09-13 Alexandre Spangaro (aspangaro@open-dsi.fr) * * Help : https://sage50c.online-help.sage.fr/aide-technique/ * In sage software | Use menu : "Exchange" > "Importing entries..." @@ -507,7 +507,7 @@ class AccountancyExport $Tab = array(); $Tab['num_ecriture'] = str_pad($data->piece_num, 5); - $Tab['code_journal'] = str_pad($data->code_journal, 2); + $Tab['code_journal'] = str_pad(self::trunc($data->code_journal, 2), 2); $Tab['date_ecriture'] = str_pad($date_document, 8, ' ', STR_PAD_LEFT); $Tab['date_echeance'] = str_pad($date_echeance, 8, ' ', STR_PAD_LEFT); $Tab['num_piece'] = str_pad(self::trunc($data->doc_ref, 12), 12); @@ -515,9 +515,9 @@ class AccountancyExport $Tab['libelle_ecriture'] = str_pad(self::trunc(dol_string_unaccent($data->doc_ref).dol_string_unaccent($data->label_operation), 25), 25); $Tab['montant'] = str_pad(price2fec(abs($data->debit - $data->credit)), 13, ' ', STR_PAD_LEFT); $Tab['type_montant'] = str_pad($data->sens, 1); - $Tab['vide'] = str_repeat(' ', 18); + $Tab['vide'] = str_repeat(' ', 18); // Analytical accounting - Not managed in Dolibarr $Tab['intitule_compte'] = str_pad(self::trunc(dol_string_unaccent($data->label_operation), 34), 34); - $Tab['end'] = 'O2003'; + $Tab['end'] = 'O2003'; // 0 = EUR | 2003 = Format Ciel $Tab['end_line'] = $end_line; @@ -527,14 +527,19 @@ class AccountancyExport } /** - * Export format : Quadratus + * Export format : Quadratus (Format ASCII) + * Format since 2015 compatible QuadraCOMPTA + * Last review for this format : 2021/09/13 Alexandre Spangaro (aspangaro@open-dsi.fr) + * + * Help : https://docplayer.fr/20769649-Fichier-d-entree-ascii-dans-quadracompta.html + * In QuadraCompta | Use menu : "Outils" > "Suivi des dossiers" > "Import ASCII(Compta)" * * @param array $TData data * @return void */ public function exportQuadratus(&$TData) { - global $conf; + global $conf, $db; $end_line = "\r\n"; @@ -547,6 +552,44 @@ class AccountancyExport $code_compta = $data->subledger_account; } + $Tab = array(); + + if (!empty($data->subledger_account)) { + $Tab['type_ligne'] = 'C'; + $Tab['num_compte'] = str_pad(self::trunc($data->subledger_account, 8), 8); + $Tab['lib_compte'] = str_pad(self::trunc($data->subledger_label, 30), 30); + + if ($data->doc_type == 'customer_invoice') { + $Tab['lib_alpha'] = strtoupper(str_pad('C'.self::trunc($data->subledger_label, 6), 6)); + $Tab['filler'] = str_repeat(' ', 52); + $Tab['coll_compte'] = str_pad(self::trunc($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER, 8), 8); + } elseif ($data->doc_type == 'supplier_invoice') { + $Tab['lib_alpha'] = strtoupper(str_pad('F'.self::trunc($data->subledger_label, 6), 6)); + $Tab['filler'] = str_repeat(' ', 52); + $Tab['coll_compte'] = str_pad(self::trunc($conf->global->ACCOUNTING_ACCOUNT_SUPPLIER, 8), 8); + } else { + $Tab['filler'] = str_repeat(' ', 59); + $Tab['coll_compte'] = str_pad(' ', 8); + } + + $Tab['filler2'] = str_repeat(' ', 110); + $Tab['Maj'] = 2; // Partial update (alpha key, label, address, collectif, RIB) + + if ($data->doc_type == 'customer_invoice') { + $Tab['type_compte'] = 'C'; + } elseif ($data->doc_type == 'supplier_invoice') { + $Tab['coll_compte'] = 'F'; + } else { + $Tab['coll_compte'] = 'G'; + } + + $Tab['filler3'] = str_repeat(' ', 235); + + $Tab['end_line'] = $end_line; + + print implode($Tab); + } + $Tab = array(); $Tab['type_ligne'] = 'M'; $Tab['num_compte'] = str_pad(self::trunc($code_compta, 8), 8); @@ -871,7 +914,8 @@ class AccountancyExport print "ValidDate".$separator; print "Montantdevise".$separator; print "Idevise".$separator; - print "DateLimitReglmt"; + print "DateLimitReglmt".$separator; + print "NumFacture".$separator; print $end_line; foreach ($objectLines as $line) { @@ -881,9 +925,26 @@ class AccountancyExport $date_creation = dol_print_date($line->date_creation, '%Y%m%d'); $date_document = dol_print_date($line->doc_date, '%Y%m%d'); $date_lettering = dol_print_date($line->date_lettering, '%Y%m%d'); - $date_validation = dol_print_date($line->date_validated, '%Y%m%d'); + $date_validation = dol_print_date($line->date_validation, '%Y%m%d'); $date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d'); + $refInvoice = ''; + if ($line->doc_type == 'customer_invoice') { + // Customer invoice + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $invoice = new Facture($this->db); + $invoice->fetch($line->fk_doc); + + $refInvoice = $invoice->ref; + } elseif ($line->doc_type == 'supplier_invoice') { + // Supplier invoice + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; + $invoice = new FactureFournisseur($this->db); + $invoice->fetch($line->fk_doc); + + $refInvoice = $invoice->ref_supplier; + } + // FEC:JournalCode print $line->code_journal . $separator; @@ -941,6 +1002,9 @@ class AccountancyExport // FEC_suppl:DateLimitReglmt print $date_limit_payment; + // FEC_suppl:NumFacture + print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1) . $separator; + print $end_line; } } @@ -977,7 +1041,8 @@ class AccountancyExport print "ValidDate".$separator; print "Montantdevise".$separator; print "Idevise".$separator; - print "DateLimitReglmt"; + print "DateLimitReglmt".$separator; + print "NumFacture".$separator; print $end_line; foreach ($objectLines as $line) { @@ -987,9 +1052,26 @@ class AccountancyExport $date_creation = dol_print_date($line->date_creation, '%Y%m%d'); $date_document = dol_print_date($line->doc_date, '%Y%m%d'); $date_lettering = dol_print_date($line->date_lettering, '%Y%m%d'); - $date_validation = dol_print_date($line->date_validated, '%Y%m%d'); + $date_validation = dol_print_date($line->date_validation, '%Y%m%d'); $date_limit_payment = dol_print_date($line->date_lim_reglement, '%Y%m%d'); + $refInvoice = ''; + if ($line->doc_type == 'customer_invoice') { + // Customer invoice + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $invoice = new Facture($this->db); + $invoice->fetch($line->fk_doc); + + $refInvoice = $invoice->ref; + } elseif ($line->doc_type == 'supplier_invoice') { + // Supplier invoice + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; + $invoice = new FactureFournisseur($this->db); + $invoice->fetch($line->fk_doc); + + $refInvoice = $invoice->ref_supplier; + } + // FEC:JournalCode print $line->code_journal . $separator; @@ -1047,6 +1129,10 @@ class AccountancyExport // FEC_suppl:DateLimitReglmt print $date_limit_payment; + // FEC_suppl:NumFacture + print dol_trunc(self::toAnsi($refInvoice), 17, 'right', 'UTF-8', 1) . $separator; + + print $end_line; } } diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index fc6acffb46f..50116b94b23 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -1,10 +1,10 @@ - * Copyright (C) 2013-2020 Alexandre Spangaro - * Copyright (C) 2013-2014 Florian Henry + * Copyright (C) 2013-2021 Alexandre Spangaro + * Copyright (C) 2013-2021 Florian Henry * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2015 Ari Elbaz (elarifr) - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018 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 @@ -26,6 +26,9 @@ * \brief File of class to manage accounting accounts */ +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; +require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; /** * Class to manage accounting accounts */ @@ -140,6 +143,11 @@ class AccountingAccount extends CommonObject */ public $reconcilable; + /** + * @var array cache array + */ + private $accountingaccount_codetotid_cache = array(); + /** * Constructor * @@ -225,8 +233,8 @@ class AccountingAccount extends CommonObject /** * Insert new accounting account in chart of accounts * - * @param User $user User making action - * @param int $notrigger Disable triggers + * @param User $user User making action + * @param int $notrigger Disable triggers * @return int <0 if KO, >0 if OK */ public function create($user, $notrigger = 0) @@ -259,7 +267,7 @@ class AccountingAccount extends CommonObject // Put here code to add control on parameters values // Insert request - $sql = "INSERT INTO ".MAIN_DB_PREFIX."accounting_account("; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account("; $sql .= "datec"; $sql .= ", entity"; $sql .= ", fk_pcg_version"; @@ -293,11 +301,11 @@ class AccountingAccount extends CommonObject $resql = $this->db->query($sql); if (!$resql) { $error++; - $this->errors[] = "Error ".$this->db->lasterror(); + $this->errors[] = "Error " . $this->db->lasterror(); } if (!$error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."accounting_account"); + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account"); // Uncomment this and change MYOBJECT to your own tag if you // want this action to call a trigger. @@ -313,8 +321,8 @@ class AccountingAccount extends CommonObject // Commit or rollback if ($error) { foreach ($this->errors as $errmsg) { - dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); - $this->error .= ($this->error ? ', '.$errmsg : $errmsg); + dol_syslog(get_class($this) . "::create " . $errmsg, LOG_ERR); + $this->error .= ($this->error ? ', ' . $errmsg : $errmsg); } $this->db->rollback(); return -1 * $error; @@ -327,7 +335,7 @@ class AccountingAccount extends CommonObject /** * Update record * - * @param User $user Use making update + * @param User $user Use making update * @return int <0 if KO, >0 if OK */ public function update($user) @@ -339,18 +347,18 @@ class AccountingAccount extends CommonObject $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account "; - $sql .= " SET fk_pcg_version = ".($this->fk_pcg_version ? "'".$this->db->escape($this->fk_pcg_version)."'" : "null"); - $sql .= " , pcg_type = ".($this->pcg_type ? "'".$this->db->escape($this->pcg_type)."'" : "null"); - $sql .= " , account_number = '".$this->db->escape($this->account_number)."'"; - $sql .= " , account_parent = ".(int) $this->account_parent; - $sql .= " , label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "''"); - $sql .= " , labelshort = ".($this->labelshort ? "'".$this->db->escape($this->labelshort)."'" : "''"); - $sql .= " , fk_accounting_category = ".(empty($this->account_category) ? 0 : (int) $this->account_category); - $sql .= " , fk_user_modif = ".((int) $user->id); - $sql .= " , active = ".(int) $this->active; - $sql .= " , reconcilable = ".(int) $this->reconcilable; - $sql .= " WHERE rowid = ".((int) $this->id); + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; + $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null"); + $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null"); + $sql .= " , account_number = '" . $this->db->escape($this->account_number) . "'"; + $sql .= " , account_parent = " . (int) $this->account_parent; + $sql .= " , label = " . ($this->label ? "'" . $this->db->escape($this->label) . "'" : "''"); + $sql .= " , labelshort = " . ($this->labelshort ? "'" . $this->db->escape($this->labelshort) . "'" : "''"); + $sql .= " , fk_accounting_category = " . (empty($this->account_category) ? 0 : (int) $this->account_category); + $sql .= " , fk_user_modif = " . ((int) $user->id); + $sql .= " , active = " . (int) $this->active; + $sql .= " , reconcilable = " . (int) $this->reconcilable; + $sql .= " WHERE rowid = " . ((int) $this->id); dol_syslog(get_class($this)."::update", LOG_DEBUG); $result = $this->db->query($sql); @@ -413,22 +421,22 @@ class AccountingAccount extends CommonObject $this->db->begin(); if (!$error) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."accounting_account"; - $sql .= " WHERE rowid=".((int) $this->id); + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account"; + $sql .= " WHERE rowid=" . ((int) $this->id); - dol_syslog(get_class($this)."::delete sql=".$sql); + dol_syslog(get_class($this) . "::delete sql=" . $sql); $resql = $this->db->query($sql); if (!$resql) { $error++; - $this->errors[] = "Error ".$this->db->lasterror(); + $this->errors[] = "Error " . $this->db->lasterror(); } } // Commit or rollback if ($error) { foreach ($this->errors as $errmsg) { - dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); - $this->error .= ($this->error ? ', '.$errmsg : $errmsg); + dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR); + $this->error .= ($this->error ? ', ' . $errmsg : $errmsg); } $this->db->rollback(); return -1 * $error; @@ -444,20 +452,20 @@ class AccountingAccount extends CommonObject /** * Return clicable name (with picto eventually) * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto - * @param int $withlabel 0=No label, 1=Include label of account - * @param int $nourl 1=Disable url - * @param string $moretitle Add more text to title tooltip - * @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 $withcompletelabel 0=Short label (field short label), 1=Complete label (field label) - * @param string $option 'ledger', 'journals', 'accountcard' - * @return string String with URL + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @param int $withlabel 0=No label, 1=Include label of account + * @param int $nourl 1=Disable url + * @param string $moretitle Add more text to title tooltip + * @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 $withcompletelabel 0=Short label (field short label), 1=Complete label (field label) + * @param string $option 'ledger', 'journals', 'accountcard' + * @return string String with URL */ public function getNomUrl($withpicto = 0, $withlabel = 0, $nourl = 0, $moretitle = '', $notooltip = 0, $save_lastsearch_value = -1, $withcompletelabel = 0, $option = '') { global $langs, $conf; - require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php'; if (!empty($conf->dol_no_mouse_hover)) { $notooltip = 1; // Force disable tooltips @@ -465,15 +473,16 @@ class AccountingAccount extends CommonObject $result = ''; - $url = ''; $labelurl = ''; + $url = ''; + $labelurl = ''; if (empty($option) || $option == 'ledger') { - $url = DOL_URL_ROOT.'/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start='.urlencode($this->account_number).'&search_accountancy_code_end='.urlencode($this->account_number); + $url = DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number); $labelurl = $langs->trans("ShowAccountingAccountInLedger"); } elseif ($option == 'journals') { - $url = DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?search_accountancy_code_start='.urlencode($this->account_number).'&search_accountancy_code_end='.urlencode($this->account_number); + $url = DOL_URL_ROOT . '/accountancy/bookkeeping/list.php?search_accountancy_code_start=' . urlencode($this->account_number) . '&search_accountancy_code_end=' . urlencode($this->account_number); $labelurl = $langs->trans("ShowAccountingAccountInJournals"); } elseif ($option == 'accountcard') { - $url = DOL_URL_ROOT.'/accountancy/admin/card.php?id='.urlencode($this->id); + $url = DOL_URL_ROOT . '/accountancy/admin/card.php?id=' . urlencode($this->id); $labelurl = $langs->trans("ShowAccountingAccount"); } @@ -495,29 +504,29 @@ class AccountingAccount extends CommonObject $labeltoshow = $this->labelshort; } - $label = ''.$labelurl.''; + $label = '' . $labelurl . ''; if (!empty($this->account_number)) { - $label .= '
'.$langs->trans('AccountAccounting').': '.length_accountg($this->account_number); + $label .= '
' . $langs->trans('AccountAccounting') . ': ' . length_accountg($this->account_number); } if (!empty($labeltoshow)) { - $label .= '
'.$langs->trans('Label').': '.$labeltoshow; + $label .= '
' . $langs->trans('Label') . ': ' . $labeltoshow; } if ($moretitle) { - $label .= ' - '.$moretitle; + $label .= ' - ' . $moretitle; } $linkclose = ''; if (empty($notooltip)) { if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $labelurl; - $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"'; } - $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' title="' . dol_escape_htmltag($label, 1) . '"'; $linkclose .= ' class="classfortooltip"'; } - $linkstart = ''; + $linkstart = ''; $linkend = ''; if ($nourl) { @@ -528,17 +537,17 @@ class AccountingAccount extends CommonObject $label_link = length_accountg($this->account_number); if ($withlabel) { - $label_link .= ' - '.($nourl ? '' : '').$labeltoshow.($nourl ? '' : ''); + $label_link .= ' - ' . ($nourl ? '' : '') . $labeltoshow . ($nourl ? '' : ''); } if ($withpicto) { - $result .= ($linkstart.img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1).$linkend); + $result .= ($linkstart . img_object(($notooltip ? '' : $label), $picto, ($notooltip ? '' : 'class="classfortooltip"'), 0, 0, $notooltip ? 0 : 1) . $linkend); } if ($withpicto && $withpicto != 2) { $result .= ' '; } if ($withpicto != 2) { - $result .= $linkstart.$label_link.$linkend; + $result .= $linkstart . $label_link . $linkend; } return $result; } @@ -552,10 +561,10 @@ class AccountingAccount extends CommonObject public function info($id) { $sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'accounting_account as a'; - $sql .= ' WHERE a.rowid = '.((int) $id); + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a'; + $sql .= ' WHERE a.rowid = ' . ((int) $id); - dol_syslog(get_class($this).'::info sql='.$sql); + dol_syslog(get_class($this) . '::info sql=' . $sql); $result = $this->db->query($sql); if ($result) { @@ -584,8 +593,8 @@ class AccountingAccount extends CommonObject /** * Deactivate an account (for status active or status reconcilable) * - * @param int $id Id - * @param int $mode 0=field active, 1=field reconcilable + * @param int $id Id + * @param int $mode 0=field active, 1=field reconcilable * @return int <0 if KO, >0 if OK */ public function accountDeactivate($id, $mode = 0) @@ -620,15 +629,15 @@ class AccountingAccount extends CommonObject } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Account activated * - * @param int $id Id - * @param int $mode 0=field active, 1=field reconcilable + * @param int $id Id + * @param int $mode 0=field active, 1=field reconcilable * @return int <0 if KO, >0 if OK */ - public function account_activate($id, $mode = 0) + public function accountActivate($id, $mode = 0) { // phpcs:enable $this->db->begin(); @@ -654,12 +663,11 @@ class AccountingAccount extends CommonObject } } - /** * Retourne le libelle du statut d'un user (actif, inactif) * - * @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=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @return string Label of status */ public function getLibStatut($mode = 0) { @@ -670,9 +678,9 @@ class AccountingAccount extends CommonObject /** * Renvoi le libelle d'un statut donne * - * @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 - * @return string Label of 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 + * @return string Label of status */ public function LibStatut($status, $mode = 0) { @@ -694,9 +702,9 @@ class AccountingAccount extends CommonObject } } elseif ($mode == 2) { if ($status == 1) { - return img_picto($langs->trans('Enabled'), 'statut4').' '.$langs->trans('Enabled'); + return img_picto($langs->trans('Enabled'), 'statut4') . ' ' . $langs->trans('Enabled'); } elseif ($status == 0) { - return img_picto($langs->trans('Disabled'), 'statut5').' '.$langs->trans('Disabled'); + return img_picto($langs->trans('Disabled'), 'statut5') . ' ' . $langs->trans('Disabled'); } } elseif ($mode == 3) { if ($status == 1) { @@ -706,15 +714,206 @@ class AccountingAccount extends CommonObject } } elseif ($mode == 4) { if ($status == 1) { - return img_picto($langs->trans('Enabled'), 'statut4').' '.$langs->trans('Enabled'); + return img_picto($langs->trans('Enabled'), 'statut4') . ' ' . $langs->trans('Enabled'); } elseif ($status == 0) { - return img_picto($langs->trans('Disabled'), 'statut5').' '.$langs->trans('Disabled'); + return img_picto($langs->trans('Disabled'), 'statut5') . ' ' . $langs->trans('Disabled'); } } elseif ($mode == 5) { if ($status == 1) { - return $langs->trans('Enabled').' '.img_picto($langs->trans('Enabled'), 'statut4'); + return $langs->trans('Enabled') . ' ' . img_picto($langs->trans('Enabled'), 'statut4'); } elseif ($status == 0) { - return $langs->trans('Disabled').' '.img_picto($langs->trans('Disabled'), 'statut5'); + return $langs->trans('Disabled') . ' ' . img_picto($langs->trans('Disabled'), 'statut5'); + } + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + + /** + * Return Suggest accounting accounts to bind + * + * @param Societe $buyer Societe Object Buyers + * @param $seller Company Object seller + * @param Product $product Product object sell or buy + * @param Facture $facture Facture + * @param FactureLigne $factureDet Facture Det + * @param array $accountingAccount array of Account account + * @param string $type Customer / Supplier + * + * @return array Accounting accounts suggested + */ + public function getAccountingCodeToBind(Societe $buyer, $seller, Product $product, Facture $facture, FactureLigne $factureDet, $accountingAccount = array(), $type = '') + { + global $conf; + global $hookmanager; + + // Instantiate hooks for external modules + $hookmanager->initHooks(array('accoutancyBindingCalculation')); + + // Execute hook accoutancyBindingCalculation + $parameters = array('buyer' => $buyer, 'seller' => $seller, 'product' => $product, 'facture' => $facture, 'factureDet' => $factureDet ,'accountingAccount'=>$accountingAccount, $type); + $reshook = $hookmanager->executeHooks('accoutancyBindingCalculation', $parameters); // Note that $action and $object may have been modified by some hooks + + if (empty($reshook)) { + if ($type=='customer') { + $const_name = "SOLD"; + } elseif ($type=='supplier') { + $const_name = "BUY"; + } + + require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; + $isBuyerInEEC = isInEEC($buyer); + $isSellerInEEC = isInEEC($seller); + $code_l = ''; + $code_p = ''; + $code_t = ''; + $suggestedid = ''; + + // Level 1: Search suggested default account for product/service + $suggestedaccountingaccountbydefaultfor = ''; + if ($factureDet->product_type == 1) { + if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = ''; + } else { + if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT + $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = 'eecwithvat'; + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number + $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; + } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_INTRA_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = 'eec'; + } else { // Foreign sale + $code_l = (!empty($conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_SERVICE_' . $const_name . '_EXPORT_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = 'export'; + } + } + } elseif ($factureDet->product_type == 0) { + if ($buyer->country_code == $seller->country_code || empty($buyer->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) + $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = ''; + } else { + if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { // European intravat sale, but with a VAT + $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = 'eecwithvat'; + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { // European intravat sale, without VAT intra community number + $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = 'eecwithoutvatnumber'; + } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale + $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_INTRA_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = 'eec'; + } else { + $code_l = (!empty($conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT'}) ? $conf->global->{'ACCOUNTING_PRODUCT_' . $const_name . '_EXPORT_ACCOUNT'} : ''); + $suggestedaccountingaccountbydefaultfor = 'export'; + } + } + } + if ($code_l == -1) { + $code_l = ''; + } + + // Level 2: Search suggested account for product/service (similar code exists in page index.php to make automatic binding) + $suggestedaccountingaccountfor = ''; + if ((($buyer->country_code == $seller->country_code) || empty($buyer->country_code))) { + // If buyer in same country than seller (if not defined, we assume it is same country) + if ($type=='customer' && !empty($product->accountancy_code_sell)) { + $code_p = $product->accountancy_code_sell; + } elseif ($type=='supplier' && !empty($product->accountancy_code_buy)) { + $code_p = $product->accountancy_code_sell; + } + $suggestedid = $accountingAccount['dom']; + $suggestedaccountingaccountfor = 'prodserv'; + } else { + if ($isSellerInEEC && $isBuyerInEEC && $factureDet->tva_tx != 0) { + // European intravat sale, but with VAT + if ($type=='customer' && !empty($product->accountancy_code_sell)) { + $code_p = $product->accountancy_code_sell; + } elseif ($type=='supplier' && !empty($product->accountancy_code_buy)) { + $code_p = $product->accountancy_code_sell; + } + $suggestedid = $accountingAccount['dom']; + $suggestedaccountingaccountfor = 'eecwithvat'; + } elseif ($isSellerInEEC && $isBuyerInEEC && empty($buyer->tva_intra)) { + // European intravat sale, without VAT intra community number + if ($type=='customer' && !empty($product->accountancy_code_sell)) { + $code_p = $product->accountancy_code_sell; + } elseif ($type=='supplier' && !empty($product->accountancy_code_buy)) { + $code_p = $product->accountancy_code_sell; + } + $suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ? + $suggestedaccountingaccountfor = 'eecwithoutvatnumber'; + } elseif ($isSellerInEEC && $isBuyerInEEC && !empty($product->accountancy_code_sell_intra)) { + // European intravat sale + if ($type=='customer' && !empty($product->accountancy_code_sell_intra)) { + $code_p = $product->accountancy_code_sell_intra; + } elseif ($type=='supplier' && !empty($product->accountancy_code_buy_intra)) { + $code_p = $product->accountancy_code_buy_intra; + } + $suggestedid = $accountingAccount['intra']; + $suggestedaccountingaccountfor = 'eec'; + } else { + // Foreign sale + // European intravat sale + if ($type=='customer' && !empty($product->accountancy_code_sell_export)) { + $code_p = $product->accountancy_code_sell_export; + } elseif ($type=='supplier' && !empty($product->accountancy_code_sell_export)) { + $code_p = $product->accountancy_code_sell_export; + } + $suggestedid = $accountingAccount['export']; + $suggestedaccountingaccountfor = 'export'; + } + } + + // Level 3: Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding) + if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { + if (!empty($buyer->code_compta)) { + $code_t = $buyer->code_compta; + $suggestedid = $accountingAccount['thirdparty']; + $suggestedaccountingaccountfor = 'thridparty'; + } + } + + // Manage Deposit + if ($factureDet->desc == "(DEPOSIT)") { + $accountdeposittoventilated = new self($this->db); + $result = $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1); + if ($result < 0) { + return -1; + } + + $code_l = $accountdeposittoventilated->ref; + $suggestedid = $accountdeposittoventilated->rowid; + $suggestedaccountingaccountfor = 'deposit'; + } + + if (empty($suggestedid) && empty($code_p) && !empty($code_l) && empty($conf->global->ACCOUNTANCY_DO_NOT_AUTOFILL_ACCOUNT_WITH_GENERIC)) { + if (empty($this->accountingaccount_codetotid_cache[$code_l])) { + $tmpaccount = new self($this->db); + $result = $tmpaccount->fetch(0, $code_l, 1); + if ($result < 0) { + return -1; + } + if ($tmpaccount->id > 0) { + $suggestedid = $tmpaccount->id; + } + $this->accountingaccount_codetotid_cache[$code_l] = $tmpaccount->id; + } else { + $suggestedid = $this->accountingaccount_codetotid_cache[$code_l]; + } + } + return array( + 'suggestedaccountingaccountbydefaultfor' => $suggestedaccountingaccountbydefaultfor, + 'suggestedaccountingaccountfor' => $suggestedaccountingaccountfor, + 'suggestedid' => $suggestedid, + 'code_l' => $code_l, + 'code_p' => $code_p, + 'code_t' => $code_t, + ); + } else { + if (is_array($hookmanager->resArray) && !empty($hookmanager->resArray)) { + return $hookmanager->resArray; } } } diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index d47078af06c..9cda04f6155 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -888,9 +888,11 @@ class BookKeeping extends CommonObject // Affichage par compte comptable if (!empty($option)) { $sql .= ' AND t.subledger_account IS NOT NULL'; - $sql .= ' ORDER BY t.subledger_account ASC'; + $sortfield = 't.subledger_account'.($sortfield ? ','.$sortfield : ''); + $sortorder = 'ASC'.($sortfield ? ','.$sortfield : ''); } else { - $sql .= ' ORDER BY t.numero_compte ASC'; + $sortfield = 't.numero_compte'.($sortfield ? ','.$sortfield : ''); + $sortorder = 'ASC'.($sortorder ? ','.$sortorder : ''); } $sql .= $this->db->order($sortfield, $sortorder); @@ -935,7 +937,6 @@ class BookKeeping extends CommonObject $line->piece_num = $obj->piece_num; $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_validated); $line->date_validation = $this->db->jdate($obj->date_validation); $this->lines[] = $line; @@ -1088,7 +1089,6 @@ class BookKeeping extends CommonObject $line->date_lim_reglement = $this->db->jdate($obj->date_lim_reglement); $line->date_modification = $this->db->jdate($obj->date_modification); $line->date_export = $this->db->jdate($obj->date_export); - $line->date_validation = $this->db->jdate($obj->date_validated); $line->date_validation = $this->db->jdate($obj->date_validation); $this->lines[] = $line; @@ -1750,7 +1750,6 @@ class BookKeeping extends CommonObject $line->date_creation = $obj->date_creation; $line->date_modification = $obj->date_modification; $line->date_export = $obj->date_export; - $line->date_validation = $obj->date_validated; $line->date_validation = $obj->date_validation; $this->linesmvt[] = $line; @@ -1815,7 +1814,6 @@ class BookKeeping extends CommonObject $line->sens = $obj->sens; $line->code_journal = $obj->code_journal; $line->piece_num = $obj->piece_num; - $line->date_validation = $obj->date_validated; $line->date_validation = $obj->date_validation; $this->linesexport[] = $line; diff --git a/htdocs/accountancy/closure/index.php b/htdocs/accountancy/closure/index.php index a7220d01a28..fdcc6f54ab3 100644 --- a/htdocs/accountancy/closure/index.php +++ b/htdocs/accountancy/closure/index.php @@ -63,7 +63,7 @@ if (empty($conf->accounting->enabled)) { if ($user->socid > 0) { accessforbidden(); } -if (!$user->rights->accounting->fiscalyear->write) { +if (empty($user->rights->accounting->fiscalyear->write)) { accessforbidden(); } diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index 3b30d00dbf6..a264411c501 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; // Load translation files required by the page $langs->loadLangs(array("compta", "bills", "other", "accountancy")); @@ -42,10 +43,11 @@ if (empty($conf->accounting->enabled)) { if ($user->socid > 0) { accessforbidden(); } -if (!$user->rights->accounting->bind->write) { +if (empty($user->rights->accounting->bind->write)) { accessforbidden(); } +$accountingAccount = new AccountingAccount($db); $month_start = ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); if (GETPOST("year", 'int')) { @@ -71,12 +73,23 @@ $action = GETPOST('action', 'aZ09'); $chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version'); +// Security check +if (empty($conf->accounting->enabled)) { + accessforbidden(); +} +if ($user->socid > 0) { + accessforbidden(); +} +if (empty($user->rights->accounting->mouvements->lire)) { + accessforbidden(); +} + /* * Actions */ -if ($action == 'clean' || $action == 'validatehistory') { +if (($action == 'clean' || $action == 'validatehistory') && $user->rights->accounting->bind->write) { // Clean database $db->begin(); $sql1 = "UPDATE ".MAIN_DB_PREFIX."facturedet as fd"; @@ -163,6 +176,7 @@ if ($action == 'validatehistory') { } dol_syslog('htdocs/accountancy/customer/index.php'); + $result = $db->query($sql); if (!$result) { $error++; @@ -170,37 +184,78 @@ if ($action == 'validatehistory') { } else { $num_lines = $db->num_rows($result); + $facture_static = new Facture($db); + $isSellerInEEC = isInEEC($mysoc); + $thirdpartystatic = new Societe($db); + $facture_static = new Facture($db); + $facture_static_det = new FactureLigne($db); + $product_static = new Product($db); + $i = 0; while ($i < min($num_lines, 10000)) { // No more than 10000 at once $objp = $db->fetch_object($result); - $isBuyerInEEC = isInEEC($objp); // This make a database request but there is a cache into $conf->cache['country_code_in_EEC'] + $thirdpartystatic->id = $objp->socid; + $thirdpartystatic->name = $objp->name; + $thirdpartystatic->client = $objp->client; + $thirdpartystatic->fournisseur = $objp->fournisseur; + $thirdpartystatic->code_client = $objp->code_client; + $thirdpartystatic->code_compta_client = $objp->code_compta_client; + $thirdpartystatic->code_fournisseur = $objp->code_fournisseur; + $thirdpartystatic->code_compta_fournisseur = $objp->code_compta_fournisseur; + $thirdpartystatic->email = $objp->email; + $thirdpartystatic->country_code = $objp->country_code; + $thirdpartystatic->tva_intra = $objp->tva_intra; + $thirdpartystatic->code_compta = $objp->company_code_sell; - // Level 2: Search suggested account for product/service (similar code exists in page list.php to make manual binding) - $suggestedaccountingaccountfor = ''; - if (($objp->country_code == $mysoc->country_code) || empty($objp->country_code)) { // If buyer in same country than seller (if not defined, we assume it is same country) - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = $objp->aarowid; - $suggestedaccountingaccountfor = ''; + $product_static->ref = $objp->product_ref; + $product_static->id = $objp->product_id; + $product_static->type = $objp->type; + $product_static->label = $objp->product_label; + $product_static->status = $objp->status; + $product_static->status_buy = $objp->status_buy; + $product_static->accountancy_code_sell = $objp->code_sell; + $product_static->accountancy_code_sell_intra = $objp->code_sell_intra; + $product_static->accountancy_code_sell_export = $objp->code_sell_export; + $product_static->accountancy_code_buy = $objp->code_buy; + $product_static->accountancy_code_buy_intra = $objp->code_buy_intra; + $product_static->accountancy_code_buy_export = $objp->code_buy_export; + $product_static->tva_tx = $objp->tva_tx_prod; + + $facture_static->ref = $objp->ref; + $facture_static->id = $objp->facid; + $facture_static->type = $objp->ftype; + $facture_static->date = $objp->datef; + + $facture_static_det->id = $objp->rowid; + $facture_static_det->total_ht = $objp->total_ht; + $facture_static_det->tva_tx = $objp->tva_tx_line; + $facture_static_det->vat_src_code = $objp->vat_src_code; + $facture_static_det->product_type = $objp->type_l; + $facture_static_det->desc = $objp->description; + + $accountingAccountArray = array( + 'dom'=>$objp->aarowid, + 'intra'=>$objp->aarowid_intra, + 'export'=>$objp->aarowid_export, + 'thirdparty' =>$objp->aarowid_thirdparty); + + $code_sell_p_notset = ''; + $code_sell_t_notset = ''; + + $return=$accountingAccount->getAccountingCodeToBind($thirdpartystatic, $mysoc, $product_static, $facture_static, $facture_static_det, $accountingAccountArray, 'customer'); + if (!is_array($return) && $return<0) { + setEventMessage($accountingAccount->error, 'errors'); } else { - if ($isSellerInEEC && $isBuyerInEEC && $objp->tva_tx_line != 0) { // European intravat sale, but with VAT - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = $objp->aarowid; - $suggestedaccountingaccountfor = 'eecwithvat'; - } elseif ($isSellerInEEC && $isBuyerInEEC && empty($objp->tva_intra)) { // European intravat sale, without VAT intra community number - $objp->code_sell_p = $objp->code_sell; - $objp->aarowid_suggest = 0; // There is a doubt, no automatic binding - $suggestedaccountingaccountfor = 'eecwithoutvatnumber'; - } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale - $objp->code_sell_p = $objp->code_sell_intra; - $objp->aarowid_suggest = $objp->aarowid_intra; - $suggestedaccountingaccountfor = 'eec'; - } else { // Foreign sale - $objp->code_sell_p = $objp->code_sell_export; - $objp->aarowid_suggest = $objp->aarowid_export; - $suggestedaccountingaccountfor = 'export'; + $suggestedid=$return['suggestedid']; + $suggestedaccountingaccountfor=$return['suggestedaccountingaccountfor']; + + if (!empty($suggestedid) && $suggestedaccountingaccountfor<>'') { + $suggestedid=$return['suggestedid']; + } else { + $suggestedid=0; } } @@ -213,10 +268,22 @@ if ($action == 'validatehistory') { } } + // Manage Deposit + if (!empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT)) { + if ($objp->description == "(DEPOSIT)" || $objp->ftype == $facture_static::TYPE_DEPOSIT) { + $accountdeposittoventilated = new AccountingAccount($db); + $accountdeposittoventilated->fetch('', $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT, 1); + $objp->code_sell_l = $accountdeposittoventilated->ref; + $objp->code_sell_p = ''; + $objp->code_sell_t = ''; + $objp->aarowid_suggest = $accountdeposittoventilated->rowid; + } + } + if ($objp->aarowid_suggest > 0) { $sqlupdate = "UPDATE ".MAIN_DB_PREFIX."facturedet"; - $sqlupdate .= " SET fk_code_ventilation = ".((int) $objp->aarowid_suggest); - $sqlupdate .= " WHERE fk_code_ventilation <= 0 AND product_type <= 2 AND rowid = ".((int) $objp->rowid); + $sqlupdate .= " SET fk_code_ventilation = ".((int) $suggestedid); + $sqlupdate .= " WHERE fk_code_ventilation <= 0 AND product_type <= 2 AND rowid = ".((int) $facture_static_det->id); $resqlupdate = $db->query($sqlupdate); if (!$resqlupdate) { @@ -260,13 +327,13 @@ $y = $year_current; $buttonbind = ''.$langs->trans("ValidateHistory").''; -print_barre_liste($langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1); +print_barre_liste(img_picto('', 'unlink', 'class="paddingright fa-color-unset"').$langs->trans("OverviewOfAmountOfLinesNotBound"), '', '', '', '', '', '', -1, '', '', 0, $buttonbind, '', 0, 1, 1); //print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesNotBound"), $buttonbind, ''); print '
'; print ''; -print ''; -print ''; +print ''; +print ''; for ($i = 1; $i <= 12; $i++) { $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1; if ($j > 12) { @@ -314,12 +381,12 @@ if ($resql) { while ($row = $db->fetch_row($resql)) { print ''; - print ''; $entry .= ''; $entry .= ''; $entry .= ''; diff --git a/htdocs/categories/photos.php b/htdocs/categories/photos.php index 5fb1c85dd40..5c014b6206f 100644 --- a/htdocs/categories/photos.php +++ b/htdocs/categories/photos.php @@ -231,10 +231,10 @@ if ($object->id) { // On propose la generation de la vignette si elle n'existe pas et si la taille est superieure aux limites if (!$obj['photo_vignette'] && preg_match('/(\.bmp|\.gif|\.jpg|\.jpeg|\.png)$/i', $obj['photo']) && ($object->imgWidth > $maxWidth || $object->imgHeight > $maxHeight)) { - print ''.img_picto($langs->trans('GenerateThumb'), 'refresh').'  '; + print ''.img_picto($langs->trans('GenerateThumb'), 'refresh').'  '; } if ($user->rights->categorie->creer) { - print ''; + print ''; print img_delete().''; } if ($nbbyrow) { diff --git a/htdocs/categories/traduction.php b/htdocs/categories/traduction.php index 80f64210bf5..2bbb4b5f0a8 100644 --- a/htdocs/categories/traduction.php +++ b/htdocs/categories/traduction.php @@ -231,9 +231,9 @@ print "\n
\n"; if ($action == '') { if ($user->rights->produit->creer || $user->rights->service->creer) { - print ''.$langs->trans('Add').''; + print ''.$langs->trans('Add').''; if ($cnt_trans > 0) { - print ''.$langs->trans('Update').''; + print ''.$langs->trans('Update').''; } } } diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index 8ebb9f43b1e..5912d63c7cf 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -173,7 +173,12 @@ if ($elemid && $action == 'addintocategory' && (($type == Categorie::TYPE_PRODUCT && ($user->rights->produit->creer || $user->rights->service->creer)) || ($type == Categorie::TYPE_CUSTOMER && $user->rights->societe->creer) || ($type == Categorie::TYPE_SUPPLIER && $user->rights->societe->creer) || - ($type == Categorie::TYPE_TICKET && $user->rights->ticket->write) + ($type == Categorie::TYPE_TICKET && $user->rights->ticket->write) || + ($type == Categorie::TYPE_PROJECT && $user->rights->projet->creer) || + ($type == Categorie::TYPE_MEMBER && $user->rights->projet->creer) || + ($type == Categorie::TYPE_CONTACT && $user->rights->societe->creer) || + ($type == Categorie::TYPE_USER && $user->rights->user->user->creer) || + ($type == Categorie::TYPE_ACCOUNT && $user->rights->banque->configurer) )) { if ($type == Categorie::TYPE_PRODUCT) { require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; @@ -191,6 +196,26 @@ if ($elemid && $action == 'addintocategory' && require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php'; $newobject = new Ticket($db); $elementtype = 'ticket'; + } elseif ($type == Categorie::TYPE_PROJECT) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; + $newobject = new Project($db); + $elementtype = 'project'; + } elseif ($type == Categorie::TYPE_MEMBER) { + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; + $newobject = new Adherent($db); + $elementtype = 'member'; + } elseif ($type == Categorie::TYPE_CONTACT) { + require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + $newobject = new Contact($db); + $elementtype = 'contact'; + } elseif ($type == Categorie::TYPE_USER) { + require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + $newobject = new User($db); + $elementtype = 'user'; + } elseif ($type == Categorie::TYPE_ACCOUNT) { + require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + $newobject = new User($db); + $elementtype = 'bank_account'; } $result = $newobject->fetch($elemid); @@ -199,7 +224,7 @@ if ($elemid && $action == 'addintocategory' && if ($result >= 0) { setEventMessages($langs->trans("WasAddedSuccessfully", $newobject->ref), null, 'mesgs'); } else { - if ($cat->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { setEventMessages($langs->trans("ObjectAlreadyLinkedToCategory"), null, 'warnings'); } else { setEventMessages($object->error, $object->errors, 'errors'); @@ -538,6 +563,7 @@ if ($type == Categorie::TYPE_PRODUCT) { } } +// List of customers if ($type == Categorie::TYPE_CUSTOMER) { $permission = $user->rights->societe->creer; @@ -611,7 +637,7 @@ if ($type == Categorie::TYPE_CUSTOMER) { } } - +// List of suppliers if ($type == Categorie::TYPE_SUPPLIER) { $permission = $user->rights->societe->creer; @@ -696,6 +722,26 @@ if ($type == Categorie::TYPE_MEMBER) { if ($prods < 0) { dol_print_error($db, $object->error, $object->errors); } else { + // Form to add record into a category + $showclassifyform = 1; + if ($showclassifyform) { + print '
'; + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
'.$langs->trans("Account").''.$langs->trans("Label").'
'.$langs->trans("Account").''.$langs->trans("Label").'
'; if ($row[0] == 'tobind') { - print $langs->trans("Unknown"); + print ''.$langs->trans("Unknown").''; } else { print length_accountg($row[0]); } print ''; + print ''; if ($row[0] == 'tobind') { print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/customer/list.php?search_year='.$y, $langs->transnoentitiesnoconv("ToBind")); } else { @@ -344,13 +411,13 @@ print ''; print '
'; -print_barre_liste($langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1); +print_barre_liste(img_picto('', 'link', 'class="paddingright fa-color-unset"').$langs->trans("OverviewOfAmountOfLinesBound"), '', '', '', '', '', '', -1, '', '', 0, '', '', 0, 1, 1); //print load_fiche_titre($langs->trans("OverviewOfAmountOfLinesBound"), '', ''); print '
'; print ''; -print ''; -print ''; +print ''; +print ''; for ($i = 1; $i <= 12; $i++) { $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1; if ($j > 12) { @@ -404,7 +471,7 @@ if ($resql) { } print ''; - print ''; } else { print '"; } diff --git a/htdocs/admin/ldap.php b/htdocs/admin/ldap.php index 80897320e90..abdf6b75073 100644 --- a/htdocs/admin/ldap.php +++ b/htdocs/admin/ldap.php @@ -1,10 +1,10 @@ - * Copyright (C) 2004 Sebastien Di Cintio - * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005-2017 Regis Houssin - * Copyright (C) 2006-2020 Laurent Destailleur - * Copyright (C) 2011-2013 Juanjo Menent +/* Copyright (C) 2004 Rodolphe Quiedeville + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005-2017 Regis Houssin + * Copyright (C) 2006-2020 Laurent Destailleur + * Copyright (C) 2011-2013 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 @@ -43,6 +43,7 @@ $action = GETPOST('action', 'aZ09'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('adminldap', 'globaladmin')); + /* * Actions */ @@ -130,7 +131,7 @@ if (!function_exists("ldap_connect")) { $form = new Form($db); -print '
'; +print ''; print ''; print dol_get_fiche_head($head, 'ldap', $langs->trans("LDAPSetup"), -1); @@ -150,9 +151,9 @@ $arraylist['0'] = $langs->trans("No"); $arraylist['ldap2dolibarr'] = $langs->trans("LDAPToDolibarr"); $arraylist['dolibarr2ldap'] = $langs->trans("DolibarrToLDAP"); print $form->selectarray('activesynchro', $arraylist, $conf->global->LDAP_SYNCHRO_ACTIVE); -print '
'; @@ -163,7 +164,7 @@ if (!empty($conf->societe->enabled)) { $arraylist['0'] = $langs->trans("No"); $arraylist['1'] = $langs->trans("DolibarrToLDAP"); print $form->selectarray('activecontact', $arraylist, $conf->global->LDAP_CONTACT_ACTIVE); - print ''; + print ''; } // Synchro member active @@ -174,7 +175,7 @@ if (!empty($conf->adherent->enabled)) { $arraylist['1'] = $langs->trans("DolibarrToLDAP"); $arraylist['ldap2dolibarr'] = $langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; print $form->selectarray('activemembers', $arraylist, $conf->global->LDAP_MEMBER_ACTIVE); - print ''; + print ''; } // Synchro member type active @@ -185,7 +186,7 @@ if (!empty($conf->adherent->enabled)) { $arraylist['1'] = $langs->trans("DolibarrToLDAP"); $arraylist['ldap2dolibarr'] = $langs->trans("LDAPToDolibarr").' ('.$langs->trans("SupportedForLDAPImportScriptOnly").')'; print $form->selectarray('activememberstypes', $arraylist, $conf->global->LDAP_MEMBER_TYPE_ACTIVE); - print ''; + print ''; } // Fields from hook @@ -214,33 +215,33 @@ $arraylist = array(); $arraylist['3'] = 'Version 3'; $arraylist['2'] = 'Version 2'; print $form->selectarray('LDAP_SERVER_PROTOCOLVERSION', $arraylist, $conf->global->LDAP_SERVER_PROTOCOLVERSION); -print ''; +print ''; // Serveur primaire print ''; +print ''; +print ''; // Serveur secondaire print ''; +print ''; +print ''; // Port print ''; +print ''; // DNserver print ''; +print ''; +print ''; // Utiliser TLS print ''; +print ''; print ''; print ''; @@ -257,18 +258,18 @@ print "\n"; // DNAdmin print ''; print ''; +print ''; +print ''; // Pass print ''; print ''; +print ''; print '
'.$langs->trans("Account").''.$langs->trans("Label").'
'.$langs->trans("Account").''.$langs->trans("Label").''; + print ''; if ($row[0] == 'tobind') { print $langs->trans("UseMenuToSetBindindManualy", DOL_URL_ROOT.'/accountancy/customer/list.php?search_year='.$y, $langs->transnoentitiesnoconv("ToBind")); } else { @@ -436,7 +503,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange print '
'; print ''; - print ''; + print ''; for ($i = 1; $i <= 12; $i++) { $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1; if ($j > 12) { @@ -497,7 +564,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) { // This part of code looks strange print "
\n"; print '
'; print '
'.$langs->trans("TotalVente").'
'.$langs->trans("TotalVente").'
'; - print ''; + print ''; for ($i = 1; $i <= 12; $i++) { $j = $i + ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1) - 1; if ($j > 12) { diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index 55700fe8439..7f09e111a23 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -191,7 +191,14 @@ print ''; + } + } 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); + } + } else { + print ''; + } + print ''; + } + } + print '
'.$langs->trans("TotalMarge").'
'.$langs->trans("TotalMarge").'
'; + + print '
'; + print ''; + print '
'; + + print ''; + print '
'; +} else { + if (!empty($arrayofparameters)) { + print ''; + print ''; + + foreach ($arrayofparameters as $constname => $val) { + if ($val['enabled']==1) { + $setupnotempty++; + print ''; + } + } + + print '
'.$langs->trans("Parameter").''.$langs->trans("Value").'
'; + $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'); + } + $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"); + } + } else { + print $conf->global->{$constname}; + } + print '
    '; + + print '
    '; + print ''.$langs->trans("Modify").''; + print '
    '; + } else { + print '
    '.$langs->trans("NothingToSetup"); + } +} + + +if (empty($setupnotempty)) { + print '
    '.$langs->trans("NothingToSetup"); +} + +// Page end +print dol_get_fiche_end(); + +llxFooter(); +$db->close(); diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 9d8f655a608..697f8fa2130 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2017 Regis Houssin * Copyright (C) 2016 Juanjo Menent * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2021 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 @@ -43,7 +44,7 @@ if (!$user->admin) { $action = GETPOST('action', 'aZ09'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'adminihm'; // To manage different context of search -$mode = GETPOST('mode', 'aZ09') ? GETPOST('mode', 'aZ09') : 'language'; // 'language', 'template', 'login', 'other' +$mode = GETPOST('mode', 'aZ09') ? GETPOST('mode', 'aZ09') : 'other'; // 'template', 'dashboard', 'login', 'other' if (!defined("MAIN_MOTD")) { define("MAIN_MOTD", ""); @@ -96,12 +97,6 @@ if ($action == 'removebackgroundlogin' && !empty($conf->global->MAIN_LOGIN_BACKG if ($action == 'update') { $error = 0; - if ($mode == 'language') { - dolibarr_set_const($db, "MAIN_LANG_DEFAULT", GETPOST("MAIN_LANG_DEFAULT", 'aZ09'), 'chaine', 0, '', $conf->entity); - dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); - //dolibarr_set_const($db, "MAIN_MULTILANGS", GETPOST("MAIN_MULTILANGS"), 'chaine', 0, '', $conf->entity); - } - if ($mode == 'template') { dolibarr_set_const($db, "MAIN_THEME", GETPOST("main_theme", 'aZ09'), 'chaine', 0, '', $conf->entity); @@ -206,7 +201,14 @@ if ($action == 'update') { } } + if ($mode == 'dashboard') { + dolibarr_set_const($db, "MAIN_MOTD", dol_htmlcleanlastbr(GETPOST("main_motd", 'restricthtml')), 'chaine', 0, '', $conf->entity); + } + if ($mode == 'other') { + dolibarr_set_const($db, "MAIN_LANG_DEFAULT", GETPOST("MAIN_LANG_DEFAULT", 'aZ09'), 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); + dolibarr_set_const($db, "MAIN_SIZE_LISTE_LIMIT", GETPOST("main_size_liste_limit", 'int'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_SIZE_SHORTLIST_LIMIT", GETPOST("main_size_shortliste_limit", 'int'), 'chaine', 0, '', $conf->entity); @@ -221,8 +223,6 @@ if ($action == 'update') { dolibarr_set_const($db, "MAIN_BUGTRACK_ENABLELINK", GETPOST("MAIN_BUGTRACK_ENABLELINK", 'alpha'), 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_FIRSTNAME_NAME_POSITION", GETPOST("MAIN_FIRSTNAME_NAME_POSITION", 'aZ09'), 'chaine', 0, '', $conf->entity); - - dolibarr_set_const($db, "MAIN_MOTD", dol_htmlcleanlastbr(GETPOST("main_motd", 'restricthtml')), 'chaine', 0, '', $conf->entity); } if ($mode == 'login') { @@ -299,12 +299,143 @@ $head = ihm_prepare_head(); print dol_get_fiche_head($head, $mode, '', -1, ''); +print '
    '; + clearstatcache(); -if ($mode == 'language') { +if ($mode == 'template') { + // Themes and themes options + showSkins(null, 1); +} + +if ($mode == 'dashboard') { + print '
    '; + print ''; + + // Message of the day on home page + $substitutionarray = getCommonSubstitutionArray($langs, 0, array('object', 'objectamount')); + complete_substitutions_array($substitutionarray, $langs); + + print '' . "\n"; + + /* no more need for this option. It is now a widget already controlled by end user + print ''; + print ''; + */ + + print '
    '; + $texthelp = $langs->trans("FollowingConstantsWillBeSubstituted") . '
    '; + foreach ($substitutionarray as $key => $val) { + $texthelp .= $key . '
    '; + } + print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessageofday'); + + print '
    '; + + $doleditor = new DolEditor('main_motd', (isset($conf->global->MAIN_MOTD) ? $conf->global->MAIN_MOTD : ''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); + $doleditor->Create(); + + print '
    ' . $langs->trans('BoxstatsDisableGlobal') . ''; + print ajax_constantonoff("MAIN_DISABLE_GLOBAL_BOXSTATS", array(), $conf->entity, 0, 0, 1, 0); + print '
    '; + print '
    '; + + print '
    '; + + print '
    '; + print ''; + + print ''; + + print ''; + print ''; + + if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { + // Block meteo + print ''; + print ''; + + // Block agenda + print ''; + print ''; + + // Block agenda + print ''; + print ''; + + // Block customer + print ''; + print ''; + + // Block supplier + print ''; + print ''; + + // Block contract + print ''; + print ''; + + // Block ticket + print ''; + print ''; + + // Block bank + print ''; + print ''; + + // Block adherent + print ''; + print ''; + + // Block expense report + print ''; + print ''; + + // Block holiday + print ''; + print ''; + } + + print '
    '; + print $langs->trans("DashboardDisableBlocks"); + print ''; + print '
    ' . $langs->trans('DashboardDisableGlobal') . ''; + print ajax_constantonoff("MAIN_DISABLE_GLOBAL_WORKBOARD", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('MAIN_DISABLE_METEO') . ''; + print ajax_constantonoff("MAIN_DISABLE_METEO", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockAgenda') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_AGENDA", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockProject') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_PROJECT", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockCustomer') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_CUSTOMER", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockSupplier') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_SUPPLIER", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockContract') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_CONTRACT", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockTicket') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_TICKET", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockBank') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_BANK", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockAdherent') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_ADHERENT", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockExpenseReport') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_EXPENSEREPORT", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . $langs->trans('DashboardDisableBlockHoliday') . ''; + print ajax_constantonoff("MAIN_DISABLE_BLOCK_HOLIDAY", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '_red', 'dashboard'); + print '
    ' . "\n"; + print '
    '; +} + +if ($mode == 'other') { print '
    '; print ''; + print ''; + // Default language print ''; print ''; print '
    '; + print $langs->trans("Language"); + print ''; + print '
    '.$langs->trans("DefaultLanguage").''; print img_picto('', 'language', 'class="pictofixedwidth"'); @@ -315,32 +446,28 @@ if ($mode == 'language') { // Multilingual GUI print '
    ' . $langs->trans("EnableMultilangInterface") . ''; - print ajax_constantonoff("MAIN_MULTILANGS", array(), $conf->entity, 0, 0, 1, 0); + print ajax_constantonoff("MAIN_MULTILANGS", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'language'); print '
    ' . "\n"; print '
    '; -} -if ($mode == 'template') { - // Themes and themes options - showSkins(null, 1); -} + print '
    '; + print ''; + print '
    '; + + print '
    '; + print '
    '; -if ($mode == 'other') { // Other print '
    '; print ''; - // Disable javascript and ajax - print ''; - print ''; - print ''; + print ''; // Max size of lists print ''; @@ -393,7 +520,7 @@ if ($mode == 'other') { // Hide unauthorized menus print ''; print ''; print ''; @@ -401,7 +528,7 @@ if ($mode == 'other') { // Hide unauthorized button print ''; print ''; print ''; @@ -417,7 +544,9 @@ if ($mode == 'other') { */ // Show bugtrack link - print ''; print ''; @@ -426,29 +555,20 @@ if ($mode == 'other') { // Hide wiki link on login page $pictohelp = ''; print ''; print ''; print ''; - // Message of the day on home page - $substitutionarray = getCommonSubstitutionArray($langs, 0, array('object', 'objectamount')); - complete_substitutions_array($substitutionarray, $langs); - - print '' . "\n"; + // Disable javascript and ajax + print ''; + print ''; + print ''; print '
    ' . $langs->trans("DisableJavascript") . ''; - print ajax_constantonoff("MAIN_DISABLE_JAVASCRIPT", array(), $conf->entity, 0, 0, 1, 0); - print '     ' . $langs->trans("DisableJavascriptNote") . ''; - print ''; - print '
    '; + print $langs->trans("Miscelaneous"); + print ''; + print '
    ' . $langs->trans("DefaultMaxSizeList") . '
    ' . $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); + 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); + print ajax_constantonoff("MAIN_BUTTON_HIDE_UNAUTHORIZED", array(), $conf->entity, 0, 0, 1, 0, 0, 0, '', 'other'); print ' 
    ' . $langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")) . ''; + 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); + 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 ' 
    '; - $texthelp = $langs->trans("FollowingConstantsWillBeSubstituted") . '
    '; - foreach ($substitutionarray as $key => $val) { - $texthelp .= $key . '
    '; - } - print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessageofday'); - - print '
    '; - - $doleditor = new DolEditor('main_motd', (isset($conf->global->MAIN_MOTD) ? $conf->global->MAIN_MOTD : ''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); - $doleditor->Create(); - - 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 '
    '; @@ -459,11 +579,16 @@ if ($mode == 'login') { print '
    '; print ''; + print ''; + // Hide helpcenter link on login page print ''; - print ''; print ''; // Message on login page @@ -475,13 +600,13 @@ if ($mode == 'login') { $texthelp .= $key . '
    '; } print $form->textwithpicto($langs->trans("MessageLogin"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessagelogin'); - print '' . "\n"; // Background - print '
    '; + print $langs->trans("Parameter"); + print ''; + print $langs->trans("Value"); + print '
    ' . $langs->trans("DisableLinkToHelpCenter") . ''; - print ajax_constantonoff("MAIN_HELPCENTER_DISABLELINK", array(), $conf->entity, 0, 0, 0, 0); + print ajax_constantonoff("MAIN_HELPCENTER_DISABLELINK", array(), $conf->entity, 0, 0, 0, 0, 0, 0, '', 'login'); print ' 
    '; + print ''; $doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME) ? $conf->global->MAIN_HOME : ''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%'); $doleditor->Create(); print '
    '; + print '
    '; print '
    '; $disabled = ''; if (!empty($conf->global->ADD_UNSPLASH_LOGIN_BACKGROUND)) { @@ -507,7 +632,6 @@ if ($mode == 'login') { print '
    '; } -print '
    '; print '
    '; print ''; print '
    '; diff --git a/htdocs/admin/index.php b/htdocs/admin/index.php index c02ee501d94..daf20ce5aa2 100644 --- a/htdocs/admin/index.php +++ b/htdocs/admin/index.php @@ -82,8 +82,9 @@ print '

    '; if (empty($conf->global->MAIN_INFO_SOCIETE_NOM) || empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY)) { $setupcompanynotcomplete = 1; } -print img_picto('', 'company', 'class="paddingright valignmiddle double"').' '.$langs->trans("SetupDescriptionLink", DOL_URL_ROOT.'/admin/company.php?mainmenu=home'.(empty($setupcompanynotcomplete) ? '' : '&action=edit'), $langs->transnoentities("Setup"), $langs->transnoentities("MenuCompanySetup")); -print '

    '.$langs->trans("SetupDescription3b"); +print img_picto('', 'company', 'class="paddingright valignmiddle double"').' '.$langs->trans("SetupDescriptionLink", DOL_URL_ROOT.'/admin/company.php?mainmenu=home'.(empty($setupcompanynotcomplete) ? '' : '&action=edit&token='.newToken()), $langs->transnoentities("Setup"), $langs->transnoentities("MenuCompanySetup")); +print '

    '; +print $langs->trans("SetupDescription3b"); if (!empty($setupcompanynotcomplete)) { $langs->load("errors"); $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete"), 'style="padding-right: 6px;"'); @@ -92,6 +93,7 @@ if (!empty($setupcompanynotcomplete)) { print '
    '; print '
    '; print '
    '; +print '
    '; // Show info setup module print img_picto('', 'cog', 'class="paddingright valignmiddle double"').' '.$langs->trans("SetupDescriptionLink", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentities("Setup"), $langs->transnoentities("Modules")); @@ -112,8 +114,8 @@ $reshook = $hookmanager->executeHooks('addHomeSetup', $parameters, $object, $act print $hookmanager->resPrint; if (empty($reshook)) { // Show into other - print ''.$langs->trans("SetupDescription5")."
    "; - print "
    "; + print ''.$langs->trans("SetupDescription5")."
    "; + print '
    '; // Show logo print '
    '; diff --git a/htdocs/admin/knowledgemanagement.php b/htdocs/admin/knowledgemanagement.php index 477f38fa663..8d93c16741a 100644 --- a/htdocs/admin/knowledgemanagement.php +++ b/htdocs/admin/knowledgemanagement.php @@ -17,7 +17,7 @@ */ /** - * \file knowledgemanagement/admin/setup.php + * \file htdocs/admin/knowledgemanagement.php * \ingroup knowledgemanagement * \brief KnowledgeManagement setup page. */ @@ -65,9 +65,7 @@ if (!$user->admin) { * Actions */ -if ((float) DOL_VERSION >= 6) { - include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; -} +include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; if ($action == 'updateMask') { $maskconstorder = GETPOST('maskconstorder', 'alpha'); @@ -324,7 +322,7 @@ if ($action == 'edit') { print '
    '; print ''; } else { //print '
    '.$langs->trans("NothingToSetup"); @@ -533,13 +531,13 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Active if (in_array($name, $def)) { print '
    '."\n"; - print ''; + 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 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print "'.$langs->trans("LDAPDnSynchroActiveExample"); +print ''.$langs->trans("LDAPDnSynchroActiveExample").''; if ($conf->global->LDAP_SYNCHRO_ACTIVE && !$conf->global->LDAP_USER_DN) { - print '
    '.$langs->trans("LDAPSetupNotComplete").''; + print '
    '.$langs->trans("LDAPSetupNotComplete").''; } print '
    '.$langs->trans("LDAPDnContactActiveExample").'
    '.$langs->trans("LDAPDnContactActiveExample").'
    '.$langs->trans("LDAPDnMemberActiveExample").'
    '.$langs->trans("LDAPDnMemberActiveExample").'
    '.$langs->trans("LDAPDnMemberTypeActiveExample").'
    '.$langs->trans("LDAPDnMemberTypeActiveExample").'
    '.$langs->trans("LDAPServerProtocolVersion").'
    '.$langs->trans("LDAPServerProtocolVersion").'
    '; print $langs->trans("LDAPPrimaryServer").''; -print ''; -print ''.$langs->trans("LDAPServerExample").'
    '.$langs->trans("LDAPServerExample").'
    '; print $langs->trans("LDAPSecondaryServer").''; -print ''; -print ''.$langs->trans("LDAPServerExample").'
    '.$langs->trans("LDAPServerExample").'
    '.$langs->trans("LDAPServerPort").''; if (!empty($conf->global->LDAP_SERVER_PORT)) { - print ''; + print ''; } else { - print ''; + print ''; } -print ''.$langs->trans("LDAPServerPortExample").'
    '.$langs->trans("LDAPServerPortExample").'
    '.$langs->trans("LDAPServerDn").''; -print ''; -print ''.$langs->trans("LDAPServerDnExample").'
    '.$langs->trans("LDAPServerDnExample").'
    '.$langs->trans("LDAPServerUseTLS").''; @@ -248,7 +249,7 @@ $arraylist = array(); $arraylist['0'] = $langs->trans("No"); $arraylist['1'] = $langs->trans("Yes"); print $form->selectarray('usetls', $arraylist, $conf->global->LDAP_SERVER_USE_TLS); -print ''.$langs->trans("LDAPServerUseTLSExample").'
    '.$langs->trans("LDAPServerUseTLSExample").'
    '.$langs->trans("ForANonAnonymousAccess").'
    '.$langs->trans("LDAPAdminDn").''; -print ''; -print ''.$langs->trans("LDAPAdminDnExample").'
    '.$langs->trans("LDAPAdminDnExample").'
    '.$langs->trans("LDAPPassword").''; if (!empty($conf->global->LDAP_ADMIN_PASS)) { - print ''; // je le met en visible pour test + print ''; // je le met en visible pour test } else { - print ''; + print ''; } -print ''.$langs->trans('Password').' (ex: secret)
    '.$langs->trans('Password').' (ex: secret)
    '; @@ -289,31 +290,31 @@ if (function_exists("ldap_connect")) { print ''.$langs->trans("LDAPTestConnect").'

    '; } - if ($_GET["action"] == 'test') { + if ($action == 'test') { $ldap = new Ldap(); // Les parametres sont passes et recuperes via $conf $result = $ldap->connect_bind(); if ($result > 0) { // Test ldap connect and bind print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPTCPConnectOK", $conf->global->LDAP_SERVER_HOST, $conf->global->LDAP_SERVER_PORT).''; + print ''.$langs->trans("LDAPTCPConnectOK", $ldap->connectedServer, $conf->global->LDAP_SERVER_PORT).''; print '
    '; - if ($conf->global->LDAP_ADMIN_DN && !empty($conf->global->LDAP_ADMIN_PASS)) { + if (!empty($conf->global->LDAP_ADMIN_DN) && !empty($conf->global->LDAP_ADMIN_PASS)) { if ($result == 2) { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPBindOK", $conf->global->LDAP_SERVER_HOST, $conf->global->LDAP_SERVER_PORT, $conf->global->LDAP_ADMIN_DN, preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)).''; + print ''.$langs->trans("LDAPBindOK", $ldap->connectedServer, $conf->global->LDAP_SERVER_PORT, $conf->global->LDAP_ADMIN_DN, preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)).''; print '
    '; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPBindKO", $conf->global->LDAP_SERVER_HOST, $conf->global->LDAP_SERVER_PORT, $conf->global->LDAP_ADMIN_DN, preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)).''; + print ''.$langs->trans("LDAPBindKO", $ldap->connectedServer, $conf->global->LDAP_SERVER_PORT, $conf->global->LDAP_ADMIN_DN, preg_replace('/./i', '*', $conf->global->LDAP_ADMIN_PASS)).''; print '
    '; print $langs->trans("Error").' '.$ldap->error; print '
    '; } } else { print img_picto('', 'warning').' '; - print ''.$langs->trans("LDAPNoUserOrPasswordProvidedAccessIsReadOnly").''; + print ''.$langs->trans("LDAPNoUserOrPasswordProvidedAccessIsReadOnly").''; print '
    '; } @@ -321,18 +322,18 @@ if (function_exists("ldap_connect")) { // Test ldap_getversion if (($ldap->getVersion() == 3)) { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPSetupForVersion3").''; + print ''.$langs->trans("LDAPSetupForVersion3").''; print '
    '; } else { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPSetupForVersion2").''; + print ''.$langs->trans("LDAPSetupForVersion2").''; print '
    '; } - $unbind = $ldap->unbind(); + $ldap->unbind(); } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPTCPConnectKO", $conf->global->LDAP_SERVER_HOST, $conf->global->LDAP_SERVER_PORT).''; + print ''.$langs->trans("LDAPTCPConnectKO", $ldap->connectedServer, $conf->global->LDAP_SERVER_PORT).''; print '
    '; print $langs->trans("Error").' '.$ldap->error; print '
    '; diff --git a/htdocs/admin/ldap_contacts.php b/htdocs/admin/ldap_contacts.php index d68726c5125..fef3882d2ff 100644 --- a/htdocs/admin/ldap_contacts.php +++ b/htdocs/admin/ldap_contacts.php @@ -145,7 +145,7 @@ print dol_get_fiche_head($head, 'contacts', $langs->trans("LDAPSetup"), -1); print $langs->trans("LDAPDescContact").'
    '; print '
    '; -print ''; +print ''; print ''; print ''; @@ -321,12 +321,12 @@ if (function_exists("ldap_connect")) { if ($result2 > 0) { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPSynchroOK").'
    '; + print ''.$langs->trans("LDAPSynchroOK").'
    '; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } @@ -336,9 +336,9 @@ if (function_exists("ldap_connect")) { print "\n
    "; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKO"); + print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } } diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index 91fba4e3519..82ee85b9a20 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -120,7 +120,7 @@ print $langs->trans("LDAPDescGroups").'
    '; print '
    '; -print ''; +print ''; print ''; print '
    '; @@ -260,12 +260,12 @@ if (function_exists("ldap_connect")) { if ($result2 > 0) { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPSynchroOK").'
    '; + print ''.$langs->trans("LDAPSynchroOK").'
    '; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } @@ -275,9 +275,9 @@ if (function_exists("ldap_connect")) { print "\n
    "; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKO"); + print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } } @@ -331,9 +331,9 @@ if (function_exists("ldap_connect")) { print "\n
    "; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKO"); + print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } } diff --git a/htdocs/admin/ldap_members.php b/htdocs/admin/ldap_members.php index 3fb65f730c6..876c31d79b1 100644 --- a/htdocs/admin/ldap_members.php +++ b/htdocs/admin/ldap_members.php @@ -184,7 +184,7 @@ if (!function_exists("ldap_connect")) { setEventMessages($langs->trans("LDAPFunctionsNotAvailableOnPHP"), null, 'errors'); } -print ''; +print ''; print ''; print dol_get_fiche_head($head, 'members', $langs->trans("LDAPSetup"), -1); @@ -472,12 +472,12 @@ if (function_exists("ldap_connect")) { if ($result2 > 0) { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPSynchroOK").'
    '; + print ''.$langs->trans("LDAPSynchroOK").'
    '; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } @@ -487,9 +487,9 @@ if (function_exists("ldap_connect")) { print "\n
    "; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKO"); + print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } } diff --git a/htdocs/admin/ldap_members_types.php b/htdocs/admin/ldap_members_types.php index 777bc80c6e1..05572dc8bbf 100644 --- a/htdocs/admin/ldap_members_types.php +++ b/htdocs/admin/ldap_members_types.php @@ -112,7 +112,7 @@ print $langs->trans("LDAPDescMembersTypes").'
    '; print '
    '; -print ''; +print ''; print ''; $form = new Form($db); @@ -223,12 +223,12 @@ if (function_exists("ldap_connect")) { if ($result2 > 0) { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPSynchroOK").'
    '; + print ''.$langs->trans("LDAPSynchroOK").'
    '; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } @@ -238,9 +238,9 @@ if (function_exists("ldap_connect")) { print "\n
    "; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKO"); + print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } } diff --git a/htdocs/admin/ldap_users.php b/htdocs/admin/ldap_users.php index ab6c0f52121..33bec1cb2e8 100644 --- a/htdocs/admin/ldap_users.php +++ b/htdocs/admin/ldap_users.php @@ -173,7 +173,7 @@ if (!function_exists("ldap_connect")) { } -print ''; +print ''; print ''; @@ -192,7 +192,7 @@ print "\n"; // DN Pour les utilisateurs print ''; print ''; print ''; print ''; @@ -200,7 +200,7 @@ print ''; // List of object class used to define attributes in structure print ''; print ''; print ''; print ''; @@ -208,7 +208,7 @@ print ''; // Filter, used to filter search print ''; print ''; print ''; print ''; @@ -225,168 +225,168 @@ print "\n"; // Common name print ''; -print '"; +print '"; print ''; // Name print ''; -print '"; +print '"; print ''; // Firstname print ''; -print '"; +print '"; print ''; // Login unix print ''; -print '"; +print '"; print ''; // Login samba print ''; -print '"; +print '"; print ''; // Password not crypted print ''; print ''; print ''; // Password crypted print ''; print ''; print ''; // Mail print ''; -print '"; +print '"; print ''; // Phone print ''; -print '"; +print '"; print ''; // Mobile print ''; -print '"; +print '"; print ''; // Skype print ''; -print '"; +print '"; print ''; // Fax print ''; -print '"; +print '"; print ''; // Company print ''; print ''; print ''; // Address print ''; print ''; print ''; // ZIP print ''; print ''; print ''; // TOWN print ''; print ''; print ''; // COUNTRY print ''; print ''; print ''; // Title print ''; print ''; print ''; // Note print ''; print ''; print ''; // Sid print ''; -print '"; +print '"; print ''; // Group id print ''; print ''; print ''; // Userid print ''; print ''; print ''; // Home Directory print ''; print ''; print ''; // Home Directory Prefix print ''; print ''; print ''; @@ -405,20 +405,20 @@ print ''; /* * Test de la connexion */ -if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { +if (getDolGlobalString('LDAP_SYNCHRO_ACTIVE') == 'dolibarr2ldap') { $butlabel = $langs->trans("LDAPTestSynchroUser"); $testlabel = 'testuser'; - $key = $conf->global->LDAP_KEY_USERS; - $dn = $conf->global->LDAP_USER_DN; - $objectclass = $conf->global->LDAP_USER_OBJECT_CLASS; + $key = getDolGlobalString('LDAP_KEY_USERS'); + $dn = getDolGlobalString('LDAP_USER_DN'); + $objectclass = getDolGlobalString('LDAP_USER_OBJECT_CLASS'); show_ldap_test_button($butlabel, $testlabel, $key, $dn, $objectclass); -} elseif ($conf->global->LDAP_SYNCHRO_ACTIVE == 'ldap2dolibarr') { +} elseif (getDolGlobalString('LDAP_SYNCHRO_ACTIVE') == 'ldap2dolibarr') { $butlabel = $langs->trans("LDAPTestSearch"); $testlabel = 'testsearchuser'; - $key = $conf->global->LDAP_KEY_USERS; - $dn = $conf->global->LDAP_USER_DN; - $objectclass = $conf->global->LDAP_USER_OBJECT_CLASS; + $key = getDolGlobalString('LDAP_KEY_USERS'); + $dn = getDolGlobalString('LDAP_USER_DN'); + $objectclass = getDolGlobalString('LDAP_USER_OBJECT_CLASS'); show_ldap_test_button($butlabel, $testlabel, $key, $dn, $objectclass); } @@ -444,12 +444,12 @@ if (function_exists("ldap_connect")) { if ($result2 > 0) { print img_picto('', 'info').' '; - print ''.$langs->trans("LDAPSynchroOK").'
    '; + print ''.$langs->trans("LDAPSynchroOK").'
    '; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); + print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } @@ -459,9 +459,9 @@ if (function_exists("ldap_connect")) { print "\n
    "; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKO"); + print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } } @@ -479,29 +479,29 @@ if (function_exists("ldap_connect")) { if ($result > 0) { $required_fields = array( - $conf->global->LDAP_KEY_USERS, - $conf->global->LDAP_FIELD_FULLNAME, - $conf->global->LDAP_FIELD_NAME, - $conf->global->LDAP_FIELD_FIRSTNAME, - $conf->global->LDAP_FIELD_LOGIN, - $conf->global->LDAP_FIELD_LOGIN_SAMBA, - $conf->global->LDAP_FIELD_PASSWORD, - $conf->global->LDAP_FIELD_PASSWORD_CRYPTED, - $conf->global->LDAP_FIELD_PHONE, - $conf->global->LDAP_FIELD_FAX, - $conf->global->LDAP_FIELD_SKYPE, - $conf->global->LDAP_FIELD_MOBILE, - $conf->global->LDAP_FIELD_MAIL, - $conf->global->LDAP_FIELD_TITLE, - $conf->global->LDAP_FIELD_DESCRIPTION, - $conf->global->LDAP_FIELD_SID + getDolGlobalString('LDAP_KEY_USERS'), + getDolGlobalString('LDAP_FIELD_FULLNAME'), + getDolGlobalString('LDAP_FIELD_NAME'), + getDolGlobalString('LDAP_FIELD_FIRSTNAME'), + getDolGlobalString('LDAP_FIELD_LOGIN'), + getDolGlobalString('LDAP_FIELD_LOGIN_SAMBA'), + getDolGlobalString('LDAP_FIELD_PASSWORD'), + getDolGlobalString('LDAP_FIELD_PASSWORD_CRYPTED'), + getDolGlobalString('LDAP_FIELD_PHONE'), + getDolGlobalString('LDAP_FIELD_FAX'), + getDolGlobalString('LDAP_FIELD_SKYPE'), + getDolGlobalString('LDAP_FIELD_MOBILE'), + getDolGlobalString('LDAP_FIELD_MAIL'), + getDolGlobalString('LDAP_FIELD_TITLE'), + getDolGlobalString('LDAP_FIELD_DESCRIPTION'), + getDolGlobalString('LDAP_FIELD_SID') ); // Remove from required_fields all entries not configured in LDAP (empty) and duplicated $required_fields = array_unique(array_values(array_filter($required_fields, "dol_validElement"))); // Get from LDAP database an array of results - $ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, $required_fields, 1); + $ldapusers = $ldap->getRecords('*', getDolGlobalString('LDAP_USER_DN'), getDolGlobalString('LDAP_KEY_USERS'), $required_fields, 1); //$ldapusers = $ldap->getRecords('*', $conf->global->LDAP_USER_DN, $conf->global->LDAP_KEY_USERS, '', 1); if (is_array($ldapusers)) { @@ -523,16 +523,16 @@ if (function_exists("ldap_connect")) { print "
    \n"; print "LDAP search for user:
    \n"; print "search: *
    \n"; - print "userDN: ".$conf->global->LDAP_USER_DN."
    \n"; - print "useridentifier: ".$conf->global->LDAP_KEY_USERS."
    \n"; + print "userDN: ".getDolGlobalString('LDAP_USER_DN')."
    \n"; + print "useridentifier: ".getDolGlobalString('LDAP_KEY_USERS')."
    \n"; print "required_fields: ".implode(',', $required_fields)."
    \n"; print "=> ".count($liste)." records
    \n"; print "\n
    "; } else { print img_picto('', 'error').' '; - print ''.$langs->trans("LDAPSynchroKO"); + print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; - print '
    '; + print '
    '; print $langs->trans("ErrorLDAPMakeManualTest", $conf->ldap->dir_temp).'
    '; } } diff --git a/htdocs/admin/limits.php b/htdocs/admin/limits.php index ef0c996569f..74c46112241 100644 --- a/htdocs/admin/limits.php +++ b/htdocs/admin/limits.php @@ -190,7 +190,7 @@ if ($action == 'edit') { print ''; print ''; } @@ -237,7 +237,7 @@ if (empty($mysoc->country_code)) { $sql = "SELECT taux as vat_rate, t.code as vat_code, t.localtax1 as localtax_rate1, t.localtax2 as localtax_rate2"; $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c"; - $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='".$db->escape($mysoc->country_code)."' AND (t.taux <> 0 OR t.localtax1 <>0 OR t.localtax2 <>0)"; + $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='".$db->escape($mysoc->country_code)."' AND (t.taux <> 0 OR t.localtax1 <> '0' OR t.localtax2 <> '0')"; $sql .= " ORDER BY t.taux ASC"; $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/admin/loan.php b/htdocs/admin/loan.php index 0769ee5c0a0..59b7eb8b463 100644 --- a/htdocs/admin/loan.php +++ b/htdocs/admin/loan.php @@ -105,7 +105,7 @@ foreach ($list as $key) { // Value print ''; diff --git a/htdocs/categories/card.php b/htdocs/categories/card.php index 44b812b4d96..ec3d75dee1a 100644 --- a/htdocs/categories/card.php +++ b/htdocs/categories/card.php @@ -266,7 +266,7 @@ if ($user->rights->categorie->creer) { $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, 'edit', $parameters); + print $object->showOptionals($extrafields, 'create', $parameters); } print '
    '.$langs->trans("LDAPUserDn").''; -print ''; +print ''; print ''.$langs->trans("LDAPUserDnExample").' 
    '.$langs->trans("LDAPUserObjectClassList").''; -print ''; +print ''; print ''.$langs->trans("LDAPUserObjectClassListExample").' 
    '.$langs->trans("LDAPFilterConnection").''; -print ''; +print ''; print ''.$langs->trans("LDAPFilterConnectionExample").'
    '.$langs->trans("LDAPFieldFullname").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldFullnameExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_FULLNAME) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldName").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldNameExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_NAME) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldFirstName").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldFirstNameExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_FIRSTNAME) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldLoginUnix").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldLoginExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_LOGIN) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldLoginSamba").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldLoginSambaExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_LOGIN_SAMBA) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldPasswordNotCrypted").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldPasswordExample").' 
    '.$langs->trans("LDAPFieldPasswordCrypted").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldPasswordExample").' 
    '.$langs->trans("LDAPFieldMail").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldMailExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_MAIL) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldPhone").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldPhoneExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_PHONE) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldMobile").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldMobileExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_MOBILE) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldSkype").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldSkypeExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_SKYPE) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldFax").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldFaxExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_FAX) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldCompany").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldCompanyExample").' 
    '.$langs->trans("LDAPFieldAddress").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldAddressExample").' 
    '.$langs->trans("LDAPFieldZip").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldZipExample").' 
    '.$langs->trans("LDAPFieldTown").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldTownExample").' 
    '.$langs->trans("LDAPFieldCountry").''; -print ''; +print ''; print '  
    '.$langs->trans("LDAPFieldTitle").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldTitleExample").' 
    '.$langs->trans("Note").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldDescriptionExample").' 
    '.$langs->trans("LDAPFieldSid").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldSidExample").'global->LDAP_KEY_USERS && $conf->global->LDAP_KEY_USERS == $conf->global->LDAP_FIELD_SID) ? ' checked' : '').">
    '.$langs->trans("LDAPFieldGroupid").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldGroupidExample").' 
    '.$langs->trans("LDAPFieldUserid").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldUseridExample").' 
    '.$langs->trans("LDAPFieldHomedirectory").''; -print ''; +print ''; print ''.$langs->trans("LDAPFieldHomedirectoryExample").' 
    '.$langs->trans("LDAPFieldHomedirectoryprefix").''; -print ''; +print ''; print ' 
    '; if (!empty($conf->accounting->enabled)) { - print $formaccounting->select_account($conf->global->$key, $key, 1, '', 1, 1); + print $formaccounting->select_account(getDolGlobalString($key), $key, 1, '', 1, 1); } else { print ''; } diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index de160a1c946..d60b4e4ddc6 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -292,7 +292,7 @@ if ($action == 'edit') { print dol_get_fiche_head($head, 'common', '', -1); print ''.$langs->trans("EMailsDesc")."
    \n"; - print "
    \n"; + print "

    \n"; clearstatcache(); @@ -543,7 +543,7 @@ if ($action == 'edit') { print dol_get_fiche_head($head, 'common', '', -1); print ''.$langs->trans("EMailsDesc")."
    \n"; - print "
    \n"; + print "

    \n"; print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table print ''; @@ -784,7 +784,7 @@ if ($action == 'edit') { // Actions button print '
    '; - print ''.$langs->trans("Modify").''; + print ''.$langs->trans("Modify").''; if (empty($conf->global->MAIN_DISABLE_ALL_MAILS)) { if ($conf->global->MAIN_MAIL_SENDMODE != 'mail' || !$linuxlike) { @@ -829,27 +829,41 @@ if ($action == 'edit') { if ($conf->global->MAIN_MAIL_SENDMODE == 'mail') { if (!empty($conf->global->MAIN_EXTERNAL_MAIL_SPF_STRING_TO_ADD)) { // List of string to add in SPF if the setup use the mail method. Example 'include:sendgrid.net include:spf.mydomain.com' - $text .= ($text ? '

    ' : '').$langs->trans("WarningPHPMailSPF", $conf->global->MAIN_EXTERNAL_MAIL_SPF_STRING_TO_ADD); + $text .= ($text ? '

    ' : '').''.$langs->trans("WarningPHPMailSPF", $conf->global->MAIN_EXTERNAL_MAIL_SPF_STRING_TO_ADD); } else { // MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS is list of IPs where email is sent from. Example: '1.2.3.4, [aaaa:bbbb:cccc:dddd]'. if (!empty($conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS)) { // List of IP show as record to add in SPF if we use the mail method - $text .= ($text ? '

    ' : '').$langs->trans("WarningPHPMailSPF", $conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS); + $text .= ($text ? '

    ' : '').''.$langs->trans("WarningPHPMailSPF", $conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS); } } } else { if (!empty($conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS)) { // List of IP show as record to add as allowed IP if we use the smtp method. Value is '1.2.3.4, [aaaa:bbbb:cccc:dddd]' // TODO Add a key to allow to show the IP/name of server detected dynamically - $text .= ($text ? '

    ' : '').$langs->trans("WarningPHPMail2", $conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS); + $text .= ($text ? '

    ' : '').''.$langs->trans("WarningPHPMail2", $conf->global->MAIN_EXTERNAL_SMTP_CLIENT_IP_ADDRESS); } if (!empty($conf->global->MAIN_EXTERNAL_SMTP_SPF_STRING_TO_ADD)) { // Should be required only if you have preset the Dolibarr to use your own SMTP and you want to warn users to update their domain name to match your SMTP server. // List of string to add in SPF if we use the smtp method. Example 'include:spf.mydomain.com' - $text .= ($text ? '

    ' : '').$langs->trans("WarningPHPMailSPF", $conf->global->MAIN_EXTERNAL_SMTP_SPF_STRING_TO_ADD); + $text .= ($text ? '

    ' : '').''.$langs->trans("WarningPHPMailSPF", $conf->global->MAIN_EXTERNAL_SMTP_SPF_STRING_TO_ADD); + } + } + $companyemail = getDolGlobalString('MAIN_INFO_SOCIETE_MAIL'); + $dnsinfo = false; + if (!empty($companyemail) && function_exists('dns_get_record')) { + $arrayofemailparts = explode('@', $companyemail); + if (count($arrayofemailparts) == 2) { + $domain = $arrayofemailparts[1]; + $dnsinfo = dns_get_record($domain, DNS_TXT); + } + } + if (!empty($dnsinfo) && is_array($dnsinfo)) { + foreach ($dnsinfo as $info) { + if (strpos($info['txt'], 'v=spf') !== false) { + $text .= ($text ? '

    ' : '').$langs->trans("ActualMailSPFRecordFound", $info['txt']); + } } } - - if ($text) { print info_admin($text); } diff --git a/htdocs/admin/mails_emailing.php b/htdocs/admin/mails_emailing.php index 436ffa3d003..015b943ac04 100644 --- a/htdocs/admin/mails_emailing.php +++ b/htdocs/admin/mails_emailing.php @@ -243,7 +243,7 @@ if ($action == 'edit') { print dol_get_fiche_head($head, 'common_emailing', '', -1); print ''.$langs->trans("EMailsDesc")."
    \n"; - print "
    \n"; + print "

    \n"; clearstatcache(); @@ -412,7 +412,7 @@ if ($action == 'edit') { print dol_get_fiche_head($head, 'common_emailing', '', -1); print ''.$langs->trans("EMailsDesc")."
    \n"; - print "
    \n"; + print "

    \n"; print '
    '; print ''; @@ -515,7 +515,7 @@ if ($action == 'edit') { print '
    '; - print ''.$langs->trans("Modify").''; + print ''.$langs->trans("Modify").''; if (!empty($conf->global->MAIN_MAIL_SENDMODE_EMAILING) && $conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'default') { if ($conf->global->MAIN_MAIL_SENDMODE_EMAILING != 'mail' || !$linuxlike) { diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index baa8c3688d8..d3441cf2e21 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -597,7 +597,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { if (!$i) { $totalarray['nbfield']++; } - if (!empty($val['isameasure'])) { + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; } @@ -632,7 +632,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { if ($sortorder) { $url .= '&page='.urlencode($sortorder); } - print ''.img_edit().''; + print ''.img_edit().''; //print '   '; print ''.img_delete().'   '; if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 25a33717c46..b896c8962b4 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -160,6 +160,7 @@ if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $tabhelp = array(); $tabhelp[25] = array( + 'label'=>$langs->trans('EnterAnyCode'), 'topic'=>''.$helpsubstit.'', 'joinfiles'=>$langs->trans('AttachMainDocByDefault'), 'content'=>''.$helpsubstit.'', @@ -228,7 +229,7 @@ if (!empty($conf->agenda->enabled)) { $elementList['actioncomm_send'] = img_picto('', 'action', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToSendEventPush')); } if (!empty($conf->eventorganization->enabled) && !empty($user->rights->eventorganization->read)) { - $elementList['eventorganization_send'] = img_picto('', 'action', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToSendEventOrganization')); + $elementList['conferenceorbooth'] = img_picto('', 'action', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToSendEventOrganization')); } if (!empty($conf->partnership->enabled) && !empty($user->rights->partnership->read)) { $elementList['partnership_send'] = img_picto('', 'partnership', 'class="paddingright"').dol_escape_htmltag($langs->trans('MailToPartnership')); @@ -683,8 +684,8 @@ if ($action == 'view') { $tmpaction = 'create'; $parameters = array( - 'fieldlist' => $fieldlist, - 'tabname' => $tabname[$id] + 'fieldlist' => $fieldlist, + 'tabname' => $tabname[$id] ); $reshook = $hookmanager->executeHooks('createEmailTemplateFieldlist', $parameters, $obj, $tmpaction); // Note that $action and $object may have been modified by some hooks $error = $hookmanager->error; @@ -822,7 +823,7 @@ if ($resql) { print ''; } elseif ($value == 'fk_user') { print '
    '; } elseif ($value == 'topic') { print ''; @@ -893,7 +894,7 @@ if ($resql) { $valuetoshow = $langs->trans("Content"); $showfield = 0; } if ($fieldlist[$field] == 'content_lines') { - $valuetoshow = $langs->trans("ContentLines"); $showfield = 0; + $valuetoshow = $langs->trans("ContentForLines"); $showfield = 0; } // Show fields @@ -935,7 +936,7 @@ if ($resql) { print ''; @@ -972,6 +973,14 @@ if ($resql) { $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (!empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 500, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%'); print $doleditor->Create(1); } + if ($tmpfieldlist == 'content_lines') { + print $form->textwithpicto($langs->trans("ContentForLines"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'
    '; + $okforextended = true; + if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) + $okforextended = false; + $doleditor = new DolEditor($tmpfieldlist.'-'.$rowid, (! empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 140, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%'); + print $doleditor->Create(1); + } print ''; print ''; print ''; @@ -1071,8 +1080,8 @@ if ($resql) { if ($showfield) { print ''; print ''; - - /* - $fieldsforcontent = array('content'); - if (! empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) - { - $fieldsforcontent = array('content', 'content_lines'); - } - foreach ($fieldsforcontent as $tmpfieldlist) - { - $showfield = 1; - $align = "left"; - $valuetoshow = $obj->{$tmpfieldlist}; - - $class = 'tddict'; - // Show value for field - if ($showfield) { - - print ''; - print ''; - - } - }*/ - print "\n"; } @@ -1187,7 +1167,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') if ($value == 'fk_user') { print ''; } else { print ''; @@ -320,7 +320,7 @@ foreach ($dirmodels as $reldir) else { print '"; } @@ -332,7 +332,7 @@ foreach ($dirmodels as $reldir) } else { - print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; } print ''; @@ -443,7 +443,7 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION)) } - print ''; + print ''; print ''; print '
    '.$langs->trans("Parameter").''.$langs->trans("Value").'
    '; - print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), null, 0, 0, 1, '', 0, '', 'maxwidth150'); + print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), null, 0, 0, 0, '', 0, '', 'maxwidth150'); print ''; print ''; print ''; - print ''; + print ''; print '
    '; print ''; print '
    '; print $valuetoshow; @@ -1113,35 +1122,6 @@ if ($resql) { //else print ''.img_delete().''; // Some dictionary can be edited by other profile than admin } print '
    '; // To create an artificial CR for the current tr we are on - $okforextended = true; - if (empty($conf->global->FCKEDITOR_ENABLE_MAIL)) - $okforextended = false; - $doleditor = new DolEditor($tmpfieldlist.'-'.$i, (! empty($obj->{$tmpfieldlist}) ? $obj->{$tmpfieldlist} : ''), '', 140, 'dolibarr_mailings', 'In', 0, false, $okforextended, ROWS_6, '90%', 1); - print $doleditor->Create(1); - print '
    '; if ($user->admin) { - print $form->select_dolusers(empty($obj->{$value}) ? '' : $obj->{$value}, 'fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), null, 0, 0, 1, '', 0, '', 'maxwidth200'); + print $form->select_dolusers(empty($obj->{$value}) ? '' : $obj->{$value}, 'fk_user', 1, null, 0, ($user->admin ? '' : 'hierarchyme'), null, 0, 0, 0, '', 0, '', 'minwidth150 maxwidth300'); } else { if ($context == 'add') { // I am not admin and we show the add form print $user->getNomUrl(1); // Me diff --git a/htdocs/admin/mails_ticket.php b/htdocs/admin/mails_ticket.php index 667f58807dc..a94bb9c4276 100644 --- a/htdocs/admin/mails_ticket.php +++ b/htdocs/admin/mails_ticket.php @@ -232,7 +232,7 @@ if ($action == 'edit') { print dol_get_fiche_head($head, 'common_ticket', '', -1); print ''.$langs->trans("EMailsDesc")."
    \n"; - print "
    \n"; + print "

    \n"; clearstatcache(); @@ -387,7 +387,7 @@ if ($action == 'edit') { print dol_get_fiche_head($head, 'common_ticket', '', -1); print ''.$langs->trans("EMailsDesc")."
    \n"; - print "
    \n"; + print "

    \n"; print ''; print ''; @@ -479,7 +479,7 @@ if ($action == 'edit') { print '
    '; - print ''.$langs->trans("Modify").''; + print ''.$langs->trans("Modify").''; if (!empty($conf->global->MAIN_MAIL_SENDMODE_TICKET) && $conf->global->MAIN_MAIL_SENDMODE_TICKET != 'default') { if ($conf->global->MAIN_MAIL_SENDMODE_TICKET != 'mail' || !$linuxlike) { diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index aaadde965a2..65906b83f3c 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -281,7 +281,7 @@ if ($action == 'create') { print load_fiche_titre($langs->trans("NewMenu"), '', 'title_setup'); - print '
    '; + print ''; print ''; print dol_get_fiche_head(); diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index 658be446765..2cbb14bb2dd 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -133,7 +133,7 @@ if ($action == 'install') { // $original_file should match format module_modulename-x.y[.z].zip $original_file = basename($_FILES["fileinstall"]["name"]); - $original_file = preg_replace('/\(\d+\)\.zip$/i', '.zip', $original_file); + $original_file = preg_replace('/\s*\(\d+\)\.zip$/i', '.zip', $original_file); $newfile = $conf->admin->dir_temp.'/'.$original_file.'/'.$original_file; if (!$original_file) { @@ -542,7 +542,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { $moreforfilter .= '
    '; $moreforfilter .= $form->selectarray('search_nature', $arrayofnatures, dol_escape_htmltag($search_nature), $langs->trans('Origin'), 0, 0, '', 0, 0, 0, '', 'maxwidth200', 1); $moreforfilter .= '
    '; - if (!empty($conf->global->MAIN_FEATURES_LEVEL)) { + if (getDolGlobalInt('MAIN_FEATURES_LEVEL')) { $array_version = array('stable'=>$langs->transnoentitiesnoconv("Stable")); if ($conf->global->MAIN_FEATURES_LEVEL < 0) { $array_version['deprecated'] = $langs->trans("Deprecated"); @@ -878,7 +878,7 @@ if ($mode == 'common' || $mode == 'commonkanban') { } } $codeenabledisable .= ''."\n"; - $codeenabledisable .= '
    '; - print ''; + print ''; ?>
    -
    +
    @@ -1051,7 +1051,7 @@ if ($mode == 'marketplace') {
      - get_categories(); ?> + get_categories()); ?>
    diff --git a/htdocs/admin/mrp.php b/htdocs/admin/mrp.php index 7cd3c095955..54efdc4df19 100644 --- a/htdocs/admin/mrp.php +++ b/htdocs/admin/mrp.php @@ -235,7 +235,7 @@ foreach ($dirmodels as $reldir) { if ($conf->global->MRP_MO_ADDON == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { - print ''; + print ''; print img_picto($langs->trans("Disabled"), 'switch_off'); print ''; } @@ -359,13 +359,13 @@ foreach ($dirmodels as $reldir) { // Active if (in_array($name, $def)) { print '
    '; } else { print '"; } @@ -374,7 +374,7 @@ foreach ($dirmodels as $reldir) { if ($conf->global->MRP_MO_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).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print ''; diff --git a/htdocs/admin/multicurrency.php b/htdocs/admin/multicurrency.php index 95b418a75f0..e8619219471 100644 --- a/htdocs/admin/multicurrency.php +++ b/htdocs/admin/multicurrency.php @@ -138,7 +138,7 @@ if ($action == 'add_currency') { $TCurrency = array(); -$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'multicurrency WHERE entity = '.$conf->entity; +$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."multicurrency WHERE entity = ".((int) $conf->entity); $resql = $db->query($sql); if ($resql) { while ($obj = $db->fetch_object($resql)) { diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index 8137c34e1e6..1b06e9dd25e 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -97,6 +97,10 @@ if ($action == 'setvalue' && $user->admin) { $error++; } + $result = dolibarr_set_const($db, "NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE", GETPOST("notif_disable", "alphawithlgt"), 'chaine', 0, '', $conf->entity); + if ($result < 0) { + $error++; + } if (!$error) { $db->commit(); @@ -199,6 +203,29 @@ if (!empty($conf->global->NOTIFICATION_EMAIL_FROM) && !isValidEmail($conf->globa } print ''; print ''; + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; print '
    '.$langs->trans("Parameter").''.$langs->trans("Value").'
    '."\n"; - print ''; + 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 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print "
    '; +print $langs->trans("NotificationDisableConfirmMessageUser").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_USER'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_USER", $arrval, $conf->global->NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_USER); +} +print '
    '; +print $langs->trans("NotificationDisableConfirmMessageFix").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_FIX'); +} else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_FIX", $arrval, $conf->global->NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_FIX); +} +print '
    '; print $form->buttonsSaveCancel("Save", ''); diff --git a/htdocs/admin/openinghours.php b/htdocs/admin/openinghours.php index e6bc6ee8f1d..fb7dddc092c 100644 --- a/htdocs/admin/openinghours.php +++ b/htdocs/admin/openinghours.php @@ -81,7 +81,7 @@ $head = company_admin_prepare_head(); print dol_get_fiche_head($head, 'openinghours', $langs->trans("Company"), -1, 'company'); print ''.$langs->trans("OpeningHoursDesc")."
    \n"; -print "
    \n"; +print "

    \n"; if (empty($action) || $action == 'edit' || $action == 'updateedit') { /** @@ -92,7 +92,7 @@ if (empty($action) || $action == 'edit' || $action == 'updateedit') { print ''; print ''; - print ''."\n"; + print ''."\n"; print ''; -/* -print ''; -*/ - -print '
    '.$langs->trans("Day").''.$langs->trans("Value").'
    '.$langs->trans("Day").''.$langs->trans("Value").'
    '; print $form->textwithpicto($langs->trans("Monday"), $langs->trans("OpeningHoursFormatDesc")); diff --git a/htdocs/admin/paymentbybanktransfer.php b/htdocs/admin/paymentbybanktransfer.php index 4d170aa5fbd..997c71bb335 100644 --- a/htdocs/admin/paymentbybanktransfer.php +++ b/htdocs/admin/paymentbybanktransfer.php @@ -20,7 +20,7 @@ */ /** - * \file htdocs/admin/credtitransfer.php + * \file htdocs/admin/paymentbybanktransfer.php * \ingroup paymentbybanktransfer * \brief Page to setup payments by credit transfer */ @@ -144,7 +144,7 @@ $linkback = ''; -print ''; +print ''; print ''; print ''; @@ -298,7 +298,7 @@ foreach ($dirmodels as $reldir) if (in_array($name, $def)) { print ''; @@ -306,7 +306,7 @@ foreach ($dirmodels as $reldir) else { print '"; } @@ -318,7 +318,7 @@ foreach ($dirmodels as $reldir) } else { - print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; } print ''; @@ -429,7 +429,7 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION)) } - print ''; + print ''; print ''; print '
    '."\n"; - print ''; + 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 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; print "
    '; print ''; diff --git a/htdocs/admin/pdf.php b/htdocs/admin/pdf.php index 80f057af26c..b32867bd90d 100644 --- a/htdocs/admin/pdf.php +++ b/htdocs/admin/pdf.php @@ -165,9 +165,13 @@ if ($action == 'update') { if (GETPOSTISSET('PDF_SHOW_LINK_TO_ONLINE_PAYMENT')) { 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); } setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); @@ -312,7 +316,7 @@ for ($i = 1; $i <= 6; $i++) { $pid = false; } } else { - $pid = img_warning().' '.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).''; + $pid = img_warning().' '.$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CompanyCountry")).''; } if ($pid) { print ''; +print ''; + print '
    '.$langs->trans("ShowProfIdInAddress").' - '.$pid.''; @@ -548,6 +552,14 @@ if ($conf->use_javascript_ajax) { } print '
    '.$langs->trans("PDF_USE_A").''; +if ($conf->use_javascript_ajax) { + print ajax_constantonoff('PDF_USE_A'); +} else { + print $form->selectyesno('PDF_USE_A', (empty($conf->global->PDF_USE_A) ? 0 : $conf->global->PDF_USE_A), 1); +} +print '
    '; print ''; diff --git a/htdocs/admin/pdf_other.php b/htdocs/admin/pdf_other.php index 3883e885619..f42c49a4bfe 100644 --- a/htdocs/admin/pdf_other.php +++ b/htdocs/admin/pdf_other.php @@ -41,17 +41,12 @@ if (!$user->admin) { } $action = GETPOST('action', 'aZ09'); -$cancel = GETPOST('cancel', 'alpha'); /* * Actions */ -if ($cancel) { - $action = ''; -} - if ($action == 'update') { if (GETPOSTISSET('PROPOSAL_PDF_HIDE_PAYMENTTERM')) { dolibarr_set_const($db, "PROPOSAL_PDF_HIDE_PAYMENTTERM", GETPOST("PROPOSAL_PDF_HIDE_PAYMENTTERM"), 'chaine', 0, '', $conf->entity); @@ -62,6 +57,9 @@ if ($action == 'update') { if (GETPOSTISSET('MAIN_GENERATE_PROPOSALS_WITH_PICTURE')) { dolibarr_set_const($db, "MAIN_GENERATE_PROPOSALS_WITH_PICTURE", GETPOST("MAIN_GENERATE_PROPOSALS_WITH_PICTURE"), 'chaine', 0, '', $conf->entity); } + 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); + } setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); @@ -92,45 +90,47 @@ $tooltiptext = ''; print ''.$form->textwithpicto($langs->trans("PDFOtherDesc"), $tooltiptext)."
    \n"; print "
    \n"; -print load_fiche_titre($langs->trans("Proposal"), '', ''); +if (!empty($conf->propal->enabled)) { + print load_fiche_titre($langs->trans("Proposal"), '', ''); -print ''; -print ''; -print ''; + print ''; + print ''; + print ''; -print '
    '; -print ''; -print ''; + print '
    '; + print '
    '.$langs->trans("Parameter").''.$langs->trans("Value").'
    '; + print ''; -print ''; + + /* + print ''; + */ + + print '
    '.$langs->trans("Parameter").''.$langs->trans("Value").'
    '.$langs->trans("MAIN_GENERATE_PROPOSALS_WITH_PICTURE"); -print ' ('.$langs->trans("RandomlySelectedIfSeveral").')'; -print ''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('MAIN_GENERATE_PROPOSALS_WITH_PICTURE'); -} else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("MAIN_GENERATE_PROPOSALS_WITH_PICTURE", $arrval, $conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE); + print '
    '.$langs->trans("MAIN_GENERATE_PROPOSALS_WITH_PICTURE"); + print ' ('.$langs->trans("RandomlySelectedIfSeveral").')'; + print ''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('MAIN_GENERATE_PROPOSALS_WITH_PICTURE'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("MAIN_GENERATE_PROPOSALS_WITH_PICTURE", $arrval, $conf->global->MAIN_GENERATE_PROPOSALS_WITH_PICTURE); + } + print '
    '.$langs->trans("MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING").''; + if ($conf->use_javascript_ajax) { + print ajax_constantonoff('MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING'); + } else { + $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); + print $form->selectarray("MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING", $arrval, $conf->global->MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING); + } + print '
    '; + print '
    '; } -print '
    '.$langs->trans("MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING").''; -if ($conf->use_javascript_ajax) { - print ajax_constantonoff('MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING'); -} else { - $arrval = array('0' => $langs->trans("No"), '1' => $langs->trans("Yes")); - print $form->selectarray("MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING", $arrval, $conf->global->MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING); -} -print '
    '; +print '
    '; +print ''; print '
    '; -/* - print $form->buttonsSaveCancel(); -*/ - print ''; diff --git a/htdocs/admin/perms.php b/htdocs/admin/perms.php index 8f4c0c6f763..d2f0d79e4f3 100644 --- a/htdocs/admin/perms.php +++ b/htdocs/admin/perms.php @@ -236,7 +236,7 @@ if ($result) { print '
    '; - print ''; + print ''; //print img_edit_add(); print img_picto('', 'switch_off'); print ''; diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index f9c183b5c7d..88a02e90457 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -102,11 +102,11 @@ if ($action == "set") { } $res = dolibarr_set_const($db, "PRELEVEMENT_ADDDAYS", GETPOST("PRELEVEMENT_ADDDAYS"), 'chaine', 0, '', $conf->entity); - if (! ($res > 0)) { + if (!($res > 0)) { $error++; } - if (! $error) { + if (!$error) { $db->commit(); setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); } else { @@ -297,7 +297,7 @@ foreach ($dirmodels as $reldir) $module = new $classname($db); $modulequalified=1; - if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + 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) { @@ -312,7 +312,7 @@ foreach ($dirmodels as $reldir) if (in_array($name, $def)) { print ''."\n"; - print ''; + 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 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; print "
    '; print ''; diff --git a/htdocs/admin/propal.php b/htdocs/admin/propal.php index dcd91df0dbc..22ce045a7ab 100644 --- a/htdocs/admin/propal.php +++ b/htdocs/admin/propal.php @@ -278,7 +278,7 @@ foreach ($dirmodels as $reldir) { if ($conf->global->PROPALE_ADDON == "$file") { print img_picto($langs->trans("Activated"), 'switch_on'); } else { - print ''; + print ''; print img_picto($langs->trans("Disabled"), 'switch_off'); print ''; } @@ -402,13 +402,13 @@ foreach ($dirmodels as $reldir) { // Active if (in_array($name, $def)) { print ''; } else { print ""; } @@ -417,7 +417,7 @@ foreach ($dirmodels as $reldir) { if ($conf->global->PROPALE_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.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print ''; @@ -658,11 +658,11 @@ if ($conf->banque->enabled) { if (empty($conf->global->BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL)) { - print ''.img_picto($langs->trans("Disabled"),'switch_off').''; + print ''.img_picto($langs->trans("Disabled"),'switch_off').''; } else { - print ''.img_picto($langs->trans("Enabled"),'switch_on').''; + print ''.img_picto($langs->trans("Enabled"),'switch_on').''; } } print ''; diff --git a/htdocs/admin/proxy.php b/htdocs/admin/proxy.php index 635fb2e1e7b..451771f7a98 100644 --- a/htdocs/admin/proxy.php +++ b/htdocs/admin/proxy.php @@ -95,6 +95,7 @@ $head = security_prepare_head(); print dol_get_fiche_head($head, 'proxy', '', -1); +print '
    '; if ($conf->use_javascript_ajax) { print "\n".' + + id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Modify if ($object->status == $object::STATUS_DRAFT) { if ($permissiontoadd) { - print ''.$langs->trans("Modify").''."\n"; + print ''.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } @@ -616,24 +666,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Re-open if ($permissiontoadd && $object->status == $object::STATUS_CANCELED) { - print ''.$langs->trans("ReOpen").''."\n"; + print ''.$langs->trans("ReOpen").''."\n"; } // Create MO if ($conf->mrp->enabled) { if ($object->status == $object::STATUS_VALIDATED && !empty($user->rights->mrp->write)) { - print ''.$langs->trans("CreateMO").''."\n"; + print ''.$langs->trans("CreateMO").''."\n"; } } // Clone if ($permissiontoadd) { - print ''.$langs->trans("ToClone").''."\n"; + print ''.$langs->trans("ToClone").''."\n"; } // Close / Cancel if ($permissiontoadd && $object->status == $object::STATUS_VALIDATED) { - print ''.$langs->trans("Disable").''."\n"; + print ''.$langs->trans("Disable").''."\n"; } /* @@ -651,7 +701,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea */ if ($permissiontodelete) { - print ''.$langs->trans('Delete').''."\n"; + print ''.$langs->trans('Delete').''."\n"; } else { print ''.$langs->trans('Delete').''."\n"; } @@ -683,20 +733,20 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; + print '
    '; $MAXEVENT = 10; - $morehtmlright = ''; + $morehtmlright = ''; $morehtmlright .= $langs->trans("SeeAll"); $morehtmlright .= ''; // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'bom', $socid, 1, '', $MAXEVENT, '', $morehtmlright); + $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlright); - print '
    '; + print ''; } //Select mail models is same action as presend diff --git a/htdocs/bom/bom_document.php b/htdocs/bom/bom_document.php index dd0227e4305..c36ac32bb59 100644 --- a/htdocs/bom/bom_document.php +++ b/htdocs/bom/bom_document.php @@ -125,7 +125,7 @@ if ($object->id) { // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php index 4a94dc7ce86..3cc0dc1753a 100644 --- a/htdocs/bom/bom_list.php +++ b/htdocs/bom/bom_list.php @@ -655,7 +655,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { if (!$i) { $totalarray['nbfield']++; } - if (!empty($val['isameasure'])) { + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; } diff --git a/htdocs/bom/bom_note.php b/htdocs/bom/bom_note.php index f456e7ddf98..8ace40cc900 100644 --- a/htdocs/bom/bom_note.php +++ b/htdocs/bom/bom_note.php @@ -100,7 +100,7 @@ if ($id > 0 || !empty($ref)) { // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
    '; diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index e6ae5c78ae5..fd8d4a19a75 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -98,7 +98,7 @@ class BOM extends CommonObject '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'), - 'bomtype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>33, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble'), 'css'=>'minwidth150', 'csslist'=>'minwidth150 center'), + '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'), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,), @@ -381,7 +381,7 @@ class BOM extends CommonObject if ($result > 0 && !empty($this->table_element_line)) { $this->fetchLines(); } - $this->calculateCosts(); + //$this->calculateCosts(); // This consume a high number of subrequests. Do not call it into fetch but when you need it. return $result; } @@ -946,7 +946,7 @@ class BOM extends CommonObject $this->lines = array(); $objectline = new BOMLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_bom = '.$this->id)); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_bom = '.((int) $this->id))); if (is_numeric($result)) { $this->error = $this->error; @@ -1035,7 +1035,8 @@ class BOM extends CommonObject } /** - * BOM costs calculation based on cost_price or pmp of each BOM line + * BOM costs calculation based on cost_price or pmp of each BOM line. + * Set the property ->total_cost and ->unit_cost of BOM. * * @return void */ @@ -1045,30 +1046,36 @@ class BOM extends CommonObject $this->unit_cost = 0; $this->total_cost = 0; - require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $productFournisseur = new ProductFournisseur($this->db); - - foreach ($this->lines as &$line) { + if (is_array($this->lines) && count($this->lines)) { + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; + $productFournisseur = new ProductFournisseur($this->db); $tmpproduct = new Product($this->db); - $result = $tmpproduct->fetch($line->fk_product); - 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; + + foreach ($this->lines as &$line) { + $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; + } + } + + $line->total_cost = price2num($line->qty * $line->unit_cost, 'MT'); + + $this->total_cost += $line->total_cost; } - $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) { - $this->unit_cost = price2num($this->total_cost / $this->qty, 'MU'); + $this->total_cost = price2num($this->total_cost, 'MT'); + if ($this->qty) { + $this->unit_cost = price2num($this->total_cost / $this->qty, 'MU'); + } } } } @@ -1132,6 +1139,7 @@ class BOMLine extends CommonObjectLine 'rowid' => array('type'=>'integer', 'label'=>'LineID', 'enabled'=>1, 'visible'=>-1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), 'fk_bom' => array('type'=>'integer:BillOfMaterials:societe/class/bom.class.php', 'label'=>'BillOfMaterials', 'enabled'=>1, 'visible'=>1, 'position'=>10, 'notnull'=>1, 'index'=>1,), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'enabled'=>1, 'visible'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,), + 'fk_bom_child' => array('type'=>'integer:BOM:bom/class/bom.class.php', 'label'=>'BillOfMaterials', 'enabled'=>1, 'visible'=>-1, 'position'=>40, 'notnull'=>-1,), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,), 'qty' => array('type'=>'double(24,8)', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'position'=>100, 'notnull'=>1, 'isameasure'=>'1',), 'qty_frozen' => array('type'=>'smallint', 'label'=>'QuantityFrozen', 'enabled'=>1, 'visible'=>1, 'default'=>0, 'position'=>105, 'css'=>'maxwidth50imp', 'help'=>'QuantityConsumedInvariable'), @@ -1156,6 +1164,11 @@ class BOMLine extends CommonObjectLine */ public $fk_product; + /** + * @var int Id of parent bom + */ + public $fk_bom_child; + /** * @var string description */ @@ -1383,7 +1396,7 @@ class BOMLine extends CommonObjectLine $label .= '
    '; $label .= ''.$langs->trans('Ref').': '.$this->ref; - $url = dol_buildpath('/bom/bomline_card.php', 1).'?id='.$this->id; + $url = DOL_URL_ROOT.'/bom/bomline_card.php?id='.$this->id; if ($option != 'nolink') { // Add param to save lastsearch_values or not diff --git a/htdocs/bom/lib/bom.lib.php b/htdocs/bom/lib/bom.lib.php index 8f3cadeedc2..edd9bd69ef4 100644 --- a/htdocs/bom/lib/bom.lib.php +++ b/htdocs/bom/lib/bom.lib.php @@ -54,7 +54,9 @@ function bomAdminPrepareHead() //$this->tabs = array( // 'entity:-tabname:Title:@bom:/bom/mypage.php?id=__ID__' //); // to remove a tab - complete_head_from_modules($conf, $langs, null, $head, $h, 'bom'); + complete_head_from_modules($conf, $langs, null, $head, $h, 'bom@mrp'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'bom@mrp', 'remove'); return $head; } diff --git a/htdocs/bom/tpl/linkedobjectblock.tpl.php b/htdocs/bom/tpl/linkedobjectblock.tpl.php index fcba37105d3..c42da9bdb19 100644 --- a/htdocs/bom/tpl/linkedobjectblock.tpl.php +++ b/htdocs/bom/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user, $db; global $noMoreLinkedObjectBlockAfter; @@ -73,7 +73,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { echo '
    '; echo "\n"; diff --git a/htdocs/bom/tpl/objectline_create.tpl.php b/htdocs/bom/tpl/objectline_create.tpl.php index 210ab695ec8..fc8c811379c 100644 --- a/htdocs/bom/tpl/objectline_create.tpl.php +++ b/htdocs/bom/tpl/objectline_create.tpl.php @@ -88,15 +88,14 @@ print ''; + $coldisplay++; print ''; $coldisplay++; print ''; $coldisplay++; diff --git a/htdocs/bom/tpl/objectline_edit.tpl.php b/htdocs/bom/tpl/objectline_edit.tpl.php index 46b57e89243..e5f24fa994f 100644 --- a/htdocs/bom/tpl/objectline_edit.tpl.php +++ b/htdocs/bom/tpl/objectline_edit.tpl.php @@ -124,7 +124,7 @@ print ''; $coldisplay++; print ''; +print ''; $coldisplay++; print ''; $coldisplay += $colspan; print ''; print ''; diff --git a/htdocs/bom/tpl/objectline_title.tpl.php b/htdocs/bom/tpl/objectline_title.tpl.php index d1b29ee03b0..dff3a38ccd2 100644 --- a/htdocs/bom/tpl/objectline_title.tpl.php +++ b/htdocs/bom/tpl/objectline_title.tpl.php @@ -39,6 +39,8 @@ if (empty($object) || !is_object($object)) { exit; } print "\n"; + + // Title line print "\n"; @@ -49,8 +51,13 @@ if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { print ''; } -// Description -print ''; +// Product or sub-bom +print ''; // Qty print ''; diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php index fff9d077a08..82626c12fec 100644 --- a/htdocs/bom/tpl/objectline_view.tpl.php +++ b/htdocs/bom/tpl/objectline_view.tpl.php @@ -80,9 +80,17 @@ print '
    '; $coldisplay++; $tmpproduct = new Product($object->db); $tmpproduct->fetch($line->fk_product); -print $tmpproduct->getNomUrl(1); -print ' - '.$tmpproduct->label; +$tmpbom = new BOM($object->db); +$res = $tmpbom->fetch($line->fk_bom_child); +if ($tmpbom->id > 0) { + print $tmpbom->getNomUrl(1); + print '' . (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT) ? '(+)' : '(-)') . ' '; +} else { + print $tmpproduct->getNomUrl(1); + print ' - '.$tmpproduct->label; +} print ''; + print ''; -print ''; @@ -121,7 +130,7 @@ if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines') { $coldisplay++; if (($line->info_bits & 2) == 2 || !empty($disableedit)) { } else { - print 'id.'">'.img_edit().''; + print 'id.'">'.img_edit().''; } print ''; @@ -129,7 +138,7 @@ if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines') { $coldisplay++; if (($line->fk_prev_id == null) && empty($disableremove)) { //La suppression n'est autorisée que si il n'y a pas de ligne dans une précédente situation - print 'id.'">'; + print 'id.'">'; print img_delete(); print ''; } @@ -166,6 +175,93 @@ 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'; +$sql.= ' WHERE fk_bom ='. (int) $tmpbom->id; +$resql = $object->db->query($sql); + +if ($resql) { + // Loop on all the sub-BOM lines if they exist + while ($obj = $object->db->fetch_object($resql)) { + $sub_bom_product = new Product($object->db); + $sub_bom_product->fetch($obj->fk_product); + + $sub_bom = new BOM($object->db); + $sub_bom->fetch($obj->fk_bom_child); + + $sub_bom_line = new BOMLine($object->db); + $sub_bom_line->fetch($obj->rowid); + + //If hidden conf is set, we show directly all the sub-BOM lines + if (empty($conf->global->BOM_SHOW_ALL_BOM_BY_DEFAULT)) { + print ''; + } else { + print ''; + } + + // Product + print ''; + + // Sub-BOM + if ($sub_bom_line->fk_bom_child > 0) { + print ''; + } else { + print ''; + } + + // Qty + print ''; + if ($sub_bom_line->qty_frozen > 0) { + print ''; + } else { + print ''; + } + + // Disable stock change + if ($sub_bom_line->disable_stock_change > 0) { + print ''; + } else { + print ''; + } + + // Efficiency + print ''; + + // Cost price if it's defined + if ($sub_bom_product->cost_price > 0) { + print ''; + $total_cost.= $sub_bom_product->cost_price * $line->qty; + } elseif ($sub_bom_product->pmp > 0) { // PMP if cost price isn't defined + print ''; + $total_cost.= $sub_bom_product->pmp * $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.= ' 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 ''; + $total_cost+= $obj->min_price * $line->qty; + } + } + + print ''; + print ''; + print ''; + } +} + +// Replace of the total_cost value by the sum of all sub-BOM lines total_cost +if ($total_cost > 0) { + $line->total_cost = price($total_cost); + ?> + + showOptionals($extrafields, 'view', array('style'=>'class="drag drop oddeven"', 'colspan'=>$coldisplay), '', '', 1, 'line'); diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 045e656de50..2637262a5e1 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -31,7 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/bookmarks/class/bookmark.class.php'; $langs->loadLangs(array('bookmarks', 'other')); // Security check -if (!$user->rights->bookmark->lire) { +if (empty($user->rights->bookmark->lire)) { restrictedArea($user, 'bookmarks'); } @@ -154,9 +154,9 @@ if ($action == 'create') { print ''; print ''; - print load_fiche_titre($langs->trans("NewBookmark")); + print load_fiche_titre($langs->trans("NewBookmark"), '', 'bookmark'); - print dol_get_fiche_head($head, $hselected, $langs->trans("Bookmark"), -1, 'bookmark'); + print dol_get_fiche_head(null, 'bookmark', '', 0, ''); print '
    '."\n"; - print ''; + 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 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print "
    '; // For now, shipments must stay linked to order, so link is not deletable if ($object->element != 'shipping') { - echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; + echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; } echo '
    '; // Predefined product/service if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { - if ($forceall >= 0 && $freelines) { - echo '
    '; + if (!empty($conf->global->BOM_SUB_BOM)) { + print $langs->trans("Product"); } echo ''; - $filtertype = ''; - if (!empty($object->element) && $object->element == 'contrat' && empty($conf->global->CONTRACT_SUPPORT_PRODUCTS)) { - $filtertype = '1'; + $filtertype = 0; + if (!empty($object->element) && $object->element == 'contrat' && empty($conf->global->STOCK_SUPPORT_SERVICES)) { + $filtertype = -1; } - $statustoshow = -1; if (!empty($conf->global->ENTREPOT_EXTRA_STATUS)) { // hide products in closed warehouse, but show products for internal transfer @@ -107,6 +106,13 @@ if (!empty($conf->product->enabled) || !empty($conf->service->enabled)) { echo ''; } +if (!empty($conf->global->BOM_SUB_BOM)) { + print '
    '.$langs->trans("or").' '.$langs->trans("BOM"); + // TODO Add component to select a BOM + print ''; +} +print '
    '; @@ -128,7 +134,7 @@ print ''; -print ''; +print ''; print ''; -print ''; @@ -133,9 +133,8 @@ print ''; $coldisplay += $colspan; -print ''; -print '
    '; -print ''; +print ''; +print ''; print '
     '.$langs->trans('Description').''.$langs->trans('Description'); +if (!empty($conf->global->BOM_SUB_BOM)) { + print '   '.img_picto('', 'folder-open', 'class="paddingright"').$langs->trans("ExpandAll").'  '; + print ''.img_picto('', 'folder', 'class="paddingright"').$langs->trans("UndoExpandAll").' '; +} +print ''.$form->textwithpicto($langs->trans('Qty'), $langs->trans("QtyRequiredIfNoLoss")).''; $coldisplay++; echo price($line->qty, 0, '', 0, 0); // Yes, it is a quantity, not a price, but we just want the formating role of function price @@ -111,7 +119,8 @@ $coldisplay++; echo $line->efficiency; print ''; +$total_cost = 0; +print ''; $coldisplay++; echo price($line->total_cost); print '
    '.$sub_bom_product->getNomUrl(1).''.$sub_bom->getNomUrl(1).' '.price($sub_bom_line->qty * $line->qty, 0, '', 0, 0).''.$sub_bom_line->qty_frozen.' '.$sub_bom_line->disable_stock_change.' '.$sub_bom_line->efficiency.''.price($sub_bom_product->cost_price * $line->qty).''.price($sub_bom_product->pmp * $line->qty).''.price($obj->min_price * $line->qty).'
    '; @@ -164,32 +164,33 @@ if ($action == 'create') { dol_set_focus('#titlebookmark'); // Url - print ''; + print ''; // Target print ''; // Owner print ''; + print img_picto('', 'user').' '.$form->select_dolusers(GETPOSTISSET('userid') ? GETPOST('userid', 'int') : $user->id, 'userid', 0, '', 0, ($user->admin ? '' : array($user->id)), '', 0, 0, 0, '', ($user->admin) ? 1 : 0, '', 'maxwidth300 widthcentpercentminusx'); + print ''; // Position print ''; + print 'position).'">'; + print ''; print '
    '.$langs->trans("UrlOrLink").''.$langs->trans("UseAnExternalHttpLinkOrRelativeDolibarrLink").'
    '.$langs->trans("UrlOrLink").''.$langs->trans("UseAnExternalHttpLinkOrRelativeDolibarrLink").'
    '.$langs->trans("BehaviourOnClick").''; $liste = array(0=>$langs->trans("ReplaceWindow"), 1=>$langs->trans("OpenANewWindow")); - print $form->selectarray('target', $liste, GETPOSTISSET('target') ? GETPOST('target', 'int') : 1); + $defaulttarget = 1; + if ($url && !preg_match('/^http/i', $url)) { + $defaulttarget = 0; + } + print $form->selectarray('target', $liste, GETPOSTISSET('target') ? GETPOST('target', 'int') : $defaulttarget, 0, 0, 0, '', 0, 0, 0, '', 'maxwidth300'); print ''.$langs->trans("ChooseIfANewWindowMustBeOpenedOnClickOnBookmark").'
    '.$langs->trans("Visibility").''; - print img_picto('', 'user').' '.$form->select_dolusers(GETPOSTISSET('userid') ? GETPOST('userid', 'int') : $user->id, 'userid', 0, '', 0, ($user->admin ? '' : array($user->id)), '', 0, 0, 0, '', ($user->admin) ? 1 : 0, '', 'maxwidth300'); - print ' 
    '.$langs->trans("Position").''; - print 'position).'">'; - print ' 
    '; print dol_get_fiche_end(); - print '
    '; - print '   '; - print ''; - print '
    '; + print $form->buttonsSaveCancel("CreateBookmark"); print ''; } @@ -313,12 +314,12 @@ if ($id > 0 && !preg_match('/^add/i', $action)) { // Edit if ($user->rights->bookmark->creer && $action != 'edit') { - print ''.$langs->trans("Edit").''."\n"; + print ''.$langs->trans("Edit").''."\n"; } // Remove if ($user->rights->bookmark->supprimer && $action != 'edit') { - print ''.$langs->trans("Delete").''."\n"; + print ''.$langs->trans("Delete").''."\n"; } print '
    '; diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index 17be6be9cef..642fc4995a9 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -35,7 +35,7 @@ $toselect = GETPOST('toselect', 'array'); $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'bookmarklist'; // To manage different context of search // Security check -if (!$user->rights->bookmark->lire) { +if (empty($user->rights->bookmark->lire)) { restrictedArea($user, 'bookmarks'); } $optioncss = GETPOST('optioncss', 'alpha'); @@ -62,9 +62,9 @@ $id = GETPOST("id", 'int'); $object = new Bookmark($db); -$permissiontoread = $user->rights->bookmark->lire; -$permissiontoadd = $user->rights->bookmark->write; -$permissiontodelete = $user->rights->bookmark->delete; +$permissiontoread = !empty($user->rights->bookmark->lire); +$permissiontoadd = !empty($user->rights->bookmark->creer); +$permissiontodelete = !empty($user->rights->bookmark->supprimer); /* diff --git a/htdocs/categories/admin/categorie.php b/htdocs/categories/admin/categorie.php index bddeb9a771a..02e6892b571 100644 --- a/htdocs/categories/admin/categorie.php +++ b/htdocs/categories/admin/categorie.php @@ -101,9 +101,9 @@ if ($conf->use_javascript_ajax) { print ajax_constantonoff('CATEGORIE_RECURSIV_ADD'); } else { if (empty($conf->global->CATEGORIE_RECURSIV_ADD)) { - print ''.img_picto($langs->trans("Disabled"), 'off').''; + print ''.img_picto($langs->trans("Disabled"), 'off').''; } else { - print ''.img_picto($langs->trans("Enabled"), 'on').''; + print ''.img_picto($langs->trans("Enabled"), 'on').''; } } print '
    '; diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index ba5515149d4..9a449d63700 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -58,6 +58,7 @@ class Categorie extends CommonObject const TYPE_ACTIONCOMM = 'actioncomm'; const TYPE_WEBSITE_PAGE = 'website_page'; const TYPE_TICKET = 'ticket'; + const TYPE_KNOWLEDGEMANAGEMENT = 'knowledgemanagement'; /** * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png @@ -81,7 +82,8 @@ class Categorie extends CommonObject 'warehouse' => 9, 'actioncomm' => 10, 'website_page' => 11, - 'ticket' => 12 + 'ticket' => 12, + 'knowledgemanagement' => 13 ); /** @@ -102,7 +104,8 @@ class Categorie extends CommonObject 9 => 'warehouse', 10 => 'actioncomm', 11 => 'website_page', - 12 => 'ticket' + 12 => 'ticket', + 13 => 'knowledgemanagement' ); /** @@ -146,7 +149,8 @@ class Categorie extends CommonObject 'warehouse'=> 'Entrepot', 'actioncomm' => 'ActionComm', 'website_page' => 'WebsitePage', - 'ticket' => 'Ticket' + 'ticket' => 'Ticket', + 'knowledgemanagement' => 'KnowledgeRecord' ); /** @@ -240,7 +244,6 @@ class Categorie extends CommonObject * @see Categorie::TYPE_ACTIONCOMM * @see Categorie::TYPE_WEBSITE_PAGE * @see Categorie::TYPE_TICKET - */ public $type; @@ -381,8 +384,8 @@ class Categorie extends CommonObject } } else { dol_print_error($this->db); - $this->error=$this->db->lasterror; - $this->errors[]=$this->db->lasterror; + $this->error = $this->db->lasterror; + $this->errors[] = $this->db->lasterror; return -1; } } @@ -622,12 +625,18 @@ class Categorie extends CommonObject } $arraydelete = array( - 'categorie_societe' => 'fk_categorie', - 'categorie_fournisseur' => 'fk_categorie', 'categorie_product' => 'fk_categorie', + 'categorie_fournisseur' => 'fk_categorie', + 'categorie_societe' => 'fk_categorie', 'categorie_member' => 'fk_categorie', 'categorie_contact' => 'fk_categorie', + 'categorie_user' => 'fk_categorie', + 'categorie_project' => 'fk_categorie', 'categorie_account' => 'fk_categorie', + 'categorie_website_page' => 'fk_categorie', + 'categorie_warehouse' => 'fk_categorie', + 'categorie_actioncomm' => 'fk_categorie', + 'categorie_ticket' => 'fk_categorie', 'bank_class' => 'fk_categ', 'categorie_lang' => 'fk_category', 'categorie' => 'rowid', @@ -724,8 +733,6 @@ class Categorie extends CommonObject } } - - // Call trigger $this->context = array('linkto'=>$obj); // Save object we want to link category to into category instance to provide information to trigger $result = $this->call_trigger('CATEGORY_LINK', $user); @@ -1969,6 +1976,12 @@ class Categorie extends CommonObject if ($type == 'bank_account') { $type = 'account'; } + if ($type == 'customer') { + $type = 'societe'; + } + if ($type == 'supplier') { + $type = 'fournisseur'; + } if (empty($searchList) && !is_array($searchList)) { return ""; diff --git a/htdocs/categories/index.php b/htdocs/categories/index.php index 065b4dfa83e..708fb3a3e83 100644 --- a/htdocs/categories/index.php +++ b/htdocs/categories/index.php @@ -205,10 +205,14 @@ foreach ($fulltree as $key => $val) { $entry .= ''.img_view().''; $entry .= '
    '; - $entry .= ''.img_edit().''; + if ($user->rights->categorie->creer) { + $entry .= '' . img_edit() . ''; + } $entry .= ''; - $entry .= ''.img_delete().''; + if ($user->rights->categorie->supprimer) { + $entry .= '' . img_delete() . ''; + } $entry .= '
    '; + print ''; + print ''; + print '
    '; + print $langs->trans("AddMemberIntoCategory").'  '; + print $form->selectMembers('', 'elemid'); + print '
    '; + print ''; + } + print '
    '; print ''; print ''; @@ -749,9 +795,28 @@ if ($type == Categorie::TYPE_CONTACT) { $permission = $user->rights->societe->creer; $contacts = $object->getObjectsInCateg($type, 0, $limit, $offset); - if ($contacts < 0) { + if (is_numeric($contacts) && $contacts < 0) { dol_print_error($db, $object->error, $object->errors); } else { + // Form to add record into a category + $showclassifyform = 1; + if ($showclassifyform) { + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '; + print $langs->trans("AddContactIntoCategory").'  '; + print $form->selectContacts('', '', 'elemid'); + print '
    '; + print '
    '; + } print '
    '; print ''; print ''; @@ -770,7 +835,7 @@ if ($type == Categorie::TYPE_CONTACT) { print ''."\n"; print ''."\n"; - if (count($contacts) > 0) { + if (is_array($contacts) && count($contacts) > 0) { $i = 0; foreach ($contacts as $key => $contact) { $i++; @@ -817,6 +882,26 @@ if ($type == Categorie::TYPE_ACCOUNT) { if ($accounts < 0) { dol_print_error($db, $object->error, $object->errors); } else { + // Form to add record into a category + $showclassifyform = 1; + if ($showclassifyform) { + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '.$langs->trans("Ref").'
    '; + print ''; + print ''; + print '
    '; + print $langs->trans("AddAccountIntoCategory").'  '; + $form->select_comptes('', 'elemid'); + print '
    '; + print '
    '; + } + print '
    '; print ''; print ''; @@ -874,6 +959,26 @@ if ($type == Categorie::TYPE_PROJECT) { if ($objects < 0) { dol_print_error($db, $object->error, $object->errors); } else { + // Form to add record into a category + $showclassifyform = 1; + if ($showclassifyform) { + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '; + print $langs->trans("AddProjectIntoCategory").'  '; + $form->selectProjects('', 'elemid'); + print '
    '; + print '
    '; + } + print '
    '; print ''; print ''; @@ -930,6 +1035,25 @@ if ($type == Categorie::TYPE_USER) { if ($users < 0) { dol_print_error($db, $object->error, $object->errors); } else { + // Form to add record into a category + $showclassifyform = 1; + if ($showclassifyform) { + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
    '; + print $langs->trans("AddProjectIntoCategory").'  '; + print $form->select_dolusers('', 'elemid'); + print '
    '; + print '
    '; + } print '
    '; print ''; print ''; diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index e4ceccdb3fc..74c7a6d272f 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -75,8 +75,13 @@ if ($complete == 'na' || $complete == -2) { $complete = -1; } -$datep = dol_mktime($fulldayevent ? '00' : $aphour, $fulldayevent ? '00' : $apmin, 0, GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int')); -$datef = dol_mktime($fulldayevent ? '23' : $p2hour, $fulldayevent ? '59' : $p2min, $fulldayevent ? '59' : '0', GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int')); +if ($fulldayevent) { + $datep = dol_mktime('00', '00', 0, GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int')); + $datef = dol_mktime('23', '59', '59', GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int')); +} else { + $datep = dol_mktime($aphour, $apmin, 0, GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int')); + $datef = dol_mktime($p2hour, $p2min, '59', GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int')); +} // Security check $socid = GETPOST('socid', 'int'); @@ -278,8 +283,20 @@ if (empty($reshook) && $action == 'add') { $object->fulldayevent = (!empty($fulldayevent) ? 1 : 0); $object->location = GETPOST("location", 'alphanohtml'); $object->label = GETPOST('label', 'alphanohtml'); - $object->fk_element = GETPOST("fk_element", 'int'); - $object->elementtype = GETPOST("elementtype", 'alpha'); + + if (GETPOST("elementtype", 'alpha')) { + $modulecodetouseforpermissioncheck = GETPOST("elementtype", 'alpha'); + + $hasPermissionOnLinkedObject = 0; + if ($user->hasRight($modulecodetouseforpermissioncheck, 'read')) { + $hasPermissionOnLinkedObject = 1; + } + if ($hasPermissionOnLinkedObject) { + $object->fk_element = GETPOST("fk_element", 'int'); + $object->elementtype = GETPOST("elementtype", 'alpha'); + } + } + if (!GETPOST('label')) { if (GETPOST('actioncode', 'aZ09') == 'AC_RDV' && $contact->getFullName($langs)) { $object->label = $langs->transnoentitiesnoconv("TaskRDVWith", $contact->getFullName($langs)); @@ -520,8 +537,20 @@ if (empty($reshook) && $action == 'update') { } $object->fk_project = GETPOST("projectid", 'int'); $object->note_private = trim(GETPOST("note", "restricthtml")); - $object->fk_element = GETPOST("fk_element", "int"); - $object->elementtype = GETPOST("elementtype", "alphanohtml"); + + if (GETPOST("elementtype", 'alpha')) { + $modulecodetouseforpermissioncheck = GETPOST("elementtype", 'alpha'); + + $hasPermissionOnLinkedObject = 0; + if ($user->hasRight($modulecodetouseforpermissioncheck, 'read')) { + $hasPermissionOnLinkedObject = 1; + } + if ($hasPermissionOnLinkedObject) { + $object->fk_element = GETPOST("fk_element", 'int'); + $object->elementtype = GETPOST("elementtype", 'alpha'); + } + } + if (!$datef && $percentage == 100) { $error++; $donotclearsession = 1; setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), $object->errors, 'errors'); @@ -943,7 +972,7 @@ if ($action == 'create') { print ''; print ''; if ($backtopage) { - print ''; + print ''; } if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) { print ''; @@ -1191,7 +1220,7 @@ if ($action == 'create') { print img_picto('', 'project', 'class="pictofixedwidth"'); print $formproject->select_projects((empty($societe->id) ? '' : $societe->id), $projectid, 'projectid', 0, 0, 1, 1, 0, 0, 0, '', 1, 0, 'maxwidth500 widthcentpercentminusxx'); - print ' '; + print ' '; print ''; $urloption = '?action=create&donotclearsession=1'; $url = dol_buildpath('comm/action/card.php', 2).$urloption; @@ -1218,7 +1247,7 @@ if ($action == 'create') { if (!empty($projectid)) { $projectsListId = $projectid; } - $tid = GETPOST("projecttaskid") ? GETPOST("projecttaskid") : ''; + $tid = GETPOSTISSET("projecttaskid") ? GETPOST("projecttaskid", 'int') : (GETPOSTISSET("taskid") ? GETPOST("taskid", 'int') : ''); $formproject->selectTasks((!empty($societe->id) ? $societe->id : -1), $tid, 'taskid', 24, 0, '1', 1, 0, 0, 'maxwidth500', $projectsListId); print ''; } @@ -1226,12 +1255,28 @@ if ($action == 'create') { // Object linked if (!empty($origin) && !empty($originid)) { include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - print ''.$langs->trans("LinkedObject").''; - print ''.dolGetElementUrl($originid, $origin, 1).''; - print ''; - print ''; - print ''; - print ''; + + $hasPermissionOnLinkedObject = 0; + if ($user->hasRight($origin, 'read')) { + $hasPermissionOnLinkedObject = 1; + } + //var_dump('origin='.$origin.' originid='.$originid.' $hasPermissionOnLinkedObject='.$hasPermissionOnLinkedObject); + + if (! in_array($origin, array('societe', 'project', 'task', 'user'))) { + // We do not use link for object that already contains a hard coded field to make links with agenda events + print ''.$langs->trans("LinkedObject").''; + print ''; + if ($hasPermissionOnLinkedObject) { + print dolGetElementUrl($originid, $origin, 1); + print ''; + print ''; + print ''; + print ''; + } else { + print ''; + } + print ''; + } } $reg = array(); @@ -1258,7 +1303,7 @@ if ($action == 'create') { $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, 'edit', $parameters); + print $object->showOptionals($extrafields, 'create', $parameters); } print ''; @@ -1429,7 +1474,7 @@ if ($id > 0) { print ''; print ''; if ($backtopage) { - print ''; + print ''; } if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) { print ''; @@ -1648,7 +1693,7 @@ if ($id > 0) { print img_picto('', 'project', 'class="paddingrightonly"'); $numprojet = $formproject->select_projects(($object->socid > 0 ? $object->socid : -1), $object->fk_project, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth500'); if ($numprojet == 0) { - print '   '; + print '   '; } print ''; } @@ -1847,7 +1892,7 @@ if ($id > 0) { if ($user->rights->agenda->allactions->create || (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->rights->agenda->myactions->create)) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -1864,9 +1909,7 @@ if ($id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); if ($proj->title) { $morehtmlref .= ' - '.$proj->title; } @@ -2128,7 +2171,7 @@ if ($id > 0) { if ($action != 'edit') { if ($user->rights->agenda->allactions->create || (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->rights->agenda->myactions->create)) { - print ''; + print ''; } else { print ''; } @@ -2167,12 +2210,12 @@ if ($id > 0) { $delallowed = $user->rights->agenda->myactions->create; - print $formfile->showdocuments('actions', $object->id, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 0, 0, '', '', '', $object->default_lang); + print $formfile->showdocuments('actions', $object->id, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 0, 0, '', '', '', $langs->getDefaultLang()); - print '
    '; + print '
    '; - print '
    '; + print ''; } } } diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index df73c6a70f7..3e2520f43da 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -735,13 +735,14 @@ class ActionComm extends CommonObject /** * Load object from database * - * @param int $id Id of action to get - * @param string $ref Ref of action to get - * @param string $ref_ext Ref ext to get - * @param string $email_msgid Email msgid - * @return int <0 if KO, >0 if OK + * @param int $id Id of action to get + * @param string $ref Ref of action to get + * @param string $ref_ext Ref ext to get + * @param string $email_msgid Email msgid + * @param string $loadresources 1=Load also resources + * @return int <0 if KO, >0 if OK */ - public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '') + public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '', $loadresources = 1) { global $langs; @@ -858,8 +859,13 @@ class ActionComm extends CommonObject $this->event_paid = $obj->event_paid; $this->status = $obj->status; - $this->fetchResources(); + $this->fetch_optionals(); + + if ($loadresources) { + $this->fetchResources(); + } } + $this->db->free($resql); } else { $this->error = $this->db->lasterror(); @@ -1240,7 +1246,6 @@ class ActionComm extends CommonObject * Load all objects with filters. * @todo WARNING: This make a fetch on all records instead of making one request with a join. * - * @param DoliDb $db Not used * @param int $socid Filter by thirdparty * @param int $fk_element Id of element action is linked to * @param string $elementtype Type of element action is linked to @@ -1250,7 +1255,7 @@ class ActionComm extends CommonObject * @param string $limit Limit number of answers * @return array|string Error string if KO, array with actions if OK */ - public static function getActions($db, $socid = 0, $fk_element = 0, $elementtype = '', $filter = '', $sortfield = 'a.datep', $sortorder = 'DESC', $limit = 0) + public function getActions($socid = 0, $fk_element = 0, $elementtype = '', $filter = '', $sortfield = 'a.datep', $sortorder = 'DESC', $limit = 0) { global $conf, $langs; @@ -1272,33 +1277,33 @@ class ActionComm extends CommonObject $sql .= " (SELECT fk_actioncomm FROM ".MAIN_DB_PREFIX."actioncomm_resources WHERE"; $sql .= " element_type = 'socpeople' AND fk_element = ".((int) $fk_element).')'; } else { - $sql .= " AND a.fk_element = ".((int) $fk_element)." AND a.elementtype = '".$db->escape($elementtype)."'"; + $sql .= " AND a.fk_element = ".((int) $fk_element)." AND a.elementtype = '".$this->db->escape($elementtype)."'"; } } if (!empty($filter)) { $sql .= $filter; } if ($sortorder && $sortfield) { - $sql .= $db->order($sortfield, $sortorder); + $sql .= $this->db->order($sortfield, $sortorder); } - $sql .= $db->plimit($limit, 0); + $sql .= $this->db->plimit($limit, 0); - $resql = $db->query($sql); + $resql = $this->db->query($sql); if ($resql) { - $num = $db->num_rows($resql); + $num = $this->db->num_rows($resql); if ($num) { for ($i = 0; $i < $num; $i++) { - $obj = $db->fetch_object($resql); - $actioncommstatic = new ActionComm($db); + $obj = $this->db->fetch_object($resql); + $actioncommstatic = new ActionComm($this->db); $actioncommstatic->fetch($obj->id); $resarray[$i] = $actioncommstatic; } } - $db->free($resql); + $this->db->free($resql); return $resarray; } else { - return $db->lasterror(); + return $this->db->lasterror(); } } @@ -1322,10 +1327,10 @@ class ActionComm extends CommonObject $sql = "SELECT count(a.id) as nb"; } $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; } - if (!$user->rights->agenda->allactions->read) { + if (empty($user->rights->agenda->allactions->read)) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."actioncomm_resources AS ar ON a.id = ar.fk_actioncomm AND ar.element_type ='user' AND ar.fk_element = ".((int) $user->id); } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; @@ -1334,13 +1339,13 @@ class ActionComm extends CommonObject $sql .= " AND a.percent >= 0 AND a.percent < 100"; } $sql .= " AND a.entity IN (".getEntity('agenda').")"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")"; } if ($user->socid) { $sql .= " AND a.fk_soc = ".((int) $user->socid); } - if (!$user->rights->agenda->allactions->read) { + if (empty($user->rights->agenda->allactions->read)) { $sql .= " AND (a.fk_user_author = ".((int) $user->id)." OR a.fk_user_action = ".((int) $user->id)." OR a.fk_user_done = ".((int) $user->id); $sql .= " OR ar.fk_element = ".((int) $user->id); $sql .= ")"; @@ -1460,18 +1465,18 @@ class ActionComm extends CommonObject // phpcs:enable global $langs; - $labelStatus = $langs->trans('StatusNotApplicable'); + $labelStatus = $langs->transnoentitiesnoconv('StatusNotApplicable'); if ($percent == -1 && !$hidenastatus) { - $labelStatus = $langs->trans('StatusNotApplicable'); + $labelStatus = $langs->transnoentitiesnoconv('StatusNotApplicable'); } elseif ($percent == 0) { - $labelStatus = $langs->trans('StatusActionToDo').' (0%)'; + $labelStatus = $langs->transnoentitiesnoconv('StatusActionToDo').' (0%)'; } elseif ($percent > 0 && $percent < 100) { - $labelStatus = $langs->trans('StatusActionInProcess').' ('.$percent.'%)'; + $labelStatus = $langs->transnoentitiesnoconv('StatusActionInProcess').' ('.$percent.'%)'; } elseif ($percent >= 100) { - $labelStatus = $langs->trans('StatusActionDone').' (100%)'; + $labelStatus = $langs->transnoentitiesnoconv('StatusActionDone').' (100%)'; } - $labelStatusShort = $langs->trans('StatusNotApplicable'); + $labelStatusShort = $langs->transnoentitiesnoconv('StatusNotApplicable'); if ($percent == -1 && !$hidenastatus) { $labelStatusShort = $langs->trans('NA'); } elseif ($percent == 0) { diff --git a/htdocs/comm/action/class/actioncommreminder.class.php b/htdocs/comm/action/class/actioncommreminder.class.php index e675c93d472..aa693d2e41f 100644 --- a/htdocs/comm/action/class/actioncommreminder.class.php +++ b/htdocs/comm/action/class/actioncommreminder.class.php @@ -228,18 +228,18 @@ class ActionCommReminder extends CommonObject // phpcs:enable global $langs; - $labelStatus = $langs->trans('ToDo'); + $labelStatus = $langs->transnoentitiesnoconv('ToDo'); if ($status == 1) { - $labelStatus = $langs->trans('Done'); + $labelStatus = $langs->transnoentitiesnoconv('Done'); } elseif ($status == -1) { - $labelStatus = $langs->trans('Error'); + $labelStatus = $langs->transnoentitiesnoconv('Error'); } - $labelStatusShort = $langs->trans('ToDo'); + $labelStatusShort = $langs->transnoentitiesnoconv('ToDo'); if ($status == 1) { - $labelStatus = $langs->trans('Done'); + $labelStatus = $langs->transnoentitiesnoconv('Done'); } elseif ($status == -1) { - $labelStatus = $langs->trans('Error'); + $labelStatus = $langs->transnoentitiesnoconv('Error'); } $statusType = 'status5'; diff --git a/htdocs/comm/action/document.php b/htdocs/comm/action/document.php index 4c4d44c3a6e..cfe87f1a259 100644 --- a/htdocs/comm/action/document.php +++ b/htdocs/comm/action/document.php @@ -166,9 +166,7 @@ if ($object->id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); if ($proj->title) { $morehtmlref .= ' - '.$proj->title; } @@ -201,9 +199,9 @@ if ($object->id > 0) { // Date start print ''.$langs->trans("DateActionStart").''; if (!$object->fulldayevent) { - print dol_print_date($object->datep, 'dayhour'); + print dol_print_date($object->datep, 'dayhour', 'tzuser'); } else { - print dol_print_date($object->datep, 'day'); + print dol_print_date($object->datep, 'day', 'tzuser'); } if ($object->percentage == 0 && $object->datep && $object->datep < ($now - $delay_warning)) { print img_warning($langs->trans("Late")); @@ -214,9 +212,9 @@ if ($object->id > 0) { // Date end print ''.$langs->trans("DateActionEnd").''; if (!$object->fulldayevent) { - print dol_print_date($object->datef, 'dayhour'); + print dol_print_date($object->datef, 'dayhour', 'tzuser'); } else { - print dol_print_date($object->datef, 'day'); + print dol_print_date($object->datef, 'day', 'tzuser'); } if ($object->percentage > 0 && $object->percentage < 100 && $object->datef && $object->datef < ($now - $delay_warning)) { print img_warning($langs->trans("Late")); diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index e79edcf8e23..5f7349fab3c 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -86,13 +86,13 @@ if ($socid < 0) { } $canedit = 1; -if (!$user->rights->agenda->myactions->read) { +if (empty($user->rights->agenda->myactions->read)) { accessforbidden(); } -if (!$user->rights->agenda->allactions->read) { +if (empty($user->rights->agenda->allactions->read)) { $canedit = 0; } -if (!$user->rights->agenda->allactions->read || $filter == 'mine') { // If no permission to see all, we show only affected to me +if (empty($user->rights->agenda->allactions->read) || $filter == 'mine') { // If no permission to see all, we show only affected to me $filtert = $user->id; } @@ -490,7 +490,7 @@ print ''; $viewmode = ''; $viewmode .= ''; //$viewmode .= ''; -$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="pictoactionview block"'); +$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="imgforviewmode pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; @@ -660,7 +660,7 @@ $sql .= ' a.fk_soc, a.fk_contact, a.fk_project,'; $sql .= ' a.fk_element, a.elementtype,'; $sql .= ' ca.code as type_code, ca.libelle as type_label, ca.color as type_color, ca.type as type_type, ca.picto as type_picto'; $sql .= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; } // We must filter on resource table @@ -711,7 +711,7 @@ if ($resourceid > 0) { if ($pid) { $sql .= " AND a.fk_project=".((int) $pid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")"; } if ($socid > 0) { diff --git a/htdocs/comm/action/info.php b/htdocs/comm/action/info.php index 071d6409176..7a369356b31 100644 --- a/htdocs/comm/action/info.php +++ b/htdocs/comm/action/info.php @@ -93,9 +93,7 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); if ($proj->title) { $morehtmlref .= ' - '.$proj->title; } diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index 477146fbfd1..7ece3fdcb28 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -4,7 +4,7 @@ * Copyright (C) 2004-2016 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2017 Open-DSI - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2020 Tobias Sekan * * This program is free software; you can redistribute it and/or modify @@ -73,8 +73,10 @@ $search_title = GETPOST('search_title', 'alpha'); $search_note = GETPOST('search_note', 'alpha'); $dateselect = dol_mktime(0, 0, 0, GETPOST('dateselectmonth', 'int'), GETPOST('dateselectday', 'int'), GETPOST('dateselectyear', 'int'), 'tzuserrel'); -$datestart = dol_mktime(0, 0, 0, GETPOST('datestartmonth', 'int'), GETPOST('datestartday', 'int'), GETPOST('datestartyear', 'int'), 'tzuserrel'); -$dateend = dol_mktime(0, 0, 0, GETPOST('dateendmonth', 'int'), GETPOST('dateendday', 'int'), GETPOST('dateendyear', 'int'), 'tzuserrel'); +$datestart_dtstart = dol_mktime(0, 0, 0, GETPOST('datestart_dtstartmonth', 'int'), GETPOST('datestart_dtstartday', 'int'), GETPOST('datestart_dtstartyear', 'int'), 'tzuserrel'); +$datestart_dtend = dol_mktime(23, 59, 59, GETPOST('datestart_dtendmonth', 'int'), GETPOST('datestart_dtendday', 'int'), GETPOST('datestart_dtendyear', 'int'), 'tzuserrel'); +$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); } @@ -134,13 +136,13 @@ if ($socid < 0) { } $canedit = 1; -if (!$user->rights->agenda->myactions->read) { +if (empty($user->rights->agenda->myactions->read)) { accessforbidden(); } -if (!$user->rights->agenda->allactions->read) { +if (empty($user->rights->agenda->allactions->read)) { $canedit = 0; } -if (!$user->rights->agenda->allactions->read || $filter == 'mine') { // If no permission to see all, we show only affected to me +if (empty($user->rights->agenda->allactions->read) || $filter == 'mine') { // If no permission to see all, we show only affected to me $filtert = $user->id; } @@ -205,8 +207,10 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_id = ''; $search_title = ''; $search_note = ''; - $datestart = ''; - $dateend = ''; + $datestart_dtstart = ''; + $datestart_dtend = ''; + $dateend_dtstart = ''; + $dateend_dtend = ''; $search_status = ''; $toselect = ''; $search_array_options = array(); @@ -323,23 +327,41 @@ if ($search_title != '') { if ($search_note != '') { $param .= '&search_note='.urlencode($search_note); } -if (GETPOST('datestartday', 'int')) { - $param .= '&datestartday='.GETPOST('datestartday', 'int'); +if (GETPOST('datestartday_dtstart', 'int')) { + $param .= '&datestartday_dtstart='.GETPOST('datestartday_dtstart', 'int'); } -if (GETPOST('datestartmonth', 'int')) { - $param .= '&datestartmonth='.GETPOST('datestartmonth', 'int'); +if (GETPOST('datestartmonth_dtstart', 'int')) { + $param .= '&datestartmonth_dtstart='.GETPOST('datestartmonth_dtstart', 'int'); } -if (GETPOST('datestartyear', 'int')) { - $param .= '&datestartyear='.GETPOST('datestartyear', 'int'); +if (GETPOST('datestartyear_dtstart', 'int')) { + $param .= '&datestartyear_dtstart='.GETPOST('datestartyear_dtstart', 'int'); } -if (GETPOST('dateendday', 'int')) { - $param .= '&dateendday='.GETPOST('dateendday', 'int'); +if (GETPOST('datestartday_dtend', 'int')) { + $param .= '&datestartday_dtend='.GETPOST('datestartday_dtend', 'int'); } -if (GETPOST('dateendmonth', 'int')) { - $param .= '&dateendmonth='.GETPOST('dateendmonth', 'int'); +if (GETPOST('datestartmonth_dtend', 'int')) { + $param .= '&datestartmonth_dtend='.GETPOST('datestartmonth_dtend', 'int'); } -if (GETPOST('dateendyear', 'int')) { - $param .= '&dateendyear='.GETPOST('dateendyear', 'int'); +if (GETPOST('datestartyear_dtend', 'int')) { + $param .= '&datestartyear_dtend='.GETPOST('datestartyear_dtend', 'int'); +} +if (GETPOST('dateendday_dtstart', 'int')) { + $param .= '&dateendday_dtstart='.GETPOST('dateendday_dtstart', 'int'); +} +if (GETPOST('dateendmonth_dtstart', 'int')) { + $param .= '&dateendmonth_dtstart='.GETPOST('dateendmonth_dtstart', 'int'); +} +if (GETPOST('dateendyear_dtstart', 'int')) { + $param .= '&dateendyear_dtstart='.GETPOST('dateendyear_dtstart', 'int'); +} +if (GETPOST('dateendday_dtend', 'int')) { + $param .= '&dateendday_dtend='.GETPOST('dateendday_dtend', 'int'); +} +if (GETPOST('dateendmonth_dtend', 'int')) { + $param .= '&dateendmonth_dtend='.GETPOST('dateendmonth_dtend', 'int'); +} +if (GETPOST('dateendyear_dtend', 'int')) { + $param .= '&dateendyear_dtend='.GETPOST('dateendyear_dtend', 'int'); } if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); @@ -392,7 +414,7 @@ $sql .= $hookmanager->resPrint; $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."actioncomm_extrafields as ef ON (a.id = ef.fk_object)"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; @@ -446,7 +468,7 @@ if ($resourceid > 0) { if ($pid) { $sql .= " AND a.fk_project=".((int) $pid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")"; } if ($socid > 0) { @@ -502,11 +524,17 @@ if ($filtert > 0 || $usergroup > 0) { if ($dateselect > 0) { $sql .= " AND ((a.datep2 >= '".$db->idate($dateselect)."' AND a.datep <= '".$db->idate($dateselect + 3600 * 24 - 1)."') OR (a.datep2 IS NULL AND a.datep > '".$db->idate($dateselect - 3600)."' AND a.datep <= '".$db->idate($dateselect + 3600 * 24 - 1)."'))"; } -if ($datestart > 0) { - $sql .= " AND a.datep BETWEEN '".$db->idate($datestart)."' AND '".$db->idate($datestart + 3600 * 24 - 1)."'"; +if ($datestart_dtstart > 0) { + $sql .= " AND a.datep >= '".$db->idate($datestart_dtstart)."'"; } -if ($dateend > 0) { - $sql .= " AND a.datep2 BETWEEN '".$db->idate($dateend)."' AND '".$db->idate($dateend + 3600 * 24 - 1)."'"; +if ($datestart_dtend > 0) { + $sql .= " AND a.datep <= '".$db->idate($datestart_dtend)."'"; +} +if ($dateend_dtstart > 0) { + $sql .= " AND a.datep2 >= '".$db->idate($dateend_dtstart)."'"; +} +if ($dateend_dtend > 0) { + $sql .= " AND a.datep2 <= '".$db->idate($dateend_dtend)."'"; } // Add where from extra fields @@ -597,60 +625,47 @@ print $nav; //print_actions_filter($form, $canedit, $search_status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, -1, $actioncode, $usergroup, '', $resourceid); //print dol_get_fiche_end(); -// Add link to show birthdays -/* -$link = ''; -if (empty($conf->use_javascript_ajax)) -{ - $newparam=$param; // newparam is for birthday links - $newparam=preg_replace('/showbirthday=[0-1]/i','showbirthday='.(empty($showbirthday)?1:0),$newparam); - if (! preg_match('/showbirthday=/i',$newparam)) $newparam.='&showbirthday=1'; - $link=''; - if (empty($showbirthday)) $link.=$langs->trans("AgendaShowBirthdayEvents"); - else $link.=$langs->trans("AgendaHideBirthdayEvents"); - $link.=''; -} -*/ $s = $newtitle; // Calendars from hooks -$parameters = array(); $object = null; +$parameters = array(); +$object = null; $reshook = $hookmanager->executeHooks('addCalendarChoice', $parameters, $object, $action); if (empty($reshook)) { $s .= $hookmanager->resPrint; } elseif ($reshook > 1) { $s = $hookmanager->resPrint; } - +$viewyear = is_object($object) ? dol_print_date($object->datep, '%Y') : ''; +$viewmonth = is_object($object) ? dol_print_date($object->datep, '%m') : ''; +$viewday = is_object($object) ? dol_print_date($object->datep, '%d') : ''; $viewmode = ''; $viewmode .= ''; //$viewmode .= ''; -$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="pictoactionview block"'); +$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="imgforviewmode pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; -$viewmode .= ''; +$viewmode .= ''; //$viewmode .= ''; $viewmode .= img_picto($langs->trans("ViewCal"), 'object_calendarmonth', 'class="pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewCal").''; -$viewmode .= ''; +$viewmode .= ''; //$viewmode .= ''; $viewmode .= img_picto($langs->trans("ViewWeek"), 'object_calendarweek', 'class="pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewWeek").''; -$viewmode .= ''; +$viewmode .= ''; //$viewmode .= ''; $viewmode .= img_picto($langs->trans("ViewDay"), 'object_calendarday', 'class="pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewDay").''; -$viewmode .= ''; +$viewmode .= ''; //$viewmode .= ''; $viewmode .= img_picto($langs->trans("ViewPerUser"), 'object_calendarperuser', 'class="pictoactionview block"'); //$viewmode .= ''; @@ -659,7 +674,8 @@ $viewmode .= ''; // Add more views from hooks -$parameters = array(); $object = null; +$parameters = array(); +$object = null; $reshook = $hookmanager->executeHooks('addCalendarView', $parameters, $object, $action); if (empty($reshook)) { $viewmode .= $hookmanager->resPrint; @@ -669,7 +685,7 @@ if (empty($reshook)) { $tmpforcreatebutton = dol_getdate(dol_now(), true); -$newparam .= '&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$tmpforcreatebutton['year']; +$newparam = '&month='.str_pad($month, 2, "0", STR_PAD_LEFT).'&year='.$tmpforcreatebutton['year']; //$param='month='.$monthshown.'&year='.$year; $hourminsec = '100000'; @@ -723,12 +739,22 @@ if (!empty($arrayfields['a.note']['checked'])) { } if (!empty($arrayfields['a.datep']['checked'])) { print ''; - print $form->selectDate($datestart, 'datestart', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzuserrel'); + print '
    '; + print $form->selectDate($datestart_dtstart, 'datestart_dtstart', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'), 'tzuserrel'); + print '
    '; + print '
    '; + print $form->selectDate($datestart_dtend, 'datestart_dtend', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('To'), 'tzuserrel'); + print '
    '; print ''; } if (!empty($arrayfields['a.datep2']['checked'])) { print ''; - print $form->selectDate($dateend, 'dateend', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzuserrel'); + print '
    '; + print $form->selectDate($dateend_dtstart, 'dateend_dtstart', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From'), 'tzuserrel'); + print '
    '; + print '
    '; + print $form->selectDate($dateend_dtend, 'dateend_dtend', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('To'), 'tzuserrel'); + print '
    '; print ''; } if (!empty($arrayfields['s.nom']['checked'])) { diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index b1fecbf6475..6b5c262fe6a 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -80,13 +80,13 @@ if ($socid < 0) { } $canedit = 1; -if (!$user->rights->agenda->myactions->read) { +if (empty($user->rights->agenda->myactions->read)) { accessforbidden(); } -if (!$user->rights->agenda->allactions->read) { +if (empty($user->rights->agenda->allactions->read)) { $canedit = 0; } -if (!$user->rights->agenda->allactions->read || $filter == 'mine') { // If no permission to see all, we show only affected to me +if (empty($user->rights->agenda->allactions->read) || $filter == 'mine') { // If no permission to see all, we show only affected to me $filtert = $user->id; } @@ -377,7 +377,6 @@ if ($conf->use_javascript_ajax) { $s .= 'jQuery(".family_birthday").toggle();'."\n"; if ($action == "show_week" || $action == "show_month" || empty($action)) { $s .= 'jQuery( "td.sortable" ).sortable({connectWith: ".sortable",placeholder: "ui-state-highlight",items: "div:not(.unsortable)", receive: function( event, ui ) {'; - $s .= 'var frm=jQuery("#move_event");frm.attr("action",ui.item.find("a.cal_event").attr("href")).children("#newdate").val(jQuery(event.target).closest("div").attr("id"));frm.submit();}});'."\n"; } $s .= '});'."\n"; $s .= ''."\n"; @@ -416,7 +415,7 @@ $massactionbutton = ''; $viewmode = ''; $viewmode .= '
    '; //$viewmode .= ''; -$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="pictoactionview block"'); +$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="imgforviewmode pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; @@ -506,7 +505,7 @@ $sql .= ' a.transparency, a.priority, a.fulldayevent, a.location,'; $sql .= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype, a.fk_project,'; $sql .= ' ca.code, ca.libelle as type_label, ca.color, ca.type as type_type, ca.picto as type_picto'; $sql .= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; } // We must filter on resource table @@ -557,7 +556,7 @@ if ($resourceid > 0) { if ($pid) { $sql .= " AND a.fk_project=".((int) $pid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")"; } if ($socid > 0) { @@ -965,8 +964,8 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s // We are in a particular day for $username, now we scan all events foreach ($eventarray as $daykey => $notused) { $annee = dol_print_date($daykey, '%Y'); - $mois = dol_print_date($daykey, '%m'); - $jour = dol_print_date($daykey, '%d'); + $mois = dol_print_date($daykey, '%m'); + $jour = dol_print_date($daykey, '%d'); if ($day == $jour && $month == $mois && $year == $annee) { // Is it the day we are looking for when calling function ? // Scan all event for this date diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index dbda8f0ae46..de9c979c0fb 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -80,13 +80,13 @@ if ($socid < 0) { } $canedit = 1; -if (!$user->rights->agenda->myactions->read) { +if (empty($user->rights->agenda->myactions->read)) { accessforbidden(); } -if (!$user->rights->agenda->allactions->read) { +if (empty($user->rights->agenda->allactions->read)) { $canedit = 0; } -if (!$user->rights->agenda->allactions->read || $filter == 'mine') { // If no permission to see all, we show only affected to me +if (empty($user->rights->agenda->allactions->read) || $filter == 'mine') { // If no permission to see all, we show only affected to me $filtert = $user->id; } @@ -387,7 +387,6 @@ if ($conf->use_javascript_ajax) { $s .= 'jQuery(".family_birthday").toggle();'."\n"; if ($action == "show_week" || $action == "show_month" || empty($action)) { $s .= 'jQuery( "td.sortable" ).sortable({connectWith: ".sortable",placeholder: "ui-state-highlight",items: "div:not(.unsortable)", receive: function( event, ui ) {'; - $s .= 'var frm=jQuery("#move_event");frm.attr("action",ui.item.find("a.cal_event").attr("href")).children("#newdate").val(jQuery(event.target).closest("div").attr("id"));frm.submit();}});'."\n"; } $s .= '});'."\n"; $s .= ''."\n"; @@ -426,7 +425,7 @@ $massactionbutton = ''; $viewmode = ''; $viewmode .= ''; //$viewmode .= ''; -$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="pictoactionview block"'); +$viewmode .= img_picto($langs->trans("List"), 'object_list', 'class="imgforviewmode pictoactionview block"'); //$viewmode .= ''; $viewmode .= ''.$langs->trans("ViewList").''; @@ -533,7 +532,7 @@ $sql .= ' a.transparency, a.priority, a.fulldayevent, a.location,'; $sql .= ' a.fk_soc, a.fk_contact, a.fk_element, a.elementtype, a.fk_project,'; $sql .= ' ca.code, ca.libelle as type_label, ca.color, ca.type as type_type, ca.picto as type_picto'; $sql .= ' FROM '.MAIN_DB_PREFIX.'c_actioncomm as ca, '.MAIN_DB_PREFIX."actioncomm as a"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; } // We must filter on resource table @@ -584,7 +583,7 @@ if ($resourceid > 0) { if ($pid) { $sql .= " AND a.fk_project = ".((int) $pid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")"; } if ($socid > 0) { @@ -802,7 +801,7 @@ $currentdaytoshow = $firstdaytoshow; echo '
    '; while ($currentdaytoshow < $lastdaytoshow) { - echo ''; + echo '
    '; echo ''; echo ''; $name = "actions-".$obj->month."-".$obj->year.".pdf"; diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index f891bf722cc..aaab987fd9c 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -351,7 +351,7 @@ if ($object->id > 0) { print showValueWithClipboardCPButton(dol_escape_htmltag($object->code_client)); $tmpcheck = $object->check_codeclient(); if ($tmpcheck != 0 && $tmpcheck != -5) { - print ' ('.$langs->trans("WrongCustomerCode").')'; + print ' ('.$langs->trans("WrongCustomerCode").')'; } print ''; @@ -406,7 +406,7 @@ if ($object->id > 0) { print $langs->trans('PaymentConditions'); print ''; + print ''; } print '
    '; @@ -829,7 +828,7 @@ while ($currentdaytoshow < $lastdaytoshow) { // Filter on days print img_picto('', 'clock', 'class="fawidth30 inline-block paddingleft"'); print ''.$langs->trans("DaysOfWeek").''; - print "\n".'
    '; + print "\n".'
    '; print ''; if (empty($conf->dol_use_jmobile)) { print ' - '; @@ -898,15 +897,23 @@ while ($currentdaytoshow < $lastdaytoshow) { } } else { /* Use this list to have for all users */ - $sql = "SELECT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity"; + $sql = "SELECT DISTINCT u.rowid, u.lastname as lastname, u.firstname, u.statut, u.login, u.admin, u.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."user as u"; - if ($usergroup > 0) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ug ON u.rowid = ug.fk_user"; + if (!empty($conf->multicompany->enabled) && !empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE)) { + $sql .= ", ".MAIN_DB_PREFIX."usergroup_user as ug"; + $sql .= " WHERE ug.entity IN (".getEntity('usergroup').")"; + $sql .= " AND ug.fk_user = u.rowid "; + } else { + if ($usergroup > 0) { + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ug ON u.rowid = ug.fk_user"; + } + $sql .= " WHERE u.entity IN (".getEntity('user').")"; } - $sql .= " WHERE u.statut = 1 AND u.entity IN (".getEntity('user').")"; - if ($usergroup > 0) { + $sql .= " AND u.statut = 1"; + if ($usergroup > 0) { $sql .= " AND ug.fk_usergroup = ".((int) $usergroup); } + //print $sql; $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/comm/action/rapport/index.php b/htdocs/comm/action/rapport/index.php index 9b6238ca0de..b75c93df799 100644 --- a/htdocs/comm/action/rapport/index.php +++ b/htdocs/comm/action/rapport/index.php @@ -163,7 +163,7 @@ if ($resql) { // Button to build doc print '
    '; - print 'month.'&year='.$obj->year.'">'.img_picto($langs->trans('BuildDoc'), 'filenew').''; + print ''.img_picto($langs->trans('BuildDoc'), 'filenew').''; print '
    '; if (($action != 'editconditions') && $user->rights->societe->creer) { - print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).'id.'">'.img_edit($langs->trans('SetConditions'), 1).'
    '; print ''; @@ -424,7 +424,7 @@ if ($object->id > 0) { print $langs->trans('PaymentMode'); print ''; if (($action != 'editmode') && $user->rights->societe->creer) { - print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; } print ''; print ''; @@ -443,7 +443,7 @@ if ($object->id > 0) { print $langs->trans('PaymentBankAccount'); print ''; if (($action != 'editbankaccount') && $user->rights->societe->creer) { - print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; } print ''; print ''; @@ -569,7 +569,7 @@ if ($object->id > 0) { print $langs->trans('SendingMethod'); print ''; if (($action != 'editshipping') && $user->rights->societe->creer) { - print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; } print ''; print ''; @@ -589,7 +589,7 @@ if ($object->id > 0) { print $langs->trans('IntracommReportTransportMode'); print ''; if (($action != 'edittransportmode') && $user->rights->societe->creer) { - print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; } print ''; print ''; @@ -652,7 +652,7 @@ if ($object->id > 0) { print $langs->trans('ProspectLevel'); print ''; if ($action != 'editlevel' && $user->rights->societe->creer) { - print 'id.'">'.img_edit($langs->trans('Modify'), 1).''; + print 'id.'">'.img_edit($langs->trans('Modify'), 1).''; } print ''; print ''; @@ -682,7 +682,7 @@ if ($object->id > 0) { print ""; } - print '
    '; + print '
    '; print '
    '; $boxstat = ''; @@ -1341,7 +1341,7 @@ if ($object->id > 0) { print $hookmanager->resPrint; } - print '
    '; + print ''; print '
    '; print dol_get_fiche_end(); diff --git a/htdocs/comm/contact.php b/htdocs/comm/contact.php index 52f6e675c5f..57a88bef157 100644 --- a/htdocs/comm/contact.php +++ b/htdocs/comm/contact.php @@ -82,14 +82,14 @@ if ($type == "f") { $sql = "SELECT s.rowid, s.nom as name, st.libelle as stcomm"; $sql .= ", p.rowid as cidp, p.name, p.firstname, p.email, p.phone"; $sql .= " FROM ".MAIN_DB_PREFIX."c_stcomm as st,"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " ".MAIN_DB_PREFIX."societe_commerciaux as sc,"; } $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').")"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($type == "c") { diff --git a/htdocs/comm/index.php b/htdocs/comm/index.php index 2603b520c77..aad02f2bd07 100644 --- a/htdocs/comm/index.php +++ b/htdocs/comm/index.php @@ -129,13 +129,13 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($propalstatic->element).")"; $sql .= " AND p.fk_soc = s.rowid"; $sql .= " AND p.fk_statut = ".Propal::STATUS_DRAFT; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -226,13 +226,13 @@ if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposa $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($supplierproposalstatic->element).")"; $sql .= " AND p.fk_statut = ".SupplierProposal::STATUS_DRAFT; $sql .= " AND p.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -322,13 +322,13 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity($orderstatic->element).")"; $sql .= " AND c.fk_statut = ".Commande::STATUS_DRAFT; $sql .= " AND c.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -419,13 +419,13 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as cf,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE cf.entity IN (".getEntity($supplierorderstatic->element).")"; $sql .= " AND cf.fk_statut = ".CommandeFournisseur::STATUS_DRAFT; $sql .= " AND cf.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -511,7 +511,7 @@ if (!empty($conf->ficheinter->enabled)) { $sql = "SELECT f.rowid, f.ref, s.nom as name, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.entity IN (".getEntity('intervention').")"; @@ -520,7 +520,7 @@ if (!empty($conf->ficheinter->enabled)) { if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -548,7 +548,6 @@ if (!empty($conf->ficheinter->enabled)) { } print '
    '; -print '
    '; /* * Last modified customers or prospects @@ -561,12 +560,12 @@ if (!empty($conf->societe->enabled) && $user->rights->societe->lire) { $sql .= ", s.canvas"; $sql .= ", s.datec, s.tms"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.entity IN (".getEntity($companystatic->element).")"; $sql .= " AND s.client IN (".Societe::CUSTOMER.", ".Societe::PROSPECT.", ".Societe::CUSTOMER_AND_PROSPECT.")"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -657,12 +656,12 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S $sql .= ", s.canvas"; $sql .= ", s.datec as dc, s.tms as dm"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.entity IN (".getEntity($companystatic->element).")"; $sql .= " AND s.fournisseur = ".Societe::SUPPLIER; - if (!$user->rights->societe->client->voir && !$user->socid) { + 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) { @@ -762,13 +761,13 @@ if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire && 0) { // T $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."contrat as c"; $sql .= ", ".MAIN_DB_PREFIX."product as p"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity($staticcontrat->element).")"; $sql .= " AND c.fk_soc = s.rowid"; $sql .= " AND c.fk_product = p.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -837,13 +836,13 @@ if (!empty($conf->propal->enabled) && $user->rights->propal->lire) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($propalstatic->element).")"; $sql .= " AND p.fk_soc = s.rowid"; $sql .= " AND p.fk_statut = ".Propal::STATUS_VALIDATED; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -953,13 +952,13 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity($orderstatic->element).")"; $sql .= " AND c.fk_soc = s.rowid"; $sql .= " AND c.fk_statut IN (".Commande::STATUS_VALIDATED.", ".Commande::STATUS_SHIPMENTONPROCESS.")"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -1057,7 +1056,6 @@ if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { } } -print '
    '; print '
    '; print ''; diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index 8b97f23737e..1ba96690f2a 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -726,7 +726,7 @@ if ($action == 'create') { $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, 'edit'); + print $object->showOptionals($extrafields, 'create'); } print ''; @@ -749,7 +749,7 @@ if ($action == 'create') { print dol_get_fiche_end(); - print '
    '; + print $form->buttonsSaveCancel("CreateMailing", ''); print ''; } else { @@ -912,7 +912,7 @@ if ($action == 'create') { } } if (empty($nbemail)) { - $nbemail .= ' '.img_warning('').' '.$langs->trans("NoTargetYet").''; + $nbemail .= ' '.img_warning('').' '.$langs->trans("NoTargetYet").''; } if ($text) { print $form->textwithpicto($nbemail, $text, 1, 'warning'); @@ -952,18 +952,18 @@ if ($action == 'create') { print "\n\n
    \n"; if (($object->statut == 1) && ($user->rights->mailing->valider || $object->fk_user_valid == $user->id)) { - print ''.$langs->trans("SetToDraft").''; + print ''.$langs->trans("SetToDraft").''; } if (($object->statut == 0 || $object->statut == 1 || $object->statut == 2) && $user->rights->mailing->creer) { if (!empty($conf->fckeditor->enabled) && !empty($conf->global->FCKEDITOR_ENABLE_MAILING)) { - print ''.$langs->trans("EditWithEditor").''; + print ''.$langs->trans("EditWithEditor").''; } else { - print ''.$langs->trans("EditWithTextEditor").''; + print ''.$langs->trans("EditWithTextEditor").''; } if (!empty($conf->use_javascript_ajax)) { - print ''.$langs->trans("EditHTMLSource").''; + print ''.$langs->trans("EditHTMLSource").''; } } @@ -972,7 +972,7 @@ if ($action == 'create') { if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !$user->rights->mailing->mailing_advance->send) { print ''.$langs->trans("TestMailing").''; } else { - print ''.$langs->trans("TestMailing").''; + print ''.$langs->trans("TestMailing").''; } if ($object->statut == 0) { @@ -1011,7 +1011,7 @@ if ($action == 'create') { if ($object->statut > 0 && (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !$user->rights->mailing->mailing_advance->delete)) { print ''.$langs->trans("DeleteMailing").''; } else { - print ''.$langs->trans("DeleteMailing").''; + print ''.$langs->trans("DeleteMailing").''; } } @@ -1161,7 +1161,7 @@ if ($action == 'create') { } } if (empty($nbemail)) { - $nbemail .= ' '.img_warning('').' '.$langs->trans("NoTargetYet").''; + $nbemail .= ' '.img_warning('').' '.$langs->trans("NoTargetYet").''; } if ($text) { print $form->textwithpicto($nbemail, $text, 1, 'warning'); diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index 97c6735221f..340ac1dfc8c 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -284,7 +284,7 @@ if ($object->fetch($id) >= 0) { } } if (empty($nbemail)) { - $nbemail .= ' '.img_warning('').' '.$langs->trans("NoTargetYet").''; + $nbemail .= ' '.img_warning('').' '.$langs->trans("NoTargetYet").''; } if ($text) { print $form->textwithpicto($nbemail, $text, 1, 'warning'); @@ -378,7 +378,7 @@ if ($object->fetch($id) >= 0) { $var = !$var; if ($allowaddtarget) { - print '
    '; + print ''; print ''; } else { print '
    '; @@ -424,7 +424,7 @@ if ($object->fetch($id) >= 0) { print '
    '; if ($allowaddtarget) { - print ''; + print ''; } else { print ''; //print $langs->trans("MailNoChangePossible"); diff --git a/htdocs/comm/mailing/class/mailing.class.php b/htdocs/comm/mailing/class/mailing.class.php index 2f9ef25af31..cb900f7ac7b 100644 --- a/htdocs/comm/mailing/class/mailing.class.php +++ b/htdocs/comm/mailing/class/mailing.class.php @@ -776,8 +776,8 @@ class Mailing extends CommonObject global $langs; $langs->load("mailing"); - $labelStatus = $langs->trans($this->statuts[$status]); - $labelStatusShort = $langs->trans($this->statuts[$status]); + $labelStatus = $langs->transnoentitiesnoconv($this->statuts[$status]); + $labelStatusShort = $langs->transnoentitiesnoconv($this->statuts[$status]); $statusType = 'status'.$status; if ($status == 2) { @@ -808,16 +808,16 @@ class Mailing extends CommonObject $labelStatus = array(); $labelStatusShort = array(); - $labelStatus[-1] = $langs->trans('MailingStatusError'); - $labelStatus[0] = $langs->trans('MailingStatusNotSent'); - $labelStatus[1] = $langs->trans('MailingStatusSent'); - $labelStatus[2] = $langs->trans('MailingStatusRead'); - $labelStatus[3] = $langs->trans('MailingStatusNotContact'); - $labelStatusShort[-1] = $langs->trans('MailingStatusError'); - $labelStatusShort[0] = $langs->trans('MailingStatusNotSent'); - $labelStatusShort[1] = $langs->trans('MailingStatusSent'); - $labelStatusShort[2] = $langs->trans('MailingStatusRead'); - $labelStatusShort[3] = $langs->trans('MailingStatusNotContact'); + $labelStatus[-1] = $langs->transnoentitiesnoconv('MailingStatusError'); + $labelStatus[0] = $langs->transnoentitiesnoconv('MailingStatusNotSent'); + $labelStatus[1] = $langs->transnoentitiesnoconv('MailingStatusSent'); + $labelStatus[2] = $langs->transnoentitiesnoconv('MailingStatusRead'); + $labelStatus[3] = $langs->transnoentitiesnoconv('MailingStatusNotContact'); + $labelStatusShort[-1] = $langs->transnoentitiesnoconv('MailingStatusError'); + $labelStatusShort[0] = $langs->transnoentitiesnoconv('MailingStatusNotSent'); + $labelStatusShort[1] = $langs->transnoentitiesnoconv('MailingStatusSent'); + $labelStatusShort[2] = $langs->transnoentitiesnoconv('MailingStatusRead'); + $labelStatusShort[3] = $langs->transnoentitiesnoconv('MailingStatusNotContact'); $statusType = 'status'.$status; if ($status == -1) { diff --git a/htdocs/comm/mailing/index.php b/htdocs/comm/mailing/index.php index 01abc1e5ef1..bd1a83e9959 100644 --- a/htdocs/comm/mailing/index.php +++ b/htdocs/comm/mailing/index.php @@ -141,8 +141,7 @@ if (is_resource($handle)) { print "
    "; -//print ''; -print '
    '; +print '
    '; /* @@ -184,7 +183,7 @@ if ($result) { $i++; } } else { - print ''.$langs->trans("None").''; + print ''.$langs->trans("None").''; } print "

    "; $db->free($result); @@ -193,7 +192,7 @@ if ($result) { } -print '
    '; +print ''; $parameters = array('user' => $user); diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 656d370d6d5..896448d7b9a 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1559,8 +1559,6 @@ if ($action == 'create') { } } - $object = new Propal($db); - print ''; print ''; print ''; @@ -1974,6 +1972,21 @@ if ($action == 'create') { $text .= $notify->confirmMessage('PROPAL_VALIDATE', $object->socid, $object); } + // mandatoryPeriod + $nbMandated = 0; + foreach ($object->lines as $line) { + $res = $line->fetch_product(); + if ($res > 0 ) { + if ($line->product->isService() && $line->product->isMandatoryPeriod() && (empty($line->date_start) || empty($line->date_end) )) { + $nbMandated++; + break; + } + } + } + if ($nbMandated > 0) { + $text .= '
    '.$langs->trans("mandatoryPeriodNeedTobeSetMsgValidate").'
    '; + } + if (!$error) { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateProp'), $text, 'confirm_validate', '', 0, 1); } @@ -2001,17 +2014,17 @@ if ($action == 'create') { $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', 0, 1); $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $usercancreate, 'string', '', null, null, '', 1); // Thirdparty - $morehtmlref .= '
    '.$langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1, 'customer'); + $morehtmlref .= '
    '.$langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1, 'customer'); if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) { $morehtmlref .= ' ('.$langs->trans("OtherProposals").')'; } // Project if (!empty($conf->projet->enabled)) { $langs->load("projects"); - $morehtmlref .= '
    '.$langs->trans('Project').' '; + $morehtmlref .= '
    '.$langs->trans('Project').''; if ($usercancreate) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -2028,9 +2041,10 @@ if ($action == 'create') { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ': '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -2064,6 +2078,8 @@ if ($action == 'create') { $absolute_discount = price2num($absolute_discount, 'MT'); $absolute_creditnote = price2num($absolute_creditnote, 'MT'); + $caneditfield = ($object->statut != Propal::STATUS_SIGNED && $object->statut != Propal::STATUS_BILLED); + $thirdparty = $soc; $discount_type = 0; $backtopage = urlencode($_SERVER["PHP_SELF"].'?id='.$object->id); @@ -2077,12 +2093,12 @@ if ($action == 'create') { print ''; - if ($action != 'editdate' && $object->statut == Propal::STATUS_DRAFT && $usercancreate) { - print ''; + if ($action != 'editdate' && $usercancreate && $caneditfield) { + print ''; } print '
    '; print $langs->trans('DatePropal'); print 'id.'">'.img_edit($langs->trans('SetDate'), 1).'id.'">'.img_edit($langs->trans('SetDate'), 1).'
    '; print ''; - if ($object->statut == Propal::STATUS_DRAFT && $action == 'editdate' && $usercancreate) { + if ($action == 'editdate' && $usercancreate && $caneditfield) { print ''; print ''; print ''; @@ -2104,12 +2120,12 @@ if ($action == 'create') { print ''; - if ($action != 'editecheance' && $object->statut == Propal::STATUS_DRAFT && $usercancreate) { - print ''; + if ($action != 'editecheance' && $usercancreate && $caneditfield) { + print ''; } print '
    '; print $langs->trans('DateEndPropal'); print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).'id.'">'.img_edit($langs->trans('SetConditions'), 1).'
    '; print ''; - if ($object->statut == Propal::STATUS_DRAFT && $action == 'editecheance' && $usercancreate) { + if ($action == 'editecheance' && $usercancreate && $caneditfield) { print ''; print ''; print ''; @@ -2134,12 +2150,12 @@ if ($action == 'create') { print ''; - if ($action != 'editconditions' && $object->statut == Propal::STATUS_DRAFT && $usercancreate) { - print ''; + if ($action != 'editconditions' && $usercancreate && $caneditfield) { + print ''; } print '
    '; print $langs->trans('PaymentConditionsShort'); print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetConditions'), 1).'id.'">'.img_edit($langs->transnoentitiesnoconv('SetConditions'), 1).'
    '; print ''; - if ($object->statut == Propal::STATUS_DRAFT && $action == 'editconditions' && $usercancreate) { + if ($action == 'editconditions' && $usercancreate && $caneditfield) { $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'cond_reglement_id'); } else { $form->form_conditions_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->cond_reglement_id, 'none'); @@ -2153,12 +2169,12 @@ if ($action == 'create') { print ''; - if ($action != 'editmode' && $object->statut == Propal::STATUS_DRAFT && $usercancreate) { - print ''; + if ($action != 'editmode' && $usercancreate && $caneditfield) { + print ''; } print '
    '; print $langs->trans('PaymentMode'); print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMode'), 1).'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMode'), 1).'
    '; print ''; - if ($object->statut == Propal::STATUS_DRAFT && $action == 'editmode' && $usercancreate) { + if ($action == 'editmode' && $usercancreate && $caneditfield) { $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'mode_reglement_id', 'CRDT', 1, 1); } else { $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id, 'none'); @@ -2168,26 +2184,27 @@ if ($action == 'create') { // Delivery date $langs->load('deliveries'); print ''; - print $form->editfieldkey($langs->trans('DeliveryDate'), 'date_livraison', $object->delivery_date, $object, $usercancreate, 'datepicker'); + print $form->editfieldkey($langs->trans('DeliveryDate'), 'date_livraison', $object->delivery_date, $object, $usercancreate && $caneditfield, 'datepicker'); print ''; - print $form->editfieldval($langs->trans('DeliveryDate'), 'date_livraison', $object->delivery_date, $object, $usercancreate, 'datepicker'); + print $form->editfieldval($langs->trans('DeliveryDate'), 'date_livraison', $object->delivery_date, $object, $usercancreate && $caneditfield, 'datepicker'); print ''; print ''; // Delivery delay print ''; print ''; - if ($action != 'editavailability' && $object->statut == Propal::STATUS_DRAFT && $usercancreate) { - print ''; + if ($action != 'editavailability' && $usercancreate && $caneditfield) { + print ''; } print '
    '; - print $langs->trans('AvailabilityPeriod'); if (!empty($conf->commande->enabled)) { - print ' ('.$langs->trans('AfterOrder').')'; + print $form->textwithpicto($langs->trans('AvailabilityPeriod'), $langs->trans('AvailabilityPeriod').' ('.$langs->trans('AfterOrder').')'); + } else { + print $langs->trans('AvailabilityPeriod'); } print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetAvailability'), 1).'id.'">'.img_edit($langs->transnoentitiesnoconv('SetAvailability'), 1).'
    '; print ''; - if ($object->statut == Propal::STATUS_DRAFT && $action == 'editavailability' && $usercancreate) { + if ($action == 'editavailability' && $usercancreate && $caneditfield) { $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'availability_id', 1); } else { $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'none', 1); @@ -2202,12 +2219,12 @@ if ($action == 'create') { print ''; - if ($action != 'editshippingmethod' && $usercancreate) { - print ''; + if ($action != 'editshippingmethod' && $usercancreate && $caneditfield) { + print ''; } print '
    '; print $langs->trans('SendingMethod'); print 'id.'">'.img_edit($langs->trans('SetShippingMode'), 1).'id.'">'.img_edit($langs->trans('SetShippingMode'), 1).'
    '; print ''; - if ($action == 'editshippingmethod' && $usercancreate) { + if ($action == 'editshippingmethod' && $usercancreate && $caneditfield) { $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'shipping_method_id', 1); } else { $form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?id='.$object->id, $object->shipping_method_id, 'none'); @@ -2239,12 +2256,12 @@ if ($action == 'create') { print ''; - if ($action != 'editdemandreason' && $object->statut == Propal::STATUS_DRAFT && $usercancreate) { - print ''; + if ($action != 'editdemandreason' && $usercancreate) { + print ''; } print '
    '; print $langs->trans('Source'); print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetDemandReason'), 1).'id.'">'.img_edit($langs->transnoentitiesnoconv('SetDemandReason'), 1).'
    '; print ''; - if ($object->statut == Propal::STATUS_DRAFT && $action == 'editdemandreason' && $usercancreate) { + if ($action == 'editdemandreason' && $usercancreate) { $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'demand_reason_id', 1); } else { $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'none'); @@ -2261,7 +2278,7 @@ if ($action == 'create') { print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0); print ''; if ($action != 'editmulticurrencycode' && $object->statut == $object::STATUS_DRAFT && $usercancreate) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -2281,7 +2298,7 @@ if ($action == 'create') { print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0); print ''; if ($action != 'editmulticurrencyrate' && $object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency && $usercancreate) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -2322,7 +2339,7 @@ if ($action == 'create') { print $langs->trans('BankAccount'); print ''; if ($action != 'editbankaccount' && $usercancreate) { - print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; } print ''; print ''; @@ -2341,13 +2358,13 @@ if ($action == 'create') { if ($totalWeight) { print ''.$langs->trans("CalculatedWeight").''; print ''; - print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, isset($conf->global->MAIN_WEIGHT_DEFAULT_ROUND) ? $conf->global->MAIN_WEIGHT_DEFAULT_ROUND : -1, isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT) ? $conf->global->MAIN_WEIGHT_DEFAULT_UNIT : 'no'); + print showDimensionInBestUnit($totalWeight, 0, "weight", $langs, isset($conf->global->MAIN_WEIGHT_DEFAULT_ROUND) ? $conf->global->MAIN_WEIGHT_DEFAULT_ROUND : -1, isset($conf->global->MAIN_WEIGHT_DEFAULT_UNIT) ? $conf->global->MAIN_WEIGHT_DEFAULT_UNIT : 'no', 0); print ''; } if ($totalVolume) { print ''.$langs->trans("CalculatedVolume").''; print ''; - print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND) ? $conf->global->MAIN_VOLUME_DEFAULT_ROUND : -1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT) ? $conf->global->MAIN_VOLUME_DEFAULT_UNIT : 'no'); + print showDimensionInBestUnit($totalVolume, 0, "volume", $langs, isset($conf->global->MAIN_VOLUME_DEFAULT_ROUND) ? $conf->global->MAIN_VOLUME_DEFAULT_ROUND : -1, isset($conf->global->MAIN_VOLUME_DEFAULT_UNIT) ? $conf->global->MAIN_VOLUME_DEFAULT_UNIT : 'no', 0); print ''; } @@ -2357,18 +2374,18 @@ if ($action == 'create') { print '
    '; print $langs->trans('IncotermLabel'); print ''; - if ($usercancreate) { - print ''.img_edit().''; + if ($action != 'editincoterm' && $usercancreate && $caneditfield) { + print ''.img_edit().''; } else { print ' '; } print '
    '; print ''; print ''; - if ($action != 'editincoterm') { - print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1); - } else { + if ($action == 'editincoterm' && $usercancreate && $caneditfield) { print $form->select_incoterms((!empty($object->fk_incoterms) ? $object->fk_incoterms : ''), (!empty($object->location_incoterms) ? $object->location_incoterms : ''), $_SERVER['PHP_SELF'].'?id='.$object->id); + } else { + print $form->textwithpicto($object->display_incoterms(), $object->label_incoterms, 1); } print ''; } @@ -2380,7 +2397,6 @@ if ($action == 'create') { print ''; print '
    '; - print '
    '; print '
    '; print ''; @@ -2439,7 +2455,6 @@ if ($action == 'create') { $formmargin->displayMarginInfos($object); } - print ''; print ''; print ''; @@ -2544,7 +2559,7 @@ if ($action == 'create') { // ReOpen if ( (( ! empty($conf->global->PROPAL_REOPEN_UNSIGNED_ONLY) && $object->statut == Propal::STATUS_NOTSIGNED) || (empty($conf->global->PROPAL_REOPEN_UNSIGNED_ONLY) && ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED))) && $usercanclose) { - print 'global->MAIN_JUMP_TAG) ? '' : '#reopen').'"'; + print 'global->MAIN_JUMP_TAG) ? '' : '#reopen').'"'; print '>'.$langs->trans('ReOpen').''; } @@ -2552,7 +2567,7 @@ if ($action == 'create') { if (empty($user->socid)) { if ($object->statut == Propal::STATUS_VALIDATED || $object->statut == Propal::STATUS_SIGNED || !empty($conf->global->PROPOSAL_SENDBYEMAIL_FOR_ALL_STATUS)) { if ($usercansend) { - print ''.$langs->trans('SendMail').''; + print ''.$langs->trans('SendMail').''; } else { print ''.$langs->trans('SendMail').''; } @@ -2595,13 +2610,13 @@ if ($action == 'create') { // Create an invoice and classify billed if ($object->statut == Propal::STATUS_SIGNED && empty($conf->global->PROPOSAL_ARE_NOT_BILLABLE)) { if (!empty($conf->facture->enabled) && $usercancreateinvoice) { - print ''.$langs->trans("AddBill").''; + print ''.$langs->trans("CreateBill").''; } $arrayofinvoiceforpropal = $object->getInvoiceArrayList(); if ((is_array($arrayofinvoiceforpropal) && count($arrayofinvoiceforpropal) > 0) || empty($conf->global->WORKFLOW_PROPAL_NEED_INVOICE_TO_BE_CLASSIFIED_BILLED)) { if ($usercanclose) { - print 'socid.'">'.$langs->trans("ClassifyBilled").''; + print 'socid.'">'.$langs->trans("ClassifyBilled").''; } else { print ''.$langs->trans("ClassifyBilled").''; } @@ -2611,7 +2626,7 @@ if ($action == 'create') { // Close as accepted/refused if ($object->statut == Propal::STATUS_VALIDATED) { if ($usercanclose) { - print 'global->MAIN_JUMP_TAG) ? '' : '#close').'"'; + print 'global->MAIN_JUMP_TAG) ? '' : '#close').'"'; print '>'.$langs->trans('SetAcceptedRefused').''; } else { print ''.$langs->trans("ToClone").''; + print ''.$langs->trans("ToClone").''; } // Delete if ($usercandelete) { - print ''.$langs->trans('Delete').''; } } @@ -2664,7 +2679,7 @@ if ($action == 'create') { $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, $compatibleImportElementsList); // Show online signature link - $useonlinesignature = $conf->global->MAIN_FEATURES_LEVEL; // Replace this with 1 when feature to make online signature is ok + $useonlinesignature = 1; // Replace this with 1 when feature to make online signature is ok if ($object->statut != Propal::STATUS_DRAFT && $useonlinesignature) { print '
    '; @@ -2672,14 +2687,14 @@ if ($action == 'create') { print showOnlineSignatureUrl('proposal', $object->ref).'
    '; } - print '
    '; + print '
    '; // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'propal', $socid, 1); - print '
    '; + print ''; } // Presend form diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index a7b5c465226..2f055f54a42 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2563,8 +2563,13 @@ class Propal extends CommonObject $outputlangs->setDefaultLang($newlang); } + // PDF + $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0); + $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0); + $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0); + //$ret=$object->fetch($id); // Reload to get new records - $this->generateDocument($modelpdf, $outputlangs); + $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } if (!$error) { @@ -2651,8 +2656,13 @@ class Propal extends CommonObject $outputlangs->setDefaultLang($newlang); } + // PDF + $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0); + $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0); + $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0); + //$ret=$object->fetch($id); // Reload to get new records - $this->generateDocument($modelpdf, $outputlangs); + $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } $this->oldcopy = clone $this; @@ -2769,17 +2779,17 @@ class Propal extends CommonObject $sql = "SELECT s.rowid, s.nom as name, s.client,"; $sql .= " p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, "; $sql .= " p.datep as dp, p.fin_validite as datelimite"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user"; } $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."propal as p, ".MAIN_DB_PREFIX."c_propalst as c"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity('propal').")"; $sql .= " AND p.fk_soc = s.rowid"; $sql .= " AND p.fk_statut = c.id"; - if (!$user->rights->societe->client->voir && !$socid) { //restriction + if (empty($user->rights->societe->client->voir) && !$socid) { //restriction $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -3283,7 +3293,7 @@ class Propal extends CommonObject $sql = "SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = " AND"; @@ -3460,7 +3470,7 @@ class Propal extends CommonObject $sql = "SELECT count(p.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/comm/propal/class/propalestats.class.php b/htdocs/comm/propal/class/propalestats.class.php index 181e5b545f8..2b8c5d9047d 100644 --- a/htdocs/comm/propal/class/propalestats.class.php +++ b/htdocs/comm/propal/class/propalestats.class.php @@ -93,7 +93,7 @@ class PropaleStats extends Stats } //$this->where.= " AND p.fk_soc = s.rowid AND p.entity = ".$conf->entity; $this->where .= ($this->where ? ' AND ' : '')."p.entity IN (".getEntity('propal').")"; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $this->where .= " AND p.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($this->socid) { @@ -129,7 +129,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -154,7 +154,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -178,7 +178,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, SUM(p.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -203,7 +203,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%m') as dm, AVG(p.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -226,7 +226,7 @@ class PropaleStats extends Stats $sql = "SELECT date_format(".$this->field_date.",'%Y') as year, COUNT(*) as nb, SUM(".$this->field.") as total, AVG(".$this->field.") as avg"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -252,7 +252,7 @@ class PropaleStats extends Stats $sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg"; $sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; diff --git a/htdocs/comm/propal/contact.php b/htdocs/comm/propal/contact.php index 61a14ab62d8..fedf6a6233d 100644 --- a/htdocs/comm/propal/contact.php +++ b/htdocs/comm/propal/contact.php @@ -148,7 +148,7 @@ if ($object->id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->propal->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -166,9 +166,10 @@ if ($object->id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/comm/propal/document.php b/htdocs/comm/propal/document.php index a60f892274c..1135dfcf0c2 100644 --- a/htdocs/comm/propal/document.php +++ b/htdocs/comm/propal/document.php @@ -141,7 +141,7 @@ if ($object->id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->propal->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -159,9 +159,10 @@ if ($object->id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/comm/propal/index.php b/htdocs/comm/propal/index.php index de2e4a1d64c..e170f873961 100644 --- a/htdocs/comm/propal/index.php +++ b/htdocs/comm/propal/index.php @@ -81,13 +81,13 @@ if (!empty($conf->propal->enabled)) { $sql .= ", s.rowid as socid, s.nom as name, s.client, s.canvas, s.code_client, s.email, s.entity, s.code_compta"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($propalstatic->element).")"; $sql .= " AND p.fk_soc = s.rowid"; $sql .= " AND p.fk_statut =".Propal::STATUS_DRAFT; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -146,7 +146,6 @@ if (!empty($conf->propal->enabled)) { print ''; print '
    '; -print '
    '; /* * Last modified proposals @@ -156,7 +155,7 @@ $sql = "SELECT c.rowid, c.entity, c.ref, c.fk_statut, date_cloture as datec"; $sql .= ", s.nom as socname, s.rowid as socid, s.canvas, s.client, s.email, s.code_compta"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity($propalstatic->element).")"; @@ -165,7 +164,7 @@ $sql .= " AND c.fk_soc = s.rowid"; if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.tms DESC"; @@ -232,13 +231,13 @@ if (!empty($conf->propal->enabled) && $user->rights->propale->lire) { $sql .= ", p.rowid as propalid, p.entity, p.total_ttc, p.total_ht, p.ref, p.fk_statut, p.datep as dp, p.fin_validite as dfv"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."propal as p"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.fk_soc = s.rowid"; $sql .= " AND p.entity IN (".getEntity($propalstatic->element).")"; $sql .= " AND p.fk_statut = ".Propal::STATUS_VALIDATED; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -317,12 +316,12 @@ if (! empty($conf->propal->enabled)) $sql = "SELECT c.rowid, c.ref, c.fk_statut, s.nom as name, s.rowid as socid"; $sql.=" FROM ".MAIN_DB_PREFIX."propal as c"; $sql.= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + if (empty($user->rights->societe->client->voir) && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE c.fk_soc = s.rowid"; $sql.= " AND c.entity = ".$conf->entity; $sql.= " AND c.fk_statut = 1"; if ($socid) $sql.= " AND c.fk_soc = ".((int) $socid); - if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .((int) $user->id); + if (empty($user->rights->societe->client->voir) && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .((int) $user->id); $sql.= " ORDER BY c.rowid DESC"; $resql=$db->query($sql); @@ -392,12 +391,12 @@ if (! empty($conf->propal->enabled)) $sql = "SELECT c.rowid, c.ref, c.fk_statut, c.facture, s.nom as name, s.rowid as socid"; $sql.= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql.= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + if (empty($user->rights->societe->client->voir) && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE c.fk_soc = s.rowid"; $sql.= " AND c.entity = ".$conf->entity; $sql.= " AND c.fk_statut = 2 "; if ($socid) $sql.= " AND c.fk_soc = ".((int) $socid); - if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .((int) $user->id); + if (empty($user->rights->societe->client->voir) && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .((int) $user->id); $sql.= " ORDER BY c.rowid DESC"; $resql=$db->query($sql); @@ -456,7 +455,6 @@ if (! empty($conf->propal->enabled)) } */ -print '
    '; print '
    '; print ''; diff --git a/htdocs/comm/propal/info.php b/htdocs/comm/propal/info.php index 798dc87bcfd..dc43af9ceff 100644 --- a/htdocs/comm/propal/info.php +++ b/htdocs/comm/propal/info.php @@ -88,7 +88,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->propal->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -106,9 +106,10 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index ff8a583b0ef..1ccbd22d511 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -13,9 +13,9 @@ * Copyright (C) 2016-2021 Ferran Marcet * Copyright (C) 2017-2018 Charlene Benke * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2019 Alexandre Spangaro + * Copyright (C) 2019-2021 Alexandre Spangaro * Copyright (C) 2021 Anthony Berton - * Copyright (C) 2021 Frédéric France + * Copyright (C) 2021 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 @@ -88,12 +88,30 @@ $search_zip = GETPOST('search_zip', 'alpha'); $search_state = GETPOST("search_state"); $search_country = GETPOST("search_country", 'int'); $search_type_thirdparty = GETPOST("search_type_thirdparty", 'int'); -$search_date_start = dol_mktime(0, 0, 0, GETPOST('search_date_startmonth', 'int'), GETPOST('search_date_startday', 'int'), GETPOST('search_date_startyear', 'int')); -$search_date_end = dol_mktime(23, 59, 59, GETPOST('search_date_endmonth', 'int'), GETPOST('search_date_endday', 'int'), GETPOST('search_date_endyear', 'int')); -$search_dateend_start = dol_mktime(0, 0, 0, GETPOST('search_dateend_startmonth', 'int'), GETPOST('search_dateend_startday', 'int'), GETPOST('search_dateend_startyear', 'int')); -$search_dateend_end = dol_mktime(23, 59, 59, GETPOST('search_dateend_endmonth', 'int'), GETPOST('search_dateend_endday', 'int'), GETPOST('search_dateend_endyear', 'int')); -$search_datedelivery_start = dol_mktime(0, 0, 0, GETPOST('search_datedelivery_startmonth', 'int'), GETPOST('search_datedelivery_startday', 'int'), GETPOST('search_datedelivery_startyear', 'int')); -$search_datedelivery_end = dol_mktime(23, 59, 59, GETPOST('search_datedelivery_endmonth', 'int'), GETPOST('search_datedelivery_endday', 'int'), GETPOST('search_datedelivery_endyear', '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); +$search_date_end_startday = GETPOST('search_date_end_startday', 'int'); +$search_date_end_startmonth = GETPOST('search_date_end_startmonth', 'int'); +$search_date_end_startyear = GETPOST('search_date_end_startyear', 'int'); +$search_date_end_endday = GETPOST('search_date_end_endday', 'int'); +$search_date_end_endmonth = GETPOST('search_date_end_endmonth', 'int'); +$search_date_end_endyear = GETPOST('search_date_end_endyear', 'int'); +$search_date_end_start = dol_mktime(0, 0, 0, $search_date_end_startmonth, $search_date_end_startday, $search_date_end_startyear); // Use tzserver +$search_date_end_end = dol_mktime(23, 59, 59, $search_date_end_endmonth, $search_date_end_endday, $search_date_end_endyear); +$search_date_delivery_startday = GETPOST('search_date_delivery_startday', 'int'); +$search_date_delivery_startmonth = GETPOST('search_date_delivery_startmonth', 'int'); +$search_date_delivery_startyear = GETPOST('search_date_delivery_startyear', 'int'); +$search_date_delivery_endday = GETPOST('search_date_delivery_endday', 'int'); +$search_date_delivery_endmonth = GETPOST('search_date_delivery_endmonth', 'int'); +$search_date_delivery_endyear = GETPOST('search_date_delivery_endyear', 'int'); +$search_date_delivery_start = dol_mktime(0, 0, 0, $search_date_delivery_startmonth, $search_date_delivery_startday, $search_date_delivery_startyear); +$search_date_delivery_end = dol_mktime(23, 59, 59, $search_date_delivery_endmonth, $search_date_delivery_endday, $search_date_delivery_endyear); $search_availability = GETPOST('search_availability', 'int'); $search_categ_cus = GETPOST("search_categ_cus", 'int'); $search_fk_cond_reglement = GETPOST("search_fk_cond_reglement", 'int'); @@ -278,12 +296,30 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_type = ''; $search_country = ''; $search_type_thirdparty = ''; + $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_dateend_start = ''; - $search_dateend_end = ''; - $search_datedelivery_start = ''; - $search_datedelivery_end = ''; + $search_date_end_startday = ''; + $search_date_end_startmonth = ''; + $search_date_end_startyear = ''; + $search_date_end_endday = ''; + $search_date_end_endmonth = ''; + $search_date_end_endyear = ''; + $search_date_end_start = ''; + $search_date_end_end = ''; + $search_date_delivery_startday = ''; + $search_date_delivery_startmonth = ''; + $search_date_delivery_startyear = ''; + $search_date_delivery_endday = ''; + $search_date_delivery_endmonth = ''; + $search_date_delivery_endyear = ''; + $search_date_delivery_start = ''; + $search_date_delivery_end = ''; $search_availability = ''; $search_status = ''; $object_statut = ''; @@ -316,13 +352,14 @@ if ($action == 'validate' && $permissiontovalidate) { if ($tmpproposal->fetch($checked)) { if ($tmpproposal->statut == 0) { if ($tmpproposal->valid($user)) { - setEventMessage($tmpproposal->ref." ".$langs->trans('PassedInOpenStatus'), 'mesgs'); + setEventMessage($langs->trans('hasBeenValidated', $tmpproposal->ref), 'mesgs'); } else { setEventMessage($langs->trans('CantBeValidated'), 'errors'); $error++; } } else { - setEventMessage($tmpproposal->ref." ".$langs->trans('IsNotADraft'), 'errors'); + $langs->load("errors"); + setEventMessage($langs->trans('ErrorIsNotADraft', $tmpproposal->ref), 'errors'); $error++; } } else { @@ -471,11 +508,11 @@ $sql .= ' p.datec as date_creation, p.tms as date_update, p.date_cloture as date $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 .= " pr.rowid as project_id, pr.ref as project_ref, pr.title as project_label,"; -$sql .= ' u.login, u.lastname, u.firstname, u.email, u.statut, u.entity as user_entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender'; -if (!$user->rights->societe->client->voir && !$socid) { +$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) { $sql .= ", sc.fk_soc, sc.fk_user"; } -if ($search_categ_cus) { +if (!empty($search_categ_cus) && $search_categ_cus != '-1') { $sql .= ", cc.fk_categorie, cc.fk_soc"; } // Add fields from extrafields @@ -493,7 +530,7 @@ $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)"; -if (!empty($search_categ_cus)) { +if (!empty($search_categ_cus) && $search_categ_cus != '-1') { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_societe as cc ON s.rowid = cc.fk_soc"; // We'll need this table joined to the select in order to filter by categ } $sql .= ', '.MAIN_DB_PREFIX.'propal as p'; @@ -510,7 +547,7 @@ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON p.fk_user_author = u.rowid'; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as pr ON pr.rowid = p.fk_projet"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_availability as ava on (ava.rowid = p.fk_availability)"; // We'll need this table joined to the select in order to filter by sale -if ($search_sale > 0 || (!$user->rights->societe->client->voir && !$socid)) { +if ($search_sale > 0 || (empty($user->rights->societe->client->voir) && !$socid)) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } if ($search_user > 0) { @@ -525,7 +562,7 @@ $sql .= $hookmanager->resPrint; $sql .= ' WHERE p.fk_soc = s.rowid'; $sql .= ' AND p.entity IN ('.getEntity('propal').')'; -if (!$user->rights->societe->client->voir && !$socid) { //restriction +if (empty($user->rights->societe->client->voir) && !$socid) { //restriction $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -598,6 +635,7 @@ if ($search_multicurrency_montant_ttc != '') { if ($sall) { $sql .= natural_search(array_keys($fieldstosearchall), $sall); } + if ($search_categ_cus > 0) { $sql .= " AND cc.fk_categorie = ".((int) $search_categ_cus); } @@ -633,17 +671,17 @@ if ($search_date_start) { if ($search_date_end) { $sql .= " AND p.datep <= '".$db->idate($search_date_end)."'"; } -if ($search_dateend_start) { - $sql .= " AND p.fin_validite >= '".$db->idate($search_dateend_start)."'"; +if ($search_date_end_start) { + $sql .= " AND p.fin_validite >= '".$db->idate($search_date_end_start)."'"; } -if ($search_dateend_end) { - $sql .= " AND p.fin_validite <= '".$db->idate($search_dateend_end)."'"; +if ($search_date_end_end) { + $sql .= " AND p.fin_validite <= '".$db->idate($search_date_end_end)."'"; } -if ($search_datedelivery_start) { - $sql .= " AND p.date_livraison >= '".$db->idate($search_datedelivery_start)."'"; +if ($search_date_delivery_start) { + $sql .= " AND p.date_livraison >= '".$db->idate($search_date_delivery_start)."'"; } -if ($search_datedelivery_end) { - $sql .= " AND p.date_livraison <= '".$db->idate($search_datedelivery_end)."'"; +if ($search_date_delivery_end) { + $sql .= " AND p.date_livraison <= '".$db->idate($search_date_delivery_end)."'"; } if ($search_sale > 0) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $search_sale); @@ -718,12 +756,60 @@ if ($resql) { if ($sall) { $param .= '&sall='.urlencode($sall); } - if ($search_date_start) $param .= '&search_date_startday='.urlencode(dol_print_date($search_date_start, '%d')).'&search_date_startmonth='.urlencode(dol_print_date($search_date_start, '%m')).'&search_date_startyear='.urlencode(dol_print_date($search_date_start, '%Y')); - if ($search_date_end) $param .= '&search_date_endday='.urlencode(dol_print_date($search_date_end, '%d')).'&search_date_endmonth='.urlencode(dol_print_date($search_date_end, '%m')).'&search_date_endyear='.urlencode(dol_print_date($search_date_end, '%Y')); - if ($search_dateend_start) $param .= '&search_dateend_startday='.urlencode(dol_print_date($search_dateend_start, '%d')).'&search_dateend_startmonth='.urlencode(dol_print_date($search_dateend_start, '%m')).'&search_dateend_startyear='.urlencode(dol_print_date($search_dateend_start, '%Y')); - if ($search_dateend_end) $param .= '&search_dateend_endday='.urlencode(dol_print_date($search_dateend_end, '%d')).'&search_dateend_endmonth='.urlencode(dol_print_date($search_dateend_end, '%m')).'&search_dateend_endyear='.urlencode(dol_print_date($search_dateend_end, '%Y')); - if ($search_datedelivery_start) $param .= '&search_datedelivery_startday='.urlencode(dol_print_date($search_datedelivery_start, '%d')).'&search_datedelivery_startmonth='.urlencode(dol_print_date($search_datedelivery_start, '%m')).'&search_datedelivery_startyear='.urlencode(dol_print_date($search_datedelivery_start, '%Y')); - if ($search_datedelivery_end) $param .= '&search_datedelivery_endday='.urlencode(dol_print_date($search_datedelivery_end, '%d')).'&search_datedelivery_endmonth='.urlencode(dol_print_date($search_datedelivery_end, '%m')).'&search_datedelivery_endyear='.urlencode(dol_print_date($search_datedelivery_end, '%Y')); + if ($search_date_startday) { + $param .= '&search_date_startday='.urlencode($search_date_startday); + } + if ($search_date_startmonth) { + $param .= '&search_date_startmonth='.urlencode($search_date_startmonth); + } + 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_date_end_startday) { + $param .= '&search_date_end_startday='.urlencode($search_date_end_startday); + } + if ($search_date_end_startmonth) { + $param .= '&search_date_end_startmonth='.urlencode($search_date_end_startmonth); + } + if ($search_date_end_startyear) { + $param .= '&search_date_end_startyear='.urlencode($search_date_end_startyear); + } + if ($search_date_end_endday) { + $param .= '&search_date_end_endday='.urlencode($search_date_end_endday); + } + if ($search_date_end_endmonth) { + $param .= '&search_date_end_endmonth='.urlencode($search_date_end_endmonth); + } + if ($search_date_end_endyear) { + $param .= '&search_date_end_endyear='.urlencode($search_date_end_endyear); + } + if ($search_date_delivery_startday) { + $param .= '&search_date_delivery_startday='.urlencode($search_date_delivery_startday); + } + if ($search_date_delivery_startmonth) { + $param .= '&search_date_delivery_startmonth='.urlencode($search_date_delivery_startmonth); + } + if ($search_date_delivery_startyear) { + $param .= '&search_date_delivery_startyear='.urlencode($search_date_delivery_startyear); + } + if ($search_date_delivery_endday) { + $param .= '&search_date_delivery_endday='.urlencode($search_date_delivery_endday); + } + if ($search_date_delivery_endmonth) { + $param .= '&search_date_delivery_endmonth='.urlencode($search_date_delivery_endmonth); + } + if ($search_date_delivery_endyear) { + $param .= '&search_date_delivery_endyear='.urlencode($search_date_delivery_endyear); + } if ($search_ref) { $param .= '&search_ref='.urlencode($search_ref); } @@ -1023,10 +1109,10 @@ if ($resql) { if (!empty($arrayfields['p.fin_validite']['checked'])) { print ''; } @@ -1034,10 +1120,10 @@ if ($resql) { if (!empty($arrayfields['p.date_livraison']['checked'])) { print ''; } @@ -1297,10 +1383,24 @@ if ($resql) { if (!empty($arrayfields['sale_representative']['checked'])) { print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder); } + $totalarray = array( + 'nbfield' => 0, + 'val' => array( + 'p.total_ht' => 0, + 'p.total_tva' => 0, + 'p.total_ttc' => 0, + ), + ); // 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); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (!empty($arrayfields['p.datec']['checked'])) { @@ -1326,12 +1426,6 @@ if ($resql) { $now = dol_now(); $i = 0; - $totalarray = array(); - $totalarray['nbfield'] = 0; - $totalarray['val'] = array(); - $totalarray['val']['p.total_ht'] = 0; - $totalarray['val']['p.total_tva'] = 0; - $totalarray['val']['p.total_ttc'] = 0; $typenArray = null; while ($i < min($num, $limit)) { @@ -1714,8 +1808,8 @@ if ($resql) { $userstatic->login = $obj->login; $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; - $userstatic->email = $obj->email; - $userstatic->statut = $obj->statut; + $userstatic->email = $obj->user_email; + $userstatic->statut = $obj->user_statut; $userstatic->entity = $obj->user_entity; $userstatic->photo = $obj->photo; $userstatic->office_phone = $obj->office_phone; diff --git a/htdocs/comm/propal/note.php b/htdocs/comm/propal/note.php index 53a3a37c84d..13fa42edb29 100644 --- a/htdocs/comm/propal/note.php +++ b/htdocs/comm/propal/note.php @@ -112,7 +112,7 @@ if ($object->id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->propal->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ''; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -130,9 +130,10 @@ if ($object->id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/comm/propal/stats/index.php b/htdocs/comm/propal/stats/index.php index c1975e309f5..36d9af8f9b4 100644 --- a/htdocs/comm/propal/stats/index.php +++ b/htdocs/comm/propal/stats/index.php @@ -111,7 +111,7 @@ $data = $stats->getNbByMonthWithPrevYear($endyear, $startyear); // $data = array(array('Lib',val1,val2,val3),...) -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filenamenb = $dir.'/proposalsnbinyear-'.$user->id.'-'.$year.'.png'; $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsnbinyear-'.$user->id.'-'.$year.'.png'; } else { @@ -147,7 +147,7 @@ if (!$mesg) { $data = $stats->getAmountByMonthWithPrevYear($endyear, $startyear, 0); // $data = array(array('Lib',val1,val2,val3),...) -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filenameamount = $dir.'/proposalsamountinyear-'.$user->id.'-'.$year.'.png'; $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=propalstats&file=proposalsamountinyear-'.$user->id.'-'.$year.'.png'; } else { @@ -182,7 +182,7 @@ if (!$mesg) { $data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); $fileurl_avg = ''; -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png'; if ($mode == 'customer') { $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png'; @@ -347,7 +347,7 @@ foreach ($data as $val) { print '
    '; print '
    '; - print $form->selectDate($search_dateend_start ? $search_dateend_start : -1, 'search_dateend_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print $form->selectDate($search_date_end_start ? $search_date_end_start : -1, 'search_date_end_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); print '
    '; print '
    '; - print $form->selectDate($search_dateend_end ? $search_dateend_end : -1, 'search_dateend_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print $form->selectDate($search_date_end_end ? $search_date_end_end : -1, 'search_date_end_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); print '
    '; print '
    '; print '
    '; - print $form->selectDate($search_datedelivery_start ? $search_datedelivery_start : -1, 'search_datedelivery_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print $form->selectDate($search_date_delivery_start ? $search_date_delivery_start : -1, 'search_date_delivery_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); print '
    '; print '
    '; - print $form->selectDate($search_datedelivery_end ? $search_datedelivery_end : -1, 'search_datedelivery_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print $form->selectDate($search_date_delivery_end ? $search_date_delivery_end : -1, 'search_date_delivery_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); print '
    '; print '
    '; print '
    '; -print '
    '; +print '
    '; // Show graphs @@ -364,7 +364,7 @@ if ($mesg) { print ''; -print '
    '; +print ''; print '
    '; diff --git a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php index 23c1a459c74..adc9de9339e 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; @@ -68,7 +68,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { } print ''; print ''.$objectlink->getLibStatut(3).''; - print ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; + print ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; print "\n"; } if (count($linkedObjectBlock) > 1) { diff --git a/htdocs/comm/prospect/index.php b/htdocs/comm/prospect/index.php index d2f60c36212..1e1caa796b5 100644 --- a/htdocs/comm/prospect/index.php +++ b/htdocs/comm/prospect/index.php @@ -80,13 +80,13 @@ if (!empty($conf->propal->enabled)) { $sql = "SELECT count(*) as cc, st.libelle, st.picto, st.id"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."c_stcomm as st "; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.fk_stcomm = st.id"; $sql .= " AND s.client IN (2, 3)"; $sql .= " AND s.entity IN (".getEntity($companystatic->element).")"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY st.id"; @@ -122,13 +122,13 @@ if (!empty($conf->propal->enabled) && $user->rights->propale->lire) { $sql = "SELECT p.rowid, p.ref, p.price, s.nom as sname"; $sql .= " FROM ".MAIN_DB_PREFIX."propal as p"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.fk_statut = 0"; $sql .= " AND p.fk_soc = s.rowid"; $sql .= " AND p.entity IN (".getEntity('propal').")"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -163,8 +163,7 @@ if (!empty($conf->propal->enabled) && $user->rights->propale->lire) { } -//print ''; -print '
    '; +print '
    '; /* @@ -183,14 +182,14 @@ if (!empty($conf->propal->enabled) && $user->rights->propale->lire) { $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."propal as p"; $sql .= ", ".MAIN_DB_PREFIX."c_propalst as c"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.fk_soc = s.rowid"; $sql .= " AND p.fk_statut = c.id"; $sql .= " AND p.fk_statut = 1"; $sql .= " AND p.entity IN (".getEntity('propal').")"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -244,12 +243,12 @@ if (!empty($conf->propal->enabled) && $user->rights->propale->lire) { */ $sql = "SELECT s.nom as name, s.rowid as socid, s.client, s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.fk_stcomm = 1"; $sql .= " AND s.entity IN (".getEntity($companystatic->element).")"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY s.tms ASC"; @@ -280,8 +279,7 @@ if ($resql) { } -//print ''; -print '
    '; +print ''; // End of page llxFooter(); diff --git a/htdocs/comm/remise.php b/htdocs/comm/remise.php index bcb0fefa7b8..b2900e65575 100644 --- a/htdocs/comm/remise.php +++ b/htdocs/comm/remise.php @@ -250,7 +250,6 @@ if ($socid > 0) { if ($isCustomer) { print ''; // class="fichehalfleft" print '
    '; - print '
    '; print load_fiche_titre($langs->trans("SupplierDiscounts"), '', ''); } @@ -298,7 +297,6 @@ if ($socid > 0) { } if ($isCustomer) { - print '
    '; // class="ficheaddleft" print '
    '; // class="fichehalfright" print ''; // class="fichecenter" } diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index e9419480ed6..4404f9758a6 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -532,7 +532,6 @@ if ($socid > 0) { if ($isCustomer) { print ''; // class="fichehalfleft" print '
    '; - print '
    '; print load_fiche_titre($langs->trans("SupplierDiscounts"), '', ''); } @@ -667,7 +666,6 @@ if ($socid > 0) { } if ($isCustomer) { - print '
    '; // class="ficheaddleft" print '
    '; // class="fichehalfright" print ''; // class="fichecenter" } @@ -843,7 +841,6 @@ if ($socid > 0) { if ($isCustomer) { print ''; // class="fichehalfleft" print '
    '; - print '
    '; print load_fiche_titre($langs->trans("SupplierDiscounts"), '', ''); } @@ -1000,7 +997,6 @@ if ($socid > 0) { } if ($isCustomer) { - print '
    '; // class="ficheaddleft" print '
    '; // class="fichehalfright" print ''; // class="fichecenter" } diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 3aaa79cab55..db29da62565 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -294,6 +294,7 @@ if (empty($reshook)) { if (!empty($origin) && !empty($originid)) { // Parse element/subelement (ex: project_task) $element = $subelement = $origin; + $regs = array(); if (preg_match('/^([^_]+)_([^_]+)/i', $origin, $regs)) { $element = $regs [1]; $subelement = $regs [2]; @@ -1410,6 +1411,7 @@ if (empty($reshook)) { /* * View */ + $title = $langs->trans('Order')." - ".$langs->trans('Card'); $help_url = 'EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes|DE:Modul_Kundenaufträge'; llxHeader('', $title, $help_url); @@ -1492,13 +1494,13 @@ if ($action == 'create' && $usercancreate) { $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 $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 : (!empty($soc->availability_id) ? $soc->availability_id : 0)); + $availability_id = (!empty($objectsrc->availability_id) ? $objectsrc->availability_id : 0); $shipping_method_id = (!empty($objectsrc->shipping_method_id) ? $objectsrc->shipping_method_id : (!empty($soc->shipping_method_id) ? $soc->shipping_method_id : 0)); $warehouse_id = (!empty($objectsrc->warehouse_id) ? $objectsrc->warehouse_id : (!empty($soc->warehouse_id) ? $soc->warehouse_id : 0)); $demand_reason_id = (!empty($objectsrc->demand_reason_id) ? $objectsrc->demand_reason_id : (!empty($soc->demand_reason_id) ? $soc->demand_reason_id : 0)); $remise_percent = (!empty($objectsrc->remise_percent) ? $objectsrc->remise_percent : (!empty($soc->remise_percent) ? $soc->remise_percent : 0)); $remise_absolue = (!empty($objectsrc->remise_absolue) ? $objectsrc->remise_absolue : (!empty($soc->remise_absolue) ? $soc->remise_absolue : 0)); - $dateorder = empty($conf->global->MAIN_AUTOFILL_DATE_ORDER) ?-1 : ''; + $dateorder = empty($conf->global->MAIN_AUTOFILL_DATE_ORDER) ? -1 : ''; $date_delivery = (!empty($objectsrc->delivery_date) ? $objectsrc->delivery_date : ''); if (empty($date_delivery)) { @@ -1524,7 +1526,7 @@ if ($action == 'create' && $usercancreate) { $cond_reglement_id = $soc->cond_reglement_id; $mode_reglement_id = $soc->mode_reglement_id; $fk_account = $soc->fk_account; - $availability_id = $soc->availability_id; + $availability_id = 0; $shipping_method_id = $soc->shipping_method_id; $warehouse_id = $soc->warehouse_id; $demand_reason_id = $soc->demand_reason_id; @@ -1644,13 +1646,19 @@ if ($action == 'create' && $usercancreate) { print "\n"; print ''; + // Delivery delay + print ''.$langs->trans('AvailabilityPeriod').''; + print img_picto('', 'clock', 'class="pictofixedwidth"'); + $form->selectAvailabilityDelay($availability_id, 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx'); + print ''; + // Terms of the settlement print ''.$langs->trans('PaymentConditionsShort').''; print img_picto('', 'paiment'); $form->select_conditions_paiements($cond_reglement_id, 'cond_reglement_id', - 1, 1); print ''; - // Mode de reglement + // Payment mode print ''.$langs->trans('PaymentMode').''; print img_picto('', 'bank', 'class="pictofixedwidth"'); $form->select_types_paiements($mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx'); @@ -1663,12 +1671,6 @@ if ($action == 'create' && $usercancreate) { print ''; } - // Delivery delay - print ''.$langs->trans('AvailabilityPeriod').''; - print img_picto('', 'clock', 'class="pictofixedwidth"'); - $form->selectAvailabilityDelay($availability_id, 'availability_id', '', 1, 'maxwidth200 widthcentpercentminusx'); - print ''; - // Shipping Method if (!empty($conf->expedition->enabled)) { print ''.$langs->trans('SendingMethod').''; @@ -1735,7 +1737,7 @@ if ($action == 'create' && $usercancreate) { } }; - print $object->showOptionals($extrafields, 'edit', $parameters); + print $object->showOptionals($extrafields, 'create', $parameters); } // Template to use by default @@ -1922,6 +1924,21 @@ if ($action == 'create' && $usercancreate) { ); } + // mandatoryPeriod + $nbMandated = 0; + foreach ($object->lines as $line) { + $res = $line->fetch_product(); + if ($res > 0 ) { + if ($line->product->isService() && $line->product->isMandatoryPeriod() && (empty($line->date_start) || empty($line->date_end) )) { + $nbMandated++; + break; + } + } + } + if ($nbMandated > 0 ) $text .= '
    '.$langs->trans("mandatoryPeriodNeedTobeSetMsgValidate").'
    '; + + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateOrder'), $text, 'confirm_validate', $formquestion, 0, 1, 220); } @@ -2041,7 +2058,7 @@ if ($action == 'create' && $usercancreate) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($usercancreate) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -2058,9 +2075,10 @@ if ($action == 'create' && $usercancreate) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -2131,7 +2149,7 @@ if ($action == 'create' && $usercancreate) { print ''; } else { print $object->date ? dol_print_date($object->date, 'day') : ' '; - if ($object->hasDelay()) { + if ($object->hasDelay() && empty($object->delivery_date)) { // If there is a delivery date planned, warning should be on this date print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning"); } } @@ -2159,6 +2177,18 @@ if ($action == 'create' && $usercancreate) { print ''; print ''; + // Delivery delay + print ''; + $editenable = $usercancreate; + print $form->editfieldkey("AvailabilityPeriod", 'availability', '', $object, $editenable); + print ''; + if ($action == 'editavailability') { + $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'availability_id', 1); + } else { + $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'none', 1); + } + print ''; + // Shipping Method if (!empty($conf->expedition->enabled)) { print ''; @@ -2192,6 +2222,18 @@ if ($action == 'create' && $usercancreate) { print ''; } + // Source reason (why we have an order) + print ''; + $editenable = $usercancreate; + print $form->editfieldkey("Source", 'demandreason', '', $object, $editenable); + print ''; + if ($action == 'editdemandreason') { + $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'demand_reason_id', 1); + } else { + $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'none'); + } + print ''; + // Terms of payment print ''; $editenable = $usercancreate; @@ -2257,30 +2299,6 @@ if ($action == 'create' && $usercancreate) { } } - // Delivery delay - print ''; - $editenable = $usercancreate; - print $form->editfieldkey("AvailabilityPeriod", 'availability', '', $object, $editenable); - print ''; - if ($action == 'editavailability') { - $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'availability_id', 1); - } else { - $form->form_availability($_SERVER['PHP_SELF'].'?id='.$object->id, $object->availability_id, 'none', 1); - } - print ''; - - // Source reason (why we have an ordrer) - print ''; - $editenable = $usercancreate; - print $form->editfieldkey("Channel", 'demandreason', '', $object, $editenable); - print ''; - if ($action == 'editdemandreason') { - $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'demand_reason_id', 1); - } else { - $form->formInputReason($_SERVER['PHP_SELF'].'?id='.$object->id, $object->demand_reason_id, 'none'); - } - print ''; - // TODO Order mode (how we receive order). Not yet implemented /* print ''; @@ -2350,7 +2368,6 @@ if ($action == 'create' && $usercancreate) { print ''; print '
    '; - print '
    '; print '
    '; print ''; @@ -2358,17 +2375,17 @@ if ($action == 'create' && $usercancreate) { if (!empty($conf->multicurrency->enabled) && ($object->multicurrency_code != $conf->currency)) { // Multicurrency Amount HT print ''; - print ''; + print ''; print ''; // Multicurrency Amount VAT print ''; - print ''; + print ''; print ''; // Multicurrency Amount TTC print ''; - print ''; + print ''; print ''; } @@ -2378,23 +2395,23 @@ if ($action == 'create' && $usercancreate) { $alert = ' '.img_warning($langs->trans('OrderMinAmount').': '.price($object->thirdparty->order_min_amount)); } print ''; - print ''; + print ''; // Total VAT - print ''; + print ''; // Amount Local Taxes if ($mysoc->localtax1_assuj == "1" || $object->total_localtax1 != 0) { // Localtax1 print ''; - print ''; + print ''; } if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) { // Localtax2 IRPF print ''; - print ''; + print ''; } // Total TTC - print ''; + print ''; // Statut //print ''; @@ -2407,7 +2424,6 @@ if ($action == 'create' && $usercancreate) { } - print ''; print ''; print ''; // Close fichecenter @@ -2485,14 +2501,14 @@ 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 ''.$langs->trans('ReOpen').''; } // 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 ''.$langs->trans('SendMail').''; } else { print ''.$langs->trans('SendMail').''; } @@ -2574,31 +2590,31 @@ if ($action == 'create' && $usercancreate) { // 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 ''.$langs->trans("CreateBill").''; } 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 ''.$langs->trans("ClassifyBilled").''; } } 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 ''.$langs->trans("ClassifyUnBilled").''; } } // Clone if ($usercancreate) { - print ''.$langs->trans("ToClone").''; + print ''.$langs->trans("ToClone").''; } // Cancel order if ($object->statut == Commande::STATUS_VALIDATED && (!empty($usercanclose) || !empty($usercancancel))) { - print ''.$langs->trans("Cancel").''; + print ''.$langs->trans("Cancel").''; } // Delete order if ($usercandelete) { if ($numshipping == 0) { - print ''.$langs->trans('Delete').''; + print ''.$langs->trans('Delete').''; } else { print ''.$langs->trans("Delete").''; } @@ -2646,14 +2662,14 @@ if ($action == 'create' && $usercancreate) { print showOnlinePaymentUrl('order', $object->ref).'
    '; } - print '
    '; + print '
    '; // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'order', $socid, 1); - print '
    '; + print ''; } // Presend form diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 0887c22a8f3..6d0b5a5d297 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -981,6 +981,7 @@ class Orders extends DolibarrApi if (!DolibarrApiAccess::$user->rights->expedition->lire) { throw new RestException(401); } + $obj_ret = array(); $sql = "SELECT e.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."expedition as e"; $sql .= " JOIN ".MAIN_DB_PREFIX."expeditiondet as edet"; @@ -1054,7 +1055,6 @@ class Orders extends DolibarrApi if ($result <= 0) { throw new RestException(500, 'Error on creating expedition lines:'.$this->db->lasterror()); } - $i++; } return $shipment->id; } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 5fce8a81a30..9b315698527 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -299,13 +299,9 @@ class Commande extends CommonOrder '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), - 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>56), - 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>60), + '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), - 'date_commande' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>70), - 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>75), - 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>80), 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>85), 'fk_user_cloture' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>90), 'source' =>array('type'=>'smallint(6)', 'label'=>'Source', 'enabled'=>1, 'visible'=>-1, 'position'=>95), @@ -344,6 +340,10 @@ class Commande extends CommonOrder 'last_main_doc' =>array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>1, 'visible'=>-1, 'position'=>270), 'module_source' =>array('type'=>'varchar(32)', 'label'=>'POSModule', 'enabled'=>1, 'visible'=>-1, 'position'=>275), 'pos_source' =>array('type'=>'varchar(32)', 'label'=>'POSTerminal', 'enabled'=>1, 'visible'=>-1, 'position'=>280), + 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>300), + 'fk_user_modif' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>302), + 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>304), + 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>306), 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>400), 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>-1, 'position'=>500), ); @@ -2678,16 +2678,16 @@ class Commande extends CommonOrder $sql = "SELECT s.rowid, s.nom as name, s.client,"; $sql .= " c.rowid as cid, c.ref"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user"; } $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."commande as c"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.entity IN (".getEntity('commande').")"; $sql .= " AND c.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { //restriction + if (empty($user->rights->societe->client->voir) && !$socid) { //restriction $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -3505,7 +3505,7 @@ class Commande extends CommonOrder $sql = "SELECT c.rowid, c.date_creation as datec, c.date_commande, c.date_livraison as delivery_date, c.fk_statut, c.total_ht"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = " AND"; @@ -3915,7 +3915,7 @@ class Commande extends CommonOrder $sql = "SELECT count(co.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as co"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON co.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/commande/class/commandestats.class.php b/htdocs/commande/class/commandestats.class.php index 8ac89d5a18f..d02d56175ff 100644 --- a/htdocs/commande/class/commandestats.class.php +++ b/htdocs/commande/class/commandestats.class.php @@ -93,7 +93,7 @@ class CommandeStats extends Stats //$this->where.= " AND c.fk_soc = s.rowid AND c.entity = ".$conf->entity; $this->where .= ($this->where ? ' AND ' : '').'c.entity IN ('.getEntity('commande').')'; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $this->where .= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($this->socid) { @@ -128,7 +128,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -153,7 +153,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%Y') as dm, COUNT(*) as nb, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -177,7 +177,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, SUM(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -202,7 +202,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%m') as dm, AVG(c.".$this->field.")"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -225,7 +225,7 @@ class CommandeStats extends Stats $sql = "SELECT date_format(c.date_commande,'%Y') as year, COUNT(*) as nb, SUM(c.".$this->field.") as total, AVG(".$this->field.") as avg"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; @@ -249,7 +249,7 @@ class CommandeStats extends Stats $sql = "SELECT product.ref, COUNT(product.ref) as nb, SUM(tl.".$this->field_line.") as total, AVG(tl.".$this->field_line.") as avg"; $sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= $this->join; diff --git a/htdocs/commande/contact.php b/htdocs/commande/contact.php index 0a44d87f4ae..a4d857a47fd 100644 --- a/htdocs/commande/contact.php +++ b/htdocs/commande/contact.php @@ -143,7 +143,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->commande->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -161,9 +161,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/commande/customer.php b/htdocs/commande/customer.php index 3ecaa0fbee1..96efda7c187 100644 --- a/htdocs/commande/customer.php +++ b/htdocs/commande/customer.php @@ -77,16 +77,16 @@ $thirdpartystatic = new Societe($db); $sql = "SELECT s.rowid, s.nom as name, s.client, s.town, s.datec, s.datea"; $sql .= ", st.libelle as stcomm, s.prefix_comm, s.code_client, s.code_compta "; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user "; } $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."c_stcomm as st, ".MAIN_DB_PREFIX."commande as c"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.fk_stcomm = st.id AND c.fk_soc = s.rowid"; $sql .= " AND s.entity IN (".getEntity('societe').")"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if (GETPOST("search_nom")) { diff --git a/htdocs/commande/document.php b/htdocs/commande/document.php index f8cc503e0ec..b2b024f686a 100644 --- a/htdocs/commande/document.php +++ b/htdocs/commande/document.php @@ -135,7 +135,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->commande->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -153,9 +153,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/commande/index.php b/htdocs/commande/index.php index a794d79e743..03644fe5690 100644 --- a/htdocs/commande/index.php +++ b/htdocs/commande/index.php @@ -94,7 +94,7 @@ if (!empty($conf->commande->enabled)) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -103,7 +103,7 @@ if (!empty($conf->commande->enabled)) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -146,7 +146,7 @@ if (!empty($conf->commande->enabled)) { } -print '
    '; +print '
    '; $max = 5; @@ -162,7 +162,7 @@ $sql .= ", s.code_client"; $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -171,7 +171,7 @@ $sql .= " AND c.entity IN (".getEntity('commande').")"; if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.tms DESC"; @@ -246,7 +246,7 @@ if (!empty($conf->commande->enabled)) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -255,7 +255,7 @@ if (!empty($conf->commande->enabled)) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.rowid DESC"; @@ -335,7 +335,7 @@ if (!empty($conf->commande->enabled)) { $sql .= ", s.canvas"; $sql .= " FROM ".MAIN_DB_PREFIX."commande as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -344,7 +344,7 @@ if (!empty($conf->commande->enabled)) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.rowid DESC"; @@ -414,7 +414,7 @@ if (!empty($conf->commande->enabled)) { } -print '
    '; +print ''; $parameters = array('user' => $user); $reshook = $hookmanager->executeHooks('dashboardOrders', $parameters, $object); // Note that $action and $object may have been modified by hook diff --git a/htdocs/commande/info.php b/htdocs/commande/info.php index 2e5f0b696ff..38d8beba2ec 100644 --- a/htdocs/commande/info.php +++ b/htdocs/commande/info.php @@ -88,7 +88,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->commande->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -106,9 +106,10 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index e8b76a94e42..b0685b8b64b 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -309,13 +309,14 @@ if ($action == 'validate' && $permissiontoadd) { $idwarehouse = 0; } if ($objecttmp->valid($user, $idwarehouse)) { - setEventMessage($objecttmp->ref." ".$langs->trans('PassedInOpenStatus'), 'mesgs'); + setEventMessage($langs->trans('hasBeenValidated', $objecttmp->ref), 'mesgs'); } else { setEventMessage($langs->trans('CantBeValidated'), 'errors'); $error++; } } else { - setEventMessage($objecttmp->ref." ".$langs->trans('IsNotADraft'), 'errors'); + $langs->load("errors"); + setEventMessage($langs->trans('ErrorIsNotADraft', $objecttmp->ref), 'errors'); $error++; } } else { @@ -339,13 +340,14 @@ if ($action == 'shipped' && $permissiontoadd) { if ($objecttmp->fetch($checked)) { if ($objecttmp->statut == 1) { if ($objecttmp->cloture($user)) { - setEventMessage($objecttmp->ref." ".$langs->trans('PassedInOpenStatus'), 'mesgs'); + setEventMessage($langs->trans('PassedInClosedStatus', $objecttmp->ref), 'mesgs'); } else { - setEventMessage($langs->trans('CantBeValidated'), 'errors'); + setEventMessage($langs->trans('CantBeClosed'), 'errors'); $error++; } } else { - setEventMessage($objecttmp->ref." ".$langs->trans('IsNotADraft'), 'errors'); + $langs->load("errors"); + setEventMessage($langs->trans('ErrorIsNotADraft', $objecttmp->ref), 'errors'); $error++; } } else { @@ -426,10 +428,10 @@ $sql .= ' c.fk_multicurrency, c.multicurrency_code, c.multicurrency_tx, c.multic $sql .= ' c.date_valid, c.date_commande, c.note_public, c.note_private, c.date_livraison as date_delivery, c.fk_statut, c.facture as billed,'; $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, u.statut, u.entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender,'; +$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'; -if ($search_categ_cus) { +if (($search_categ_cus > 0) || ($search_categ_cus == -2)) { $sql .= ", cc.fk_categorie, cc.fk_soc"; } // Add fields from extrafields @@ -446,7 +448,7 @@ $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)"; -if (!empty($search_categ_cus)) { +if (($search_categ_cus > 0) || ($search_categ_cus == -2)) { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_societe as cc ON s.rowid = cc.fk_soc"; // We'll need this table joined to the select in order to filter by categ } $sql .= ', '.MAIN_DB_PREFIX.'commande as c'; @@ -463,7 +465,7 @@ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = c.fk_projet"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON c.fk_user_author = u.rowid'; // We'll need this table joined to the select in order to filter by sale -if ($search_sale > 0 || (!$user->rights->societe->client->voir && !$socid)) { +if ($search_sale > 0 || (empty($user->rights->societe->client->voir) && !$socid)) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } if ($search_user > 0) { @@ -484,7 +486,7 @@ if ($search_product_category > 0) { if ($socid > 0) { $sql .= ' AND s.rowid = '.((int) $socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($search_ref) { @@ -551,7 +553,7 @@ if ($search_state) { if ($search_country) { $sql .= " AND s.fk_pays IN (".$db->sanitize($search_country).')'; } -if ($search_type_thirdparty) { +if ($search_type_thirdparty && $search_type_thirdparty != '-1') { $sql .= " AND s.fk_typent IN (".$db->sanitize($search_type_thirdparty).')'; } if ($search_company) { @@ -793,13 +795,13 @@ if ($resql) { if ($search_country != '') { $param .= '&search_country='.urlencode($search_country); } - if ($search_type_thirdparty != '' && $search_type_thirdparty > 0) { + if ($search_type_thirdparty && $search_type_thirdparty != '-1') { $param .= '&search_type_thirdparty='.urlencode($search_type_thirdparty); } if ($search_product_category != '') { $param .= '&search_product_category='.urlencode($search_product_category); } - if ($search_categ_cus > 0) { + if (($search_categ_cus > 0) || ($search_categ_cus == -2)) { $param .= '&search_categ_cus='.urlencode($search_categ_cus); } if ($show_files) { @@ -1343,10 +1345,25 @@ if ($resql) { print_liste_field_titre($arrayfields['sale_representative']['label'], $_SERVER["PHP_SELF"], "", "", "$param", '', $sortfield, $sortorder); } + $totalarray = array( + 'nbfield' => 0, + 'val' => array( + 'c.total_ht' => 0, + 'c.total_tva' => 0, + 'c.total_ttc' => 0, + ), + 'pos' => array(), + ); // 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); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; if (!empty($arrayfields['c.datec']['checked'])) { @@ -1386,7 +1403,6 @@ if ($resql) { $generic_product = new Product($db); $userstatic = new User($db); $i = 0; - $totalarray = array('nbfield' => 0, 'val' => array(), 'pos' => array()); while ($i < min($num, $limit)) { $obj = $db->fetch_object($resql); @@ -1695,8 +1711,8 @@ if ($resql) { $userstatic->login = $obj->login; $userstatic->lastname = $obj->lastname; $userstatic->firstname = $obj->firstname; - $userstatic->email = $obj->email; - $userstatic->statut = $obj->statut; + $userstatic->email = $obj->user_email; + $userstatic->statut = $obj->user_statut; $userstatic->entity = $obj->entity; $userstatic->photo = $obj->photo; $userstatic->office_phone = $obj->office_phone; diff --git a/htdocs/commande/note.php b/htdocs/commande/note.php index e03d9c00edb..55140c30ae2 100644 --- a/htdocs/commande/note.php +++ b/htdocs/commande/note.php @@ -107,7 +107,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->commande->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -125,9 +125,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/commande/stats/index.php b/htdocs/commande/stats/index.php index a9c38e1531c..8a3a6a142aa 100644 --- a/htdocs/commande/stats/index.php +++ b/htdocs/commande/stats/index.php @@ -42,7 +42,7 @@ $mode = GETPOSTISSET("mode") ? GETPOST("mode", 'aZ09') : 'customer'; if ($mode == 'customer' && !$user->rights->commande->lire) { accessforbidden(); } -if ($mode == 'supplier' && !$user->rights->fournisseur->commande->lire) { +if ($mode == 'supplier' && empty($user->rights->fournisseur->commande->lire)) { accessforbidden(); } @@ -112,7 +112,7 @@ $data = $stats->getNbByMonthWithPrevYear($endyear, $startyear); // $data = array(array('Lib',val1,val2,val3),...) -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filenamenb = $dir.'/ordersnbinyear-'.$user->id.'-'.$year.'.png'; if ($mode == 'customer') { $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersnbinyear-'.$user->id.'-'.$year.'.png'; @@ -158,7 +158,7 @@ $data = $stats->getAmountByMonthWithPrevYear($endyear, $startyear); //var_dump($data); // $data = array(array('Lib',val1,val2,val3),...) -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filenameamount = $dir.'/ordersamountinyear-'.$user->id.'-'.$year.'.png'; if ($mode == 'customer') { $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersamountinyear-'.$user->id.'-'.$year.'.png'; @@ -202,7 +202,7 @@ if (!$mesg) { $data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png'; if ($mode == 'customer') { $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png'; @@ -401,7 +401,7 @@ print '
    '.$form->editfieldkey('MulticurrencyAmountHT', 'multicurrency_total_ht', '', $object, 0).''.price($object->multicurrency_total_ht, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).''.price($object->multicurrency_total_ht, '', $langs, 0, -1, -1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'
    '.$form->editfieldkey('MulticurrencyAmountVAT', 'multicurrency_total_tva', '', $object, 0).''.price($object->multicurrency_total_tva, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).''.price($object->multicurrency_total_tva, '', $langs, 0, -1, -1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'
    '.$form->editfieldkey('MulticurrencyAmountTTC', 'multicurrency_total_ttc', '', $object, 0).''.price($object->multicurrency_total_ttc, '', $langs, 0, - 1, - 1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).''.price($object->multicurrency_total_ttc, '', $langs, 0, -1, -1, (!empty($object->multicurrency_code) ? $object->multicurrency_code : $conf->currency)).'
    '.$langs->trans('AmountHT').''.price($object->total_ht, 1, '', 1, - 1, - 1, $conf->currency).$alert.''.price($object->total_ht, 1, '', 1, -1, -1, $conf->currency).$alert.'
    '.$langs->trans('AmountVAT').''.price($object->total_tva, 1, '', 1, - 1, - 1, $conf->currency).'
    '.$langs->trans('AmountVAT').''.price($object->total_tva, 1, '', 1, -1, -1, $conf->currency).'
    '.$langs->transcountry("AmountLT1", $mysoc->country_code).''.price($object->total_localtax1, 1, '', 1, - 1, - 1, $conf->currency).'
    '.price($object->total_localtax1, 1, '', 1, -1, -1, $conf->currency).'
    '.$langs->transcountry("AmountLT2", $mysoc->country_code).''.price($object->total_localtax2, 1, '', 1, - 1, - 1, $conf->currency).'
    '.price($object->total_localtax2, 1, '', 1, -1, -1, $conf->currency).'
    '.$langs->trans('AmountTTC').''.price($object->total_ttc, 1, '', 1, - 1, - 1, $conf->currency).'
    '.$langs->trans('AmountTTC').''.price($object->total_ttc, 1, '', 1, -1, -1, $conf->currency).'
    ' . $langs->trans('Status') . '' . $object->getLibStatut(4) . '
    '; print '
    '; -print '
    '; +print '
    '; // Show graphs @@ -418,7 +418,7 @@ if ($mesg) { print ''; -print '
    '; +print ''; print '
    '; print dol_get_fiche_end(); diff --git a/htdocs/commande/tpl/linkedobjectblock.tpl.php b/htdocs/commande/tpl/linkedobjectblock.tpl.php index a0641c4c493..aba881a63c6 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; @@ -64,7 +64,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { echo ''; // For now, shipments must stay linked to order, so link is not deletable if ($object->element != 'shipping') { - echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; + echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; } echo ''; echo "\n"; diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index fddf7a2879f..8abbdaa0dd3 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -578,7 +578,7 @@ print '
    '; foreach ($listofchoices as $choice => $val) { if (empty($val['enabled'])) { - continue; // list not qualified + continue; // list not qualified } $disabled = ''; if (empty($val['perms'])) { diff --git a/htdocs/compta/bank/account_statement_document.php b/htdocs/compta/bank/account_statement_document.php index 03209ad7673..0a979e01d39 100644 --- a/htdocs/compta/bank/account_statement_document.php +++ b/htdocs/compta/bank/account_statement_document.php @@ -120,6 +120,8 @@ if (GETPOST("rel") == 'prev') { $found = true; } +$permissiontoadd = $user->rights->banque->modifier; // Used by the include of actions_dellink.inc.php + /* * Actions diff --git a/htdocs/compta/bank/annuel.php b/htdocs/compta/bank/annuel.php index d771b307234..36a9d17315a 100644 --- a/htdocs/compta/bank/annuel.php +++ b/htdocs/compta/bank/annuel.php @@ -448,9 +448,9 @@ if ($result < 0) { print '
    '; // do not use class="center" here, it will have no effect for the js graph inside. print $show1; - print '
    '; // do not use class="center" here, it will have no effect for the js graph inside. + print '
    '; // do not use class="center" here, it will have no effect for the js graph inside. print $show2; - print '
    '; + print ''; print '
    '; } diff --git a/htdocs/compta/bank/bankentries_list.php b/htdocs/compta/bank/bankentries_list.php index e5e264a12f5..8628e287bd0 100644 --- a/htdocs/compta/bank/bankentries_list.php +++ b/htdocs/compta/bank/bankentries_list.php @@ -8,7 +8,7 @@ * Copyright (C) 2016 Juanjo Menent * Copyright (C) 2017-2019 Alexandre Spangaro * Copyright (C) 2018 Ferran Marcet - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2021 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify @@ -64,11 +64,12 @@ $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); $contextpage = 'banktransactionlist'.(empty($object->ref) ? '' : '-'.$object->id); +$massaction = GETPOST('massaction', 'alpha'); // Security check $fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : '')); $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); -if ($fielvalue) { +if ($fieldvalue) { if ($user->socid) { $socid = $user->socid; } @@ -97,6 +98,8 @@ $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'); +$optioncss = GETPOST('optioncss', 'alpha'); +$toselect = GETPOST('toselect', 'array'); $num_releve = GETPOST("num_releve", "alpha"); if (empty($dateop)) { $dateop = -1; @@ -211,6 +214,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_thirdparty_user = ''; $search_num_releve = ''; $search_conciliated = ''; + $toselect = ''; $search_account = ""; if ($id > 0 || !empty($ref)) { @@ -221,14 +225,14 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' if (empty($reshook)) { $objectclass = 'Account'; $objectlabel = 'BankTransaction'; - $permissiontoread = $user->rights->banque->lire; - $permissiontodelete = $user->rights->banque->supprimer; + $permissiontoread = !empty($user->rights->banque->lire); + $permissiontodelete = !empty($user->rights->banque->modifier); $uploaddir = $conf->bank->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } // Conciliation -if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', 'alpha')) && $user->rights->banque->consolidate +if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', 'alpha')) && !empty($user->rights->banque->consolidate) && (!GETPOSTISSET('pageplusone') || (GETPOST('pageplusone') == GETPOST('pageplusoneold')))) { $error = 0; @@ -310,7 +314,7 @@ if ((GETPOST('confirm_savestatement', 'alpha') || GETPOST('confirm_reconcile', ' } -if (GETPOST('save') && !$cancel && $user->rights->banque->modifier) { +if (GETPOST('save') && !$cancel && !empty($user->rights->banque->modifier)) { $error = 0; if (price2num(GETPOST("addcredit")) > 0) { @@ -370,7 +374,7 @@ if (GETPOST('save') && !$cancel && $user->rights->banque->modifier) { } } -if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->banque->modifier) { +if ($action == 'confirm_delete' && $confirm == 'yes' && !empty($user->rights->banque->modifier)) { $accline = new AccountLine($db); $result = $accline->fetch(GETPOST("rowid", "int")); $result = $accline->delete($user); @@ -484,6 +488,11 @@ if ($optioncss != '') { if ($action == 'reconcile') { $param .= '&action=reconcile'; } +$totalarray = array( + 'nbfield' => 0, + 'totalcred' => 0, + 'totaldeb' => 0, +); // Add $param from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; @@ -574,7 +583,7 @@ if ($search_bid > 0) { } $sql .= " ".MAIN_DB_PREFIX."bank_account as ba,"; $sql .= " ".MAIN_DB_PREFIX."bank as b"; -if (is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { +if (!empty($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 (b.rowid = ef.fk_object)"; } $sql .= " WHERE b.fk_account = ba.rowid"; @@ -732,7 +741,7 @@ $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); - $arrayofselected = is_array($toselect) ? $toselect : array(); + $arrayofselected = (!empty($toselect) && is_array($toselect)) ? $toselect : array(); // List of mass actions available $arrayofmassactions = array( @@ -759,7 +768,9 @@ if ($resql) { print ''; print ''; print ''; - print ''; + if (!empty($view)) { + print ''; + } print ''; print ''; print ''; @@ -833,7 +844,7 @@ if ($resql) { } // Form to add a transaction with no invoice - if ($user->rights->banque->modifier && $action == 'addline' && !empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)) { + if (!empty($user->rights->banque->modifier) && $action == 'addline' && !empty($conf->global->BANK_USE_OLD_VARIOUS_PAYMENT)) { print load_fiche_titre($langs->trans("AddBankRecordLong"), '', ''); print ''; @@ -889,7 +900,7 @@ if ($resql) { print ''; }*/ print ''; @@ -932,13 +943,14 @@ if ($resql) { $newcardbutton = dolGetButtonTitle($langs->trans('AddBankRecord'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/compta/bank/various_payment/card.php?action=create&accountid='.urlencode($search_account).'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.urlencode($search_account)), '', $user->rights->banque->modifier); } else // If direct entries is not done using miscellaneous payments { - $newcardbutton = dolGetButtonTitle($langs->trans('AddBankRecord'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?action=addline&page='.$page.$param, '', $user->rights->banque->modifier); + $newcardbutton = dolGetButtonTitle($langs->trans('AddBankRecord'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?action=addline&token='.newToken().'&page='.$page.$param, '', $user->rights->banque->modifier); } } else { - $newcardbutton = dolGetButtonTitle($langs->trans('AddBankRecord'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?action=addline&page='.$page.$param, '', -1); + $newcardbutton = dolGetButtonTitle($langs->trans('AddBankRecord'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?action=addline&token='.newToken().'&page='.$page.$param, '', -1); } } + $morehtml = ''; /*$morehtml = '
    '; $morehtml .= ' "; // ' Page '; $morehtml .= ''; @@ -1050,7 +1062,7 @@ if ($resql) { print '
    '; } if (!empty($arrayfields['bu.label']['checked'])) { - print ''; + print ''; } if (!empty($arrayfields['ba.ref']['checked'])) { print '
    '; - print '
    '; + print '
    '; print ''; print '
    '; @@ -1160,7 +1172,6 @@ if ($resql) { // Loop on each record $sign = 1; - $totalarray = array(); while ($i < min($num, $limit)) { $objp = $db->fetch_object($resql); $links = $bankaccountstatic->get_url($objp->rowid); @@ -1296,18 +1307,10 @@ if ($resql) { $backgroundcolor = "class='oddeven'"; } else { if ($objp->amount < 0) { - if (empty($conf->global->BANK_COLORIZE_MOVEMENT_COLOR1)) { - $color = '#fca955'; - } else { - $color = '#'.$conf->global->BANK_COLORIZE_MOVEMENT_COLOR1; - } + $color = '#' . getDolGlobalString('BANK_COLORIZE_MOVEMENT_COLOR1', 'fca955'); $backgroundcolor = 'style="background: '.$color.';"'; } else { - if (empty($conf->global->BANK_COLORIZE_MOVEMENT_COLOR2)) { - $color = '#7fdb86'; - } else { - $color = '#'.$conf->global->BANK_COLORIZE_MOVEMENT_COLOR2; - } + $color = '#' . getDolGlobalString('BANK_COLORIZE_MOVEMENT_COLOR2', '7fdb86'); $backgroundcolor = 'style="background: '.$color.';"'; } } @@ -1333,7 +1336,7 @@ if ($resql) { $titletoshow = ''; $reg = array(); preg_match('/\((.+)\)/i', $objp->label, $reg); // Si texte entoure de parenthee on tente recherche de traduction - if ($reg[1] && $langs->trans($reg[1]) != $reg[1]) { + if (!empty($reg[1]) && $langs->trans($reg[1]) != $reg[1]) { $labeltoshow = $langs->trans($reg[1]); } else { if ($objp->label == '(payment_salary)') { @@ -1357,6 +1360,7 @@ if ($resql) { } 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); } elseif ($links[$key]['type'] == 'payment_supplier') { $paymentsupplierstatic->id = $links[$key]['url_id']; @@ -1683,7 +1687,7 @@ if ($resql) { } } if ($user->rights->banque->modifier) { - print 'rowid.'&id='.$objp->bankid.'&page='.$page.'">'; + print 'rowid.'&id='.$objp->bankid.'&page='.$page.'">'; print img_delete('', 'class="marginleftonly"'); print ''; } diff --git a/htdocs/compta/bank/bilan.php b/htdocs/compta/bank/bilan.php index 94ae0134a9d..6edee79f86b 100644 --- a/htdocs/compta/bank/bilan.php +++ b/htdocs/compta/bank/bilan.php @@ -28,7 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // Load translation files required by the page $langs->loadLangs(array('banks', 'categories')); -if (!$user->rights->banque->lire) { +if (empty($user->rights->banque->lire)) { accessforbidden(); } diff --git a/htdocs/compta/bank/card.php b/htdocs/compta/bank/card.php index 32b0ec5cb8a..c543b9edd9b 100644 --- a/htdocs/compta/bank/card.php +++ b/htdocs/compta/bank/card.php @@ -463,7 +463,7 @@ if ($action == 'create') { $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, 'edit', $parameters); + print $object->showOptionals($extrafields, 'create', $parameters); } print '
    '; @@ -698,7 +698,6 @@ if ($action == 'create') { print ''; print '
    '; - print '
    '; print '
    '; print ''; @@ -795,7 +794,6 @@ if ($action == 'create') { print '
    '; } - print '
    '; print '
    '; print ''; diff --git a/htdocs/compta/bank/categ.php b/htdocs/compta/bank/categ.php index 403caa6cdfd..2605bc39d30 100644 --- a/htdocs/compta/bank/categ.php +++ b/htdocs/compta/bank/categ.php @@ -146,8 +146,8 @@ if ($result) { //print ''.$langs->trans("List").''; print ''; print ''; - print ''.img_edit().''; - print ''.img_delete().''; + print ''.img_edit().''; + print ''.img_delete().''; print ''; } print ""; diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 9fd88f44d4f..685c78f5f1b 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -1125,12 +1125,12 @@ class Account extends CommonObject $langs->load('banks'); if ($status == self::STATUS_OPEN) { - $label = $langs->trans("StatusAccountOpened"); - $labelshort = $langs->trans("StatusAccountOpened"); + $label = $langs->transnoentitiesnoconv("StatusAccountOpened"); + $labelshort = $langs->transnoentitiesnoconv("StatusAccountOpened"); $statusType = 'status4'; } else { - $label = $langs->trans("StatusAccountClosed"); - $labelshort = $langs->trans("StatusAccountClosed"); + $label = $langs->transnoentitiesnoconv("StatusAccountClosed"); + $labelshort = $langs->transnoentitiesnoconv("StatusAccountClosed"); $statusType = 'status5'; } @@ -1503,7 +1503,7 @@ class Account extends CommonObject { $country_code = $this->getCountryCode(); - if (in_array($country_code, array('FR', 'ES', 'GA', 'IT', 'NC'))) { + if (in_array($country_code, array('AD', 'FR', 'ES', 'GA', 'IT', 'NC'))) { return 1; // France, Spain, Gabon, ... - Not valid for CH } if (in_array($country_code, array('AU', 'BE', 'CA', 'DE', 'DK', 'GR', 'GB', 'ID', 'IE', 'IR', 'KR', 'NL', 'NZ', 'UK', 'US'))) { @@ -1696,21 +1696,21 @@ class Account extends CommonObject /** * Function used to replace a thirdparty id with another one. * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param int $origin_id Old thirdparty id * @param int $dest_id New thirdparty id - * @return bool + * @return bool True=SQL success, False=SQL error */ - public static function replaceThirdparty($db, $origin_id, $dest_id) + public static function replaceThirdparty($dbs, $origin_id, $dest_id) { $sql = "UPDATE ".MAIN_DB_PREFIX."bank_url SET url_id = ".((int) $dest_id)." WHERE url_id = ".((int) $origin_id)." AND type='company'"; - if (!$db->query($sql)) { - //if ($ignoreerrors) return true; // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B. - //$this->errors = $db->lasterror(); - return false; - } else { + if ($dbs->query($sql)) { return true; + } else { + //if ($ignoreerrors) return true; // TODO Not enough. If there is A-B on kept thirdarty and B-C on old one, we must get A-B-C after merge. Not A-B. + //$this->errors = $dbs->lasterror(); + return false; } } } diff --git a/htdocs/compta/bank/document.php b/htdocs/compta/bank/document.php index ec46002b031..7dce00005f3 100644 --- a/htdocs/compta/bank/document.php +++ b/htdocs/compta/bank/document.php @@ -74,6 +74,8 @@ if ($id > 0 || !empty($ref)) { $result = restrictedArea($user, 'banque', $object->id, 'bank_account', '', ''); +$permissiontoadd = $user->rights->banque->modifier; // Used by the include of actions_dellink.inc.php + /* * Actions diff --git a/htdocs/compta/bank/info.php b/htdocs/compta/bank/info.php index c61f6e50bff..e8514c1e96e 100644 --- a/htdocs/compta/bank/info.php +++ b/htdocs/compta/bank/info.php @@ -39,7 +39,7 @@ if ($user->socid) { $socid = $user->socid; } $result = restrictedArea($user, 'banque', $fieldvalue, 'bank_account', '', '', $fieldtype); -if (!$user->rights->banque->lire && !$user->rights->banque->consolidate) { +if (empty($user->rights->banque->lire) && !$user->rights->banque->consolidate) { accessforbidden(); } diff --git a/htdocs/compta/bank/line.php b/htdocs/compta/bank/line.php index 05aed6a215e..f86c50f31cc 100644 --- a/htdocs/compta/bank/line.php +++ b/htdocs/compta/bank/line.php @@ -63,11 +63,12 @@ $cancel = GETPOST('cancel', 'alpha'); // Security check $fieldvalue = (!empty($id) ? $id : (!empty($ref) ? $ref : '')); $fieldtype = (!empty($ref) ? 'ref' : 'rowid'); +$socid = 0; if ($user->socid) { $socid = $user->socid; } $result = restrictedArea($user, 'banque', $fieldvalue, 'bank_account', '', '', $fieldtype); -if (!$user->rights->banque->lire && !$user->rights->banque->consolidate) { +if (empty($user->rights->banque->lire) && !$user->rights->banque->consolidate) { accessforbidden(); } @@ -568,6 +569,12 @@ if ($result) { // Bank line print ''.$form->editfieldkey('RubriquesTransactions', 'custcats', '', $object, 0).''; $cate_arbo = $form->select_all_categories(Categorie::TYPE_BANK_LINE, null, 'parent', null, null, 1); + $arrayselected = array(); + $c = new Categorie($db); + $cats = $c->containing($bankline->id, Categorie::TYPE_BANK_LINE); + foreach ($cats as $cat) { + $arrayselected[] = $cat->id; + } print img_picto('', 'category', 'class="paddingright"').$form->multiselectarray('custcats', $cate_arbo, $arrayselected, null, null, null, null, "90%"); print ""; } diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php index cd6e6cfd365..ea656141639 100644 --- a/htdocs/compta/bank/list.php +++ b/htdocs/compta/bank/list.php @@ -506,6 +506,8 @@ print "\n"; $totalarray = array(); $totalarray['nbfield'] = 0; +$totalarray['val'] = array('balance'=>0); +$total = array(); $found = 0; $i = 0; $lastcurrencycode = ''; @@ -714,7 +716,11 @@ foreach ($accounts as $key => $type) { print ''; - $total[$objecttmp->currency_code] += $solde; + if (empty($total[$objecttmp->currency_code])) { + $total[$objecttmp->currency_code] = $solde; + } else { + $total[$objecttmp->currency_code] += $solde; + } $i++; } diff --git a/htdocs/compta/bank/releve.php b/htdocs/compta/bank/releve.php index 97184c1b8eb..af0b388cb7a 100644 --- a/htdocs/compta/bank/releve.php +++ b/htdocs/compta/bank/releve.php @@ -364,7 +364,7 @@ if (empty($numref)) { print ''; if ($user->rights->banque->consolidate && $action != 'editbankreceipt') { - print 'numr.'">'.img_edit().''; + print 'numr).'">'.img_edit().''; } print ''; diff --git a/htdocs/compta/bank/various_payment/card.php b/htdocs/compta/bank/various_payment/card.php index 68c6ed20458..d4245594447 100644 --- a/htdocs/compta/bank/various_payment/card.php +++ b/htdocs/compta/bank/various_payment/card.php @@ -540,7 +540,7 @@ if ($id) { array('type' => 'date', 'name' => 'clone_date_value', 'label' => $langs->trans("DateValue"), 'value' => -1), array('type' => 'other', 'tdclass'=>'fieldrequired', 'name' => 'clone_accountid', 'label' => $langs->trans("BankAccount"), 'value' => $form->select_comptes($object->fk_account, "accountid", 0, '', 1, '', 0, 'minwidth200', 1)), array('type' => 'text', 'name' => 'clone_amount', 'label' => $langs->trans("Amount"), 'value' => price($object->amount)), - array('type' => 'select', 'name' => 'clone_sens', 'label' => $langs->trans("Sens") . ' ' . $set_value_help, 'values' => $sensarray, 'default' => $object->sens), + array('type' => 'select', 'name' => 'clone_sens', 'label' => $langs->trans("Sens").' '.$set_value_help, 'values' => $sensarray, 'default' => $object->sens), ); print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneVariousPayment', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 350); @@ -555,7 +555,7 @@ if ($id) { $morehtmlref .= $langs->trans('Project').' '; if ($user->rights->banque->modifier) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); diff --git a/htdocs/compta/bank/various_payment/document.php b/htdocs/compta/bank/various_payment/document.php index 1b5fd5fd383..ad199caaf5a 100644 --- a/htdocs/compta/bank/various_payment/document.php +++ b/htdocs/compta/bank/various_payment/document.php @@ -69,6 +69,9 @@ $object->fetch($id, $ref); $upload_dir = $conf->bank->dir_output.'/'.dol_sanitizeFileName($object->id); $modulepart = 'banque'; +$permissiontoadd = $user->rights->banque->modifier; // Used by the include of actions_dellink.inc.php + + /* * Actions @@ -99,7 +102,7 @@ if ($object->id) { $morehtmlref .= $langs->trans('Project').' : '; if ($user->rights->banque->modifier && 0) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); diff --git a/htdocs/compta/bank/various_payment/info.php b/htdocs/compta/bank/various_payment/info.php index b173426e179..e50dc10ff7f 100644 --- a/htdocs/compta/bank/various_payment/info.php +++ b/htdocs/compta/bank/various_payment/info.php @@ -62,7 +62,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= $langs->trans('Project').' : '; if ($user->rights->banque->modifier && 0) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); diff --git a/htdocs/compta/cashcontrol/cashcontrol_card.php b/htdocs/compta/cashcontrol/cashcontrol_card.php index 26949590334..c7b74abfc39 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_card.php +++ b/htdocs/compta/cashcontrol/cashcontrol_card.php @@ -107,9 +107,9 @@ if (!$user->rights->cashdesk->run && !$user->rights->takepos->run) { $permissiontoadd = ($user->rights->cashdesk->run || $user->rights->takepos->run); $permissiontodelete = ($user->rights->cashdesk->run || $user->rights->takepos->run) || ($permissiontoadd && $object->status == 0); if (empty($backtopage)) { - $backtopage = dol_buildpath('/compta/cashcontrol/cashcontrol_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + $backtopage = DOL_URL_ROOT.'/compta/cashcontrol/cashcontrol_card.php?id='.($id > 0 ? $id : '__ID__'); } -$backurlforlist = dol_buildpath('/compta/cashcontrol/cashcontrol_list.php', 1); +$backurlforlist = DOL_URL_ROOT.'/compta/cashcontrol/cashcontrol_list.php'; $triggermodname = 'CACHCONTROL_MODIFY'; // Name of trigger action code to execute when we modify record if (empty($conf->global->CASHDESK_ID_BANKACCOUNT_CASH) && empty($conf->global->CASHDESK_ID_BANKACCOUNT_CASH1)) { @@ -647,9 +647,10 @@ if (empty($action) || $action == "view" || $action == "close") { print ''; print ''; - print '
    '; + print '
    >'; print '
    '; - print ''; + + print '
    '; print '
    '; print $langs->trans("DateCreationShort"); @@ -667,7 +668,7 @@ if (empty($action) || $action == "view" || $action == "close") { } print "
    \n"; - print '
    '; + print '
    '; print '
    '; @@ -679,11 +680,11 @@ if (empty($action) || $action == "view" || $action == "close") { print ''; if ($object->status == CashControl::STATUS_DRAFT) { - print ''; + print ''; - print ''; + print ''; } else { - print ''; + print ''; } print ''; diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php index dbaaf882bfb..89781fcb211 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_list.php +++ b/htdocs/compta/cashcontrol/cashcontrol_list.php @@ -22,27 +22,6 @@ * \brief List page for cashcontrol */ -//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Do not create database handler $db -//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Do not load object $user -//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); // Do not load object $mysoc -//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Do not load object $langs -//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check injection attack on GET parameters -//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check injection attack on POST parameters -//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). -//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) -//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data -//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu -//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); // If we don't need to load the html.form.class.php -//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); // Do not load ajax.lib.php library -//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. -//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip -//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT','auto'); // Force lang to a particular value -//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE','aloginmodule'); // Force authentication handler -//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN',1); // The main.inc.php does not make a redirect if not logged, instead show simple error message -//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies -//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET -//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification - require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/compta/cashcontrol/class/cashcontrol.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; @@ -81,7 +60,7 @@ $pagenext = $page + 1; // Initialize technical objects $object = new CashControl($db); $extrafields = new ExtraFields($db); -$diroutputmassaction = $conf->monmodule->dir_output.'/temp/massgeneration/'.$user->id; +//$diroutputmassaction = $conf->mymodule->dir_output.'/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('cashcontrol')); // Note that conf->hooks_modules contains array // Fetch optionals attributes and labels @@ -141,16 +120,16 @@ 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 = ($user->rights->cashdesk->run || $user->rights->takepos->run); -$permissiontoadd = ($user->rights->cashdesk->run || $user->rights->takepos->run); -$permissiontodelete = ($user->rights->cashdesk->run || $user->rights->takepos->run); +$permissiontoread = (!empty($user->rights->cashdesk->run) || !empty($user->rights->takepos->run)); +$permissiontoadd = (!empty($user->rights->cashdesk->run) || !empty($user->rights->takepos->run)); +$permissiontodelete = (!empty($user->rights->cashdesk->run) || !empty($user->rights->takepos->run)); // Security check if ($user->socid > 0) { // Protection if external user //$socid = $user->socid; accessforbidden(); } -if (!$user->rights->cashdesk->run && !$user->rights->takepos->run) { +if (empty($user->rights->cashdesk->run) && empty($user->rights->takepos->run)) { accessforbidden(); } @@ -223,7 +202,7 @@ $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 @@ -341,7 +320,7 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $ // Output page // -------------------------------------------------------------------- -llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', 'classforhorizontalscrolloftabs'); +llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'classforhorizontalscrolloftabs'); $arrayofselected = is_array($toselect) ? $toselect : array(); @@ -578,7 +557,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { if (!$i) { $totalarray['nbfield']++; } - if (!empty($val['isameasure'])) { + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; } diff --git a/htdocs/compta/cashcontrol/class/cashcontrol.class.php b/htdocs/compta/cashcontrol/class/cashcontrol.class.php index 27f3b974a79..5308c8df1d6 100644 --- a/htdocs/compta/cashcontrol/class/cashcontrol.class.php +++ b/htdocs/compta/cashcontrol/class/cashcontrol.class.php @@ -378,10 +378,10 @@ class CashControl extends CommonObject if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("mymodule"); - $this->labelStatus[0] = $langs->trans('Draft'); - $this->labelStatus[1] = $langs->trans('Closed'); - $this->labelStatusShort[0] = $langs->trans('Draft'); - $this->labelStatusShort[1] = $langs->trans('Closed'); + $this->labelStatus[0] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatus[1] = $langs->transnoentitiesnoconv('Closed'); + $this->labelStatusShort[0] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatusShort[1] = $langs->transnoentitiesnoconv('Closed'); } $statusType = 'status0'; diff --git a/htdocs/compta/clients.php b/htdocs/compta/clients.php index 504e5638abc..b39364690a6 100644 --- a/htdocs/compta/clients.php +++ b/htdocs/compta/clients.php @@ -94,16 +94,16 @@ if ($mode == 'search') { $sql = "SELECT s.rowid, s.nom as name, s.client, s.town, s.datec, s.datea"; $sql .= ", st.libelle as stcomm, s.prefix_comm, s.code_client, s.code_compta "; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user "; } $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."c_stcomm as st"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.fk_stcomm = st.id AND s.client in (1, 3)"; $sql .= " AND s.entity IN (".getEntity('societe').")"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if (dol_strlen($stcomm)) { diff --git a/htdocs/compta/deplacement/card.php b/htdocs/compta/deplacement/card.php index 6f390e82552..33b453cd0b4 100644 --- a/htdocs/compta/deplacement/card.php +++ b/htdocs/compta/deplacement/card.php @@ -431,7 +431,7 @@ if ($action == 'create') { print $langs->trans('Project'); print ''; if ($action != 'classify' && $user->rights->deplacement->creer) { - print 'id.'">'; + print 'id.'">'; print img_edit($langs->trans('SetProject'), 1); print ''; } @@ -469,7 +469,7 @@ if ($action == 'create') { if ($object->statut < Deplacement::STATUS_REFUNDED) { // if not refunded if ($user->rights->deplacement->creer) { - print ''.$langs->trans('Modify').''; + print ''.$langs->trans('Modify').''; } else { print ''.$langs->trans('Modify').''; } @@ -485,7 +485,7 @@ if ($action == 'create') { if ($object->statut == Deplacement::STATUS_VALIDATED) { // if validated if ($user->rights->deplacement->creer) { - print ''.$langs->trans('ClassifyRefunded').''; + print ''.$langs->trans('ClassifyRefunded').''; } else { print ''.$langs->trans('ClassifyRefunded').''; } diff --git a/htdocs/compta/deplacement/document.php b/htdocs/compta/deplacement/document.php index cdb4b5f0f0f..2a16d6e4f49 100644 --- a/htdocs/compta/deplacement/document.php +++ b/htdocs/compta/deplacement/document.php @@ -42,12 +42,6 @@ $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'deplacement', $id, ''); - // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; @@ -74,6 +68,14 @@ $object->fetch($id, $ref); $upload_dir = $conf->deplacement->dir_output.'/'.dol_sanitizeFileName($object->ref); $modulepart = 'trip'; +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'deplacement', $id, ''); + +$permissiontoadd = $user->rights->deplacement->creer; // Used by the include of actions_dellink.inc.php + /* * Actions diff --git a/htdocs/compta/deplacement/index.php b/htdocs/compta/deplacement/index.php index 12351032b53..d588b7bff80 100644 --- a/htdocs/compta/deplacement/index.php +++ b/htdocs/compta/deplacement/index.php @@ -141,7 +141,7 @@ print ''; -print '
    '; +print '
    '; $max = 10; @@ -150,7 +150,7 @@ $langs->load("boxes"); $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, d.rowid, d.dated as date, d.tms as dm, d.km, d.fk_statut"; $sql .= " FROM ".MAIN_DB_PREFIX."deplacement as d, ".MAIN_DB_PREFIX."user as u"; -if (!$user->rights->societe->client->voir && !$user->socid) { +if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE u.rowid = d.fk_user"; @@ -158,7 +158,7 @@ $sql .= " AND d.entity = ".$conf->entity; if (empty($user->rights->deplacement->readall) && empty($user->rights->deplacement->lire_tous)) { $sql .= ' AND d.fk_user IN ('.$db->sanitize(join(',', $childids)).')'; } -if (!$user->rights->societe->client->voir && !$user->socid) { +if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND d.fk_soc = s. rowid AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -212,7 +212,7 @@ if ($result) { } -print '
    '; +print ''; // End of page llxFooter(); diff --git a/htdocs/compta/deplacement/list.php b/htdocs/compta/deplacement/list.php index 428eacbc93a..e7593406ad6 100644 --- a/htdocs/compta/deplacement/list.php +++ b/htdocs/compta/deplacement/list.php @@ -96,7 +96,7 @@ $sql .= " u.lastname, u.firstname"; // Qui $sql .= " FROM ".MAIN_DB_PREFIX."user as u"; $sql .= ", ".MAIN_DB_PREFIX."deplacement as d"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON d.fk_soc = s.rowid"; -if (!$user->rights->societe->client->voir && !$socid) { +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 d.fk_user = u.rowid"; @@ -104,7 +104,7 @@ $sql .= " AND d.entity = ".$conf->entity; if (empty($user->rights->deplacement->readall) && empty($user->rights->deplacement->lire_tous)) { $sql .= ' AND d.fk_user IN ('.$db->sanitize(join(',', $childids)).')'; } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND (sc.fk_user = ".((int) $user->id)." OR d.fk_soc IS NULL) "; } if ($socid) { diff --git a/htdocs/compta/deplacement/stats/index.php b/htdocs/compta/deplacement/stats/index.php index edc590119ef..8e4860bd2f2 100644 --- a/htdocs/compta/deplacement/stats/index.php +++ b/htdocs/compta/deplacement/stats/index.php @@ -163,7 +163,7 @@ if (!$mesg) { $data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png'; if ($mode == 'customer') { $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png'; @@ -302,7 +302,7 @@ foreach ($data as $val) { print ''; print ''; -print '
    '; +print '
    '; // Show graphs @@ -319,7 +319,7 @@ if ($mesg) { print ''; -print '
    '; +print ''; print '
    '; diff --git a/htdocs/compta/facture/card-rec.php b/htdocs/compta/facture/card-rec.php index 99e09130011..7f70a447c38 100644 --- a/htdocs/compta/facture/card-rec.php +++ b/htdocs/compta/facture/card-rec.php @@ -1201,7 +1201,7 @@ if ($action == 'create') { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->facture->creer) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -1218,9 +1218,10 @@ if ($action == 'create') { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -1269,7 +1270,7 @@ if ($action == 'create') { print $langs->trans('PaymentConditionsShort'); print ''; if ($action != 'editconditions' && $user->rights->facture->creer) { - print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; } print ''; print ''; @@ -1290,7 +1291,7 @@ if ($action == 'create') { print $langs->trans('PaymentMode'); print ''; if ($action != 'editmode' && $user->rights->facture->creer) { - print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; } print ''; print ''; @@ -1310,7 +1311,7 @@ if ($action == 'create') { print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0); print ''; if ($usercancreate && $action != 'editmulticurrencycode' && !empty($object->brouillon)) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -1326,7 +1327,7 @@ if ($action == 'create') { print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0); print ''; if ($usercancreate && $action != 'editmulticurrencyrate' && !empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -1398,7 +1399,7 @@ if ($action == 'create') { print $langs->trans('BankAccount'); print ''; if (($action != 'editbankaccount') && $user->rights->facture->creer && $object->statut == FactureRec::STATUS_DRAFT) { - print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; } print ''; print ''; @@ -1416,7 +1417,7 @@ if ($action == 'create') { print $langs->trans('Model'); print ''; if (($action != 'editmodelpdf') && $user->rights->facture->creer && $object->statut == FactureRec::STATUS_DRAFT) { - print 'id.'">'.img_edit($langs->trans('SetModel'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetModel'), 1).''; } print ''; print ''; @@ -1443,7 +1444,6 @@ if ($action == 'create') { print ''; print '
    '; - print '
    '; print '
    '; @@ -1463,7 +1463,7 @@ if ($action == 'create') { print $langs->trans('Frequency'); print ''; if ($action != 'editfrequency' && $user->rights->facture->creer) { - print 'id.'">'.img_edit($langs->trans('Edit'), 1).''; + print 'id.'">'.img_edit($langs->trans('Edit'), 1).''; } print ''; print ''; @@ -1591,7 +1591,6 @@ if ($action == 'create') { print '
    '; } - print '
    '; print '
    '; print ''; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 99bf843f50b..ab1ab9f5dd7 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -408,13 +408,21 @@ if (empty($reshook)) { } elseif ($action == 'setinvoicedate' && $usercancreate) { $object->fetch($id); $old_date_lim_reglement = $object->date_lim_reglement; - $date = dol_mktime(12, 0, 0, GETPOST('invoicedatemonth', 'int'), GETPOST('invoicedateday', 'int'), GETPOST('invoicedateyear', 'int')); - if (empty($date)) { + $newdate = dol_mktime(0, 0, 0, GETPOST('invoicedatemonth', 'int'), GETPOST('invoicedateday', 'int'), GETPOST('invoicedateyear', 'int'), 'tzserver'); + if (empty($newdate)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); - header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate'); + header('Location: '.$_SERVER["PHP_SELF"].'?facid='.$id.'&action=editinvoicedate&token='.newToken()); exit; } - $object->date = $date; + if ($newdate > (dol_now('tzuserrel') + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + if (empty($conf->global->INVOICE_MAX_FUTURE_DELAY)) { + setEventMessages($langs->trans("WarningInvoiceDateInFuture"), null, 'warnings'); + } else { + setEventMessages($langs->trans("WarningInvoiceDateTooFarInFuture"), null, 'warnings'); + } + } + + $object->date = $newdate; $new_date_lim_reglement = $object->calculate_date_lim_reglement(); if ($new_date_lim_reglement > $old_date_lim_reglement) { $object->date_lim_reglement = $new_date_lim_reglement; @@ -428,7 +436,9 @@ if (empty($reshook)) { } } elseif ($action == 'setdate_pointoftax' && $usercancreate) { $object->fetch($id); - $date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']); + + $date_pointoftax = dol_mktime(0, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int'), 'tzserver'); + $object->date_pointoftax = $date_pointoftax; $result = $object->update($user); if ($result < 0) { @@ -1001,14 +1011,16 @@ if (empty($reshook)) { $error++; } + $dateinvoice = dol_mktime(0, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'), 'tzserver'); // If we enter the 02 january, we need to save the 02 january for server + $date_pointoftax = dol_mktime(0, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int'), 'tzserver'); + // Replacement invoice if (GETPOST('type') == Facture::TYPE_REPLACEMENT) { - $dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); if (empty($dateinvoice)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); $action = 'create'; - } elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors'); $action = 'create'; @@ -1020,8 +1032,6 @@ if (empty($reshook)) { $action = 'create'; } - $date_pointoftax = dol_mktime(12, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); - if (!$error) { // This is a replacement invoice $result = $object->fetch(GETPOST('fac_replacement', 'int')); @@ -1064,19 +1074,16 @@ if (empty($reshook)) { $action = 'create'; } - $dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); if (empty($dateinvoice)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); $action = 'create'; - } elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors'); $action = 'create'; } - $date_pointoftax = dol_mktime(12, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); - if (!$error) { if (!empty($originentity)) { $object->entity = $originentity; @@ -1280,19 +1287,16 @@ if (empty($reshook)) { // Standard invoice or Deposit invoice, created from a Predefined template invoice if ((GETPOST('type') == Facture::TYPE_STANDARD || GETPOST('type') == Facture::TYPE_DEPOSIT) && GETPOST('fac_rec', 'int') > 0) { - $dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); if (empty($dateinvoice)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); $action = 'create'; - } elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors'); $action = 'create'; } - $date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']); - if (!$error) { $object->socid = GETPOST('socid', 'int'); $object->type = GETPOST('type'); @@ -1327,8 +1331,6 @@ if (empty($reshook)) { $typeamount = GETPOST('typedeposit', 'aZ09'); $valuestandardinvoice = price2num(str_replace('%', '', GETPOST('valuestandardinvoice', 'alpha')), 'MU'); $valuedeposit = price2num(str_replace('%', '', GETPOST('valuedeposit', 'alpha')), 'MU'); - $dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); - $date_pointoftax = dol_mktime(12, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); if (GETPOST('socid', 'int') < 1) { $error++; @@ -1340,7 +1342,7 @@ if (empty($reshook)) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors'); $action = 'create'; - } elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors'); $action = 'create'; @@ -1822,19 +1824,16 @@ if (empty($reshook)) { // Situation invoices if (GETPOST('type') == Facture::TYPE_SITUATION && GETPOST('situations')) { - $dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); if (empty($dateinvoice)) { $error++; $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")); setEventMessages($mesg, null, 'errors'); - } elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors'); $action = 'create'; } - $date_pointoftax = dol_mktime(12, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); - if (!(GETPOST('situations', 'int') > 0)) { $error++; $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("InvoiceSituation")); @@ -2847,6 +2846,7 @@ if (empty($reshook)) { * View */ + $form = new Form($db); $formother = new FormOther($db); $formfile = new FormFile($db); @@ -3529,7 +3529,8 @@ if ($action == 'create') { print ''; } - $newdateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); + $newdateinvoice = dol_mktime(0, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'), 'tzserver'); + $date_pointoftax = dol_mktime(0, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int'), 'tzserver'); // Date invoice print ''.$langs->trans('DateInvoice').''; @@ -3539,7 +3540,6 @@ if ($action == 'create') { // Date point of tax if (!empty($conf->global->INVOICE_POINTOFTAX_DATE)) { print ''.$langs->trans('DatePointOfTax').''; - $date_pointoftax = dol_mktime(12, 0, 0, GETPOST('date_pointoftaxmonth', 'int'), GETPOST('date_pointoftaxday', 'int'), GETPOST('date_pointoftaxyear', 'int')); print $form->selectDate($date_pointoftax ? $date_pointoftax : -1, 'date_pointoftax', '', '', '', "add", 1, 1); print ''; } @@ -3652,7 +3652,7 @@ if ($action == 'create') { } }; - print $object->showOptionals($extrafields, 'edit', $parameters); + print $object->showOptionals($extrafields, 'create', $parameters); } // Template to use by default @@ -3746,8 +3746,9 @@ if ($action == 'create') { print ''."\n"; print ''."\n"; print ''."\n"; - print ''; - print ''; + // The commented lines below are fields already added as hidden parameters before + //print ''; + //print ''; switch (get_class($objectsrc)) { case 'Propal': @@ -3818,8 +3819,16 @@ if ($action == 'create') { print ''; } - print ''; + print "\n"; } elseif ($id > 0 || !empty($ref)) { + if (empty($object->id)) { + llxHeader(); + $langs->load('errors'); + echo '
    '.$langs->trans("ErrorRecordNotFound").'
    '; + llxFooter(); + exit; + } + /* * Show object in view mode */ @@ -3848,15 +3857,25 @@ if ($action == 'create') { $totalpaye = $object->getSommePaiement(); $totalcreditnotes = $object->getSumCreditNotesUsed(); $totaldeposits = $object->getSumDepositsUsed(); - // print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." + //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." // selleruserrevenuestamp=".$selleruserevenustamp; // 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($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); // $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); + $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + // Multicurrency + if (!empty($conf->multicurrency->enabled)) { + $multicurrency_totalpaye = $object->getSommePaiement(1); + $multicurrency_totalcreditnotes = $object->getSumCreditNotesUsed(1); + $multicurrency_totaldeposits = $object->getSumDepositsUsed(1); + $multicurrency_resteapayer = price2num($object->multicurrency_total_ttc - $multicurrency_totalpaye - $multicurrency_totalcreditnotes - $multicurrency_totaldeposits, 'MT'); + $resteapayer = price2num($multicurrency_resteapayer / $object->multicurrency_tx, 'MT'); + } + if ($object->paye) { $resteapayer = 0; } @@ -4014,6 +4033,21 @@ if ($action == 'create') { if ($object->type != Facture::TYPE_CREDIT_NOTE && $object->total_ttc < 0) { // Can happen only if $conf->global->FACTURE_ENABLE_NEGATIVE is on $text .= '
    '.img_warning().' '.$langs->trans("ErrorInvoiceOfThisTypeMustBePositive"); } + + // mandatoryPeriod + $nbMandated = 0; + foreach ($object->lines as $line) { + $res = $line->fetch_product(); + if ($res > 0 ) { + if ($line->product->isService() && $line->product->isMandatoryPeriod() && (empty($line->date_start) || empty($line->date_end) )) { + $nbMandated++; + break; + } + } + } + if ($nbMandated > 0 ) $text .= '
    '.$langs->trans("mandatoryPeriodNeedTobeSetMsgValidate").'
    '; + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ValidateBill'), $text, 'confirm_valid', $formquestion, (($object->type != Facture::TYPE_CREDIT_NOTE && $object->total_ttc < 0) ? "no" : "yes"), 2); } @@ -4058,10 +4092,10 @@ if ($action == 'create') { } // Confirmation du classement paye - if ($action == 'paid' && $resteapayer <= 0) { + if ($action == 'paid' && ($resteapayer <= 0 || (!empty($conf->global->INVOICE_CAN_ADD_PAYMENT_EVEN_IF_ALREADY_PAID) && $resteapayer == $object->total_ttc))) { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?facid='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', "yes", 1); } - if ($action == 'paid' && $resteapayer > 0) { + if ($action == 'paid' && $resteapayer > 0 && (empty($conf->global->INVOICE_CAN_ADD_PAYMENT_EVEN_IF_ALREADY_PAID) || $resteapayer != $object->total_ttc)) { $close = array(); // Code $i = 0; @@ -4069,6 +4103,8 @@ if ($action == 'create') { $i++; $close[$i]['code'] = 'badcustomer'; $i++; + $close[$i]['code'] = 'bankcharge'; + $i++; $close[$i]['code'] = 'other'; $i++; // Help @@ -4077,6 +4113,8 @@ if ($action == 'create') { $i++; $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBadCustomerDesc"); $i++; + $close[$i]['label'] = $langs->trans("ConfirmClassifyPaidPartiallyReasonBankChargeDesc"); + $i++; $close[$i]['label'] = $langs->trans("Other"); $i++; // Texte @@ -4085,6 +4123,8 @@ if ($action == 'create') { $i++; $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBadCustomer", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1); $i++; + $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("ConfirmClassifyPaidPartiallyReasonBankCharge", $resteapayer, $langs->trans("Currency".$conf->currency)), $close[$i]['label'], 1); + $i++; $close[$i]['reason'] = $form->textwithpicto($langs->transnoentities("Other"), $close[$i]['label'], 1); $i++; // arrayreasons[code]=reason @@ -4202,7 +4242,7 @@ if ($action == 'create') { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($usercancreate) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -4219,9 +4259,10 @@ if ($action == 'create') { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -4322,7 +4363,7 @@ if ($action == 'create') { print $langs->trans('DateInvoice'); print ''; if ($action != 'editinvoicedate' && !empty($object->brouillon) && $usercancreate && empty($conf->global->FAC_FORCE_DATE_VALIDATION)) { - print 'id.'">'.img_edit($langs->trans('SetDate'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetDate'), 1).''; } print ''; print ''; @@ -4342,7 +4383,7 @@ if ($action == 'create') { print ''; - print ''; + print ''; print '
    '; print $langs->trans('DatePointOfTax'); print 'id.'">'.img_edit($langs->trans('SetDate'), 1).'id.'">'.img_edit($langs->trans('SetDate'), 1).'
    '; print ''; if ($action == 'editdate_pointoftax') { @@ -4359,7 +4400,7 @@ if ($action == 'create') { print $langs->trans('PaymentConditionsShort'); print ''; if ($object->type != Facture::TYPE_CREDIT_NOTE && $action != 'editconditions' && $usercancreate) { - print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; } print ''; print ''; @@ -4380,7 +4421,7 @@ if ($action == 'create') { print $langs->trans('DateMaxPayment'); print ''; if ($object->type != Facture::TYPE_CREDIT_NOTE && $action != 'editpaymentterm' && $usercancreate) { - print 'id.'">'.img_edit($langs->trans('SetDate'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetDate'), 1).''; } print ''; print ''; @@ -4404,7 +4445,7 @@ if ($action == 'create') { print $langs->trans('PaymentMode'); print ''; if ($action != 'editmode' && $usercancreate) { - print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; } print ''; print ''; @@ -4424,7 +4465,7 @@ if ($action == 'create') { print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0); print ''; if ($usercancreate && $action != 'editmulticurrencycode' && !empty($object->brouillon)) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -4440,7 +4481,7 @@ if ($action == 'create') { print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0); print ''; if ($usercancreate && $action != 'editmulticurrencyrate' && !empty($object->brouillon) && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -4468,7 +4509,7 @@ if ($action == 'create') { print $langs->trans('BankAccount'); print ''; if (($action != 'editbankaccount') && $usercancreate) { - print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; } print ''; print ''; @@ -4488,7 +4529,7 @@ if ($action == 'create') { print $langs->trans('IncotermLabel'); print ''; if ($usercancreate) { - print ''.img_edit().''; + print ''.img_edit().''; } else { print ' '; } @@ -4518,7 +4559,7 @@ if ($action == 'create') { print $langs->trans('RetainedWarranty'); print ''; if ($action != 'editretainedwarranty' && $user->rights->facture->creer) { - print 'id.'">'.img_edit($langs->trans('setretainedwarranty'), 1).''; + print 'id.'">'.img_edit($langs->trans('setretainedwarranty'), 1).''; } print ''; @@ -4541,7 +4582,7 @@ if ($action == 'create') { print $langs->trans('PaymentConditionsShortRetainedWarranty'); print ''; if ($action != 'editretainedwarrantypaymentterms' && $user->rights->facture->creer) { - print 'id.'">'.img_edit($langs->trans('setPaymentConditionsShortRetainedWarranty'), 1).''; + print 'id.'">'.img_edit($langs->trans('setPaymentConditionsShortRetainedWarranty'), 1).''; } print ''; @@ -4576,7 +4617,7 @@ if ($action == 'create') { print $langs->trans('RetainedWarrantyDateLimit'); print ''; if ($action != 'editretainedwarrantydatelimit' && $user->rights->facture->creer) { - print 'id.'">'.img_edit($langs->trans('setretainedwarrantyDateLimit'), 1).''; + print 'id.'">'.img_edit($langs->trans('setretainedwarrantyDateLimit'), 1).''; } print ''; @@ -4610,7 +4651,6 @@ if ($action == 'create') { print ''; print '
    '; - print '
    '; print ''."\n"; print ''; @@ -4662,7 +4702,7 @@ if ($action == 'create') { print $langs->trans('RevenueStamp'); print ''; if ($action != 'editrevenuestamp' && !empty($object->brouillon) && $usercancreate) { - print ''; + print ''; } print '
    id.'">'.img_edit($langs->trans('SetRevenuStamp'), 1).'id.'">'.img_edit($langs->trans('SetRevenuStamp'), 1).'
    '; print ''; @@ -4673,7 +4713,7 @@ if ($action == 'create') { print ''; print $formother->select_revenue_stamp('', 'revenuestamp_type', $mysoc->country_code); print ' → '; - print ' '; + print ' '; print ''; print " '; + $stringtoshow .= '
    '; // hideobject is to start hidden + $stringtoshow .= '
    '; + $stringtoshow .= ''; + $stringtoshow .= ''; + $stringtoshow .= ''; + $stringtoshow .= ''; + $stringtoshow .= $langs->trans("Year").' '; + $stringtoshow .= ''; + $stringtoshow .= '
    '; + $stringtoshow .= '
    '; + $stringtoshow .= $px2->show(); + $this->info_box_contents[0][0] = array('tr'=>'class="oddeven nohover"', 'td' => 'class="nohover center"', 'textnoformat'=>$stringtoshow); + } else { + $this->info_box_contents[0][0] = array('tr'=>'class="oddeven nohover"', 'td' => 'class="nohover left"', 'maxlength'=>500, 'text' => $mesg); + } + } else { + $this->info_box_contents[0][0] = array( + 'td' => 'class="nohover 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_graph_invoices_supplier_permonth.php b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php index 5ecc26c3f90..3d8cb88938d 100644 --- a/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php +++ b/htdocs/core/boxes/box_graph_invoices_supplier_permonth.php @@ -98,7 +98,7 @@ class box_graph_invoices_supplier_permonth extends ModeleBoxes if ($user->socid) { $socid = $user->socid; } - if (!$user->rights->societe->client->voir || $socid) { + if (empty($user->rights->societe->client->voir) || $socid) { $prefix .= 'private-'.$user->id.'-'; // If user has no permission to see all, output dir is specific to user } 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 baa822dcf29..1c0e7a6e3ff 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 @@ -65,6 +65,8 @@ class box_graph_nb_ticket_last_x_days extends ModeleBoxes public function loadBox($max = 5) { global $conf, $user, $langs; + $dataseries = array(); + $graphtoshow = ""; $badgeStatus0 = '#cbd3d3'; // draft $badgeStatus1 = '#bc9526'; // validated @@ -78,14 +80,14 @@ class box_graph_nb_ticket_last_x_days extends ModeleBoxes $badgeStatus7 = '#baa32b'; $badgeStatus8 = '#993013'; $badgeStatus9 = '#e7f0f0'; - if (file_exists(DOL_DOCUMENT_ROOT . '/theme/' . $conf->theme . '/theme_vars.inc.php')) { - include DOL_DOCUMENT_ROOT . '/theme/' . $conf->theme . '/theme_vars.inc.php'; + if (file_exists(DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php')) { + include DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; } $this->max = $max; $param_day = 'DOLUSERCOOKIE_ticket_last_days'; - if ($_POST[$param_day]) { + if (!empty($_POST[$param_day])) { if ($_POST[$param_day] >= 15) { $days = 14; } else { @@ -95,28 +97,27 @@ class box_graph_nb_ticket_last_x_days extends ModeleBoxes $days = 7; } require_once DOL_DOCUMENT_ROOT."/ticket/class/ticket.class.php"; - $text = $langs->trans("BoxTicketLastXDays", $days).' ' . img_picto('', 'filter.png', 'id="idsubimgDOLUSERCOOKIE_ticket_last_days" class="linkobject"'); + $text = $langs->trans("BoxTicketLastXDays", $days).' '.img_picto('', 'filter.png', 'id="idsubimgDOLUSERCOOKIE_ticket_last_days" class="linkobject"'); $this->info_box_head = array( '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'); + $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)); 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 .= " FROM ".MAIN_DB_PREFIX."ticket as t"; + $sql .= " WHERE CAST(t.datec AS DATE) > DATE_SUB(CURRENT_DATE, INTERVAL ".$days." DAY)"; $sql .= " GROUP BY CAST(t.datec AS DATE)"; $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); $i = 0; - $dataseries = array(); while ($i < $num) { $objp = $this->db->fetch_object($resql); while ($minimumdatecformated < $objp->datec) { @@ -147,12 +148,12 @@ class box_graph_nb_ticket_last_x_days extends ModeleBoxes }); '; $stringtoshow .= '
    '; // hideobject is to start hidden - $stringtoshow .= '
    '; - $stringtoshow .= ''; + $stringtoshow .= ''; + $stringtoshow .= ''; $stringtoshow .= ''; $stringtoshow .= ''; - $stringtoshow .= ' ' . $langs->trans("Days"); - $stringtoshow .= ''; + $stringtoshow .= ' '.$langs->trans("Days"); + $stringtoshow .= ''; $stringtoshow .= '
    '; $stringtoshow .= '
    '; @@ -180,21 +181,21 @@ class box_graph_nb_ticket_last_x_days extends ModeleBoxes $px1->mode = 'depth'; $px1->draw('idgraphticketlastxdays'); - $graphtoshow= $px1->show($totalnb ? 0 : 1); + $graphtoshow = $px1->show($totalnb ? 0 : 1); } if ($totalnb) { $stringtoshow .= $graphtoshow; } $stringtoshow .= '
    '; if ($totalnb) { - $this->info_box_contents[][]=array( + $this->info_box_contents[][] = array( 'td' => 'center', 'text' => $stringtoshow ); } else { $this->info_box_contents[0][0] = array( 'td' => 'class="center opacitymedium"', - 'text' => $stringtoshow . $langs->trans("BoxNoTicketLastXDays", $days) + 'text' => $stringtoshow.$langs->trans("BoxNoTicketLastXDays", $days) ); } } else { diff --git a/htdocs/core/boxes/box_graph_new_vs_close_ticket.php b/htdocs/core/boxes/box_graph_new_vs_close_ticket.php index a4bf2d6990f..435cc76451e 100644 --- a/htdocs/core/boxes/box_graph_new_vs_close_ticket.php +++ b/htdocs/core/boxes/box_graph_new_vs_close_ticket.php @@ -2,7 +2,7 @@ /* Module descriptor for ticket system * Copyright (C) 2013-2016 Jean-François FERRY * 2016 Christophe Battarel - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019-2021 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 @@ -19,7 +19,7 @@ */ /** - * \file core/boxes/box_nb_ticket_last_x_days.php + * \file htdocs/core/boxes/box_graph_new_vs_close_ticket.php * \ingroup ticket * \brief This box shows the number of new daily tickets the last X days */ @@ -98,10 +98,10 @@ class box_graph_new_vs_close_ticket extends ModeleBoxes $num = $this->db->num_rows($resql); if ($num > 0) { $objp = $this->db->fetch_object($resql); - $data[] = array($langs->trans('TicketCreatedToday'), $objp->nb); + $data[] = array($langs->transnoentitiesnoconv('TicketCreatedToday'), $objp->nb); $totalnb += $objp->nb; } else { - $data[] = array($langs->trans('TicketCreatedToday'), 0); + $data[] = array($langs->transnoentitiesnoconv('TicketCreatedToday'), 0); } } else { dol_print_error($this->db); @@ -116,10 +116,10 @@ class box_graph_new_vs_close_ticket extends ModeleBoxes $num = $this->db->num_rows($resql); if ($num > 0) { $objp = $this->db->fetch_object($resql); - $data[] = array($langs->trans('TicketClosedToday'), $objp->nb); + $data[] = array($langs->transnoentitiesnoconv('TicketClosedToday'), $objp->nb); $totalnb += $objp->nb; } else { - $data[] = array($langs->trans('TicketClosedToday'), 0); + $data[] = array($langs->transnoentitiesnoconv('TicketClosedToday'), 0); } } else { dol_print_error($this->db); diff --git a/htdocs/core/boxes/box_graph_orders_permonth.php b/htdocs/core/boxes/box_graph_orders_permonth.php index 48f0bd67ec3..0fd27c377d5 100644 --- a/htdocs/core/boxes/box_graph_orders_permonth.php +++ b/htdocs/core/boxes/box_graph_orders_permonth.php @@ -99,7 +99,7 @@ class box_graph_orders_permonth extends ModeleBoxes if ($user->socid) { $socid = $user->socid; } - if (!$user->rights->societe->client->voir || $socid) { + if (empty($user->rights->societe->client->voir) || $socid) { $prefix .= 'private-'.$user->id.'-'; // If user has no permission to see all, output dir is specific to user } diff --git a/htdocs/core/boxes/box_graph_orders_supplier_permonth.php b/htdocs/core/boxes/box_graph_orders_supplier_permonth.php index a394834cd97..be58b1e983c 100644 --- a/htdocs/core/boxes/box_graph_orders_supplier_permonth.php +++ b/htdocs/core/boxes/box_graph_orders_supplier_permonth.php @@ -98,7 +98,7 @@ class box_graph_orders_supplier_permonth extends ModeleBoxes if ($user->socid) { $socid = $user->socid; } - if (!$user->rights->societe->client->voir || $socid) { + if (empty($user->rights->societe->client->voir) || $socid) { $prefix .= 'private-'.$user->id.'-'; // If user has no permission to see all, output dir is specific to user } diff --git a/htdocs/core/boxes/box_graph_propales_permonth.php b/htdocs/core/boxes/box_graph_propales_permonth.php index 8a95761ea08..03899fb922f 100644 --- a/htdocs/core/boxes/box_graph_propales_permonth.php +++ b/htdocs/core/boxes/box_graph_propales_permonth.php @@ -101,7 +101,7 @@ class box_graph_propales_permonth extends ModeleBoxes if ($user->socid) { $socid = $user->socid; } - if (!$user->rights->societe->client->voir || $socid) { + if (empty($user->rights->societe->client->voir) || $socid) { $prefix .= 'private-'.$user->id.'-'; // If user has no permission to see all, output dir is specific to user } diff --git a/htdocs/core/boxes/box_graph_ticket_by_severity.php b/htdocs/core/boxes/box_graph_ticket_by_severity.php index 13cd0c40c86..5e69a49e88e 100644 --- a/htdocs/core/boxes/box_graph_ticket_by_severity.php +++ b/htdocs/core/boxes/box_graph_ticket_by_severity.php @@ -2,7 +2,7 @@ /* Module descriptor for ticket system * Copyright (C) 2013-2016 Jean-François FERRY * 2016 Christophe Battarel - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019-2021 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 @@ -19,7 +19,7 @@ */ /** - * \file core/boxes/box_ticket_by_severity.php + * \file htdocs/core/boxes/box_graph_ticket_by_severity.php * \ingroup ticket * \brief This box shows open tickets by severity */ diff --git a/htdocs/core/boxes/box_last_modified_ticket.php b/htdocs/core/boxes/box_last_modified_ticket.php index 57e54594255..300a13803c5 100644 --- a/htdocs/core/boxes/box_last_modified_ticket.php +++ b/htdocs/core/boxes/box_last_modified_ticket.php @@ -96,7 +96,7 @@ class box_last_modified_ticket extends ModeleBoxes $sql .= " WHERE t.entity IN (".getEntity('ticket').')'; // $sql.= " AND e.rowid = er.fk_event"; - //if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " WHERE s.rowid = sc.fk_soc AND sc.fk_user = " .((int) $user->id); + //if (empty($user->rights->societe->client->voir) && !$user->socid) $sql.= " WHERE s.rowid = sc.fk_soc AND sc.fk_user = " .((int) $user->id); if ($user->socid) { $sql .= " AND t.fk_soc = ".((int) $user->socid); } diff --git a/htdocs/core/boxes/box_last_ticket.php b/htdocs/core/boxes/box_last_ticket.php index 39086464f73..25cb353b268 100644 --- a/htdocs/core/boxes/box_last_ticket.php +++ b/htdocs/core/boxes/box_last_ticket.php @@ -95,7 +95,7 @@ class box_last_ticket extends ModeleBoxes $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid=t.fk_soc"; $sql .= " WHERE t.entity IN (".getEntity('ticket').")"; // $sql.= " AND e.rowid = er.fk_event"; - //if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " WHERE s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); + //if (empty($user->rights->societe->client->voir) && !$user->socid) $sql.= " WHERE s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); if ($user->socid) { $sql .= " AND t.fk_soc= ".((int) $user->socid); } diff --git a/htdocs/core/boxes/box_members_by_type.php b/htdocs/core/boxes/box_members_by_type.php index 5b95b58d29d..0a5e4548e3f 100644 --- a/htdocs/core/boxes/box_members_by_type.php +++ b/htdocs/core/boxes/box_members_by_type.php @@ -68,7 +68,7 @@ class box_members_by_type extends ModeleBoxes $this->enabled = 0; // disabled for external users } - $this->hidden = !($user->rights->adherent->lire); + $this->hidden = !(!empty($conf->adherent->enabled) && $user->rights->adherent->lire); } /** diff --git a/htdocs/core/boxes/box_members_last_modified.php b/htdocs/core/boxes/box_members_last_modified.php index 9de6a3af12f..cf70bcafcb1 100644 --- a/htdocs/core/boxes/box_members_last_modified.php +++ b/htdocs/core/boxes/box_members_last_modified.php @@ -67,7 +67,7 @@ class box_members_last_modified extends ModeleBoxes $this->enabled = 0; // disabled for external users } - $this->hidden = !($user->rights->adherent->lire); + $this->hidden = !(!empty($conf->adherent->enabled) && $user->rights->adherent->lire); } /** diff --git a/htdocs/core/boxes/box_members_last_subscriptions.php b/htdocs/core/boxes/box_members_last_subscriptions.php index 3cea44c2dc3..949edd567f3 100644 --- a/htdocs/core/boxes/box_members_last_subscriptions.php +++ b/htdocs/core/boxes/box_members_last_subscriptions.php @@ -67,7 +67,7 @@ class box_members_last_subscriptions extends ModeleBoxes $this->enabled = 0; // disabled for external users } - $this->hidden = !($user->rights->adherent->lire); + $this->hidden = !(!empty($conf->adherent->enabled) && $user->rights->adherent->lire); } /** diff --git a/htdocs/core/boxes/box_members_subscriptions_by_year.php b/htdocs/core/boxes/box_members_subscriptions_by_year.php index be835511c6b..73c71521603 100644 --- a/htdocs/core/boxes/box_members_subscriptions_by_year.php +++ b/htdocs/core/boxes/box_members_subscriptions_by_year.php @@ -67,7 +67,7 @@ class box_members_subscriptions_by_year extends ModeleBoxes $this->enabled = 0; // disabled for external users } - $this->hidden = !($user->rights->adherent->lire); + $this->hidden = !(!empty($conf->adherent->enabled) && $user->rights->adherent->lire); } /** @@ -111,7 +111,7 @@ class box_members_subscriptions_by_year extends ModeleBoxes $i = 0; while ($i < $num) { $objp = $this->db->fetch_object($result); - $year = dol_print_date($this->db->jdate($objp->dateh), "%Y", 'gmt'); + $year = dol_print_date($this->db->jdate($objp->dateh), "%Y"); $Total[$year] = (isset($Total[$year]) ? $Total[$year] : 0) + $objp->subscription; $Number[$year] = (isset($Number[$year]) ? $Number[$year] : 0) + 1; $tot += $objp->subscription; diff --git a/htdocs/core/boxes/box_project.php b/htdocs/core/boxes/box_project.php index f14ab699690..63a4e90cdd0 100644 --- a/htdocs/core/boxes/box_project.php +++ b/htdocs/core/boxes/box_project.php @@ -94,7 +94,7 @@ class box_project extends ModeleBoxes // Get list of project id allowed to user (in a string list separated by coma) $projectsListId = ''; - if (!$user->rights->projet->all->lire) { + if (empty($user->rights->projet->all->lire)) { $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid); } @@ -102,7 +102,7 @@ class box_project extends ModeleBoxes $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= " WHERE p.entity IN (".getEntity('project').")"; // Only current entity or severals if permission ok $sql .= " AND p.fk_statut = 1"; // Only open projects - if (!$user->rights->projet->all->lire) { + if (empty($user->rights->projet->all->lire)) { $sql .= " AND p.rowid IN (".$this->db->sanitize($projectsListId).")"; // public and assigned to, or restricted to company for external users } diff --git a/htdocs/core/boxes/box_propales.php b/htdocs/core/boxes/box_propales.php index 6599116a980..51d313b7254 100644 --- a/htdocs/core/boxes/box_propales.php +++ b/htdocs/core/boxes/box_propales.php @@ -90,12 +90,12 @@ class box_propales extends ModeleBoxes $sql .= ", p.rowid, p.ref, p.fk_statut as status, p.datep as dp, p.datec, p.fin_validite, p.date_cloture, p.total_ht, p.total_tva, p.total_ttc, p.tms"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."propal as p"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.fk_soc = s.rowid"; $sql .= " AND p.entity IN (".getEntity('propal').")"; - if (!$user->rights->societe->client->voir && !$user->socid) { + 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) { diff --git a/htdocs/core/boxes/box_prospect.php b/htdocs/core/boxes/box_prospect.php index 06d42e34b18..a46713a3206 100644 --- a/htdocs/core/boxes/box_prospect.php +++ b/htdocs/core/boxes/box_prospect.php @@ -93,12 +93,12 @@ class box_prospect extends ModeleBoxes $sql .= ", s.fk_stcomm"; $sql .= ", s.datec, s.tms, s.status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.client IN (2, 3)"; $sql .= " AND s.entity IN (".getEntity('societe').")"; - if (!$user->rights->societe->client->voir && !$user->socid) { + 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) { diff --git a/htdocs/core/boxes/box_services_contracts.php b/htdocs/core/boxes/box_services_contracts.php index 320932a0c6f..c72a378a1a2 100644 --- a/htdocs/core/boxes/box_services_contracts.php +++ b/htdocs/core/boxes/box_services_contracts.php @@ -95,7 +95,7 @@ class box_services_contracts extends ModeleBoxes $sql .= " INNER JOIN ".MAIN_DB_PREFIX."contrat as c ON s.rowid = c.fk_soc"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."contratdet as cd ON c.rowid = cd.fk_contrat"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON cd.fk_product = p.rowid"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " INNER JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= ")"; diff --git a/htdocs/core/boxes/box_services_expired.php b/htdocs/core/boxes/box_services_expired.php index 433c566ad31..4353fb7eb02 100644 --- a/htdocs/core/boxes/box_services_expired.php +++ b/htdocs/core/boxes/box_services_expired.php @@ -86,7 +86,7 @@ class box_services_expired extends ModeleBoxes $sql .= " 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 .= " MIN(cd.date_fin_validite) as date_line, COUNT(cd.rowid) as nb_services"; $sql .= " FROM ".MAIN_DB_PREFIX."contrat as c, ".MAIN_DB_PREFIX."societe s, ".MAIN_DB_PREFIX."contratdet as cd"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE cd.statut = 4 AND cd.date_fin_validite <= '".$this->db->idate($now)."'"; @@ -95,7 +95,7 @@ class box_services_expired extends ModeleBoxes if ($user->socid) { $sql .= ' AND c.fk_soc = '.((int) $user->socid); } - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY c.rowid, c.ref, c.statut, c.date_contrat, c.ref_customer, c.ref_supplier, s.nom, s.rowid"; diff --git a/htdocs/core/boxes/box_shipments.php b/htdocs/core/boxes/box_shipments.php index 2b6adfe3bdc..d0ddf1f8dcb 100644 --- a/htdocs/core/boxes/box_shipments.php +++ b/htdocs/core/boxes/box_shipments.php @@ -101,7 +101,7 @@ class box_shipments extends ModeleBoxes $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON e.rowid = el.fk_target AND el.targettype = 'shipping' AND el.sourcetype IN ('commande')"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."commande as c ON el.fk_source = c.rowid AND el.sourcetype IN ('commande') AND el.targettype = 'shipping'"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = e.fk_soc"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON e.fk_soc = sc.fk_soc"; } $sql .= " WHERE e.entity IN (".getEntity('expedition').")"; @@ -111,7 +111,7 @@ class box_shipments extends ModeleBoxes if ($user->socid > 0) { $sql.= " AND s.rowid = ".((int) $user->socid); } - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND sc.fk_user = ".((int) $user->id); } else { $sql .= " ORDER BY e.date_delivery, e.ref DESC "; diff --git a/htdocs/core/boxes/box_supplier_orders.php b/htdocs/core/boxes/box_supplier_orders.php index b3451d9b6c3..2cc34a9255b 100644 --- a/htdocs/core/boxes/box_supplier_orders.php +++ b/htdocs/core/boxes/box_supplier_orders.php @@ -92,12 +92,12 @@ class box_supplier_orders extends ModeleBoxes $sql .= ", c.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande_fournisseur as c"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; $sql .= " AND c.entity IN (".getEntity('supplier_order').")"; - if (!$user->rights->societe->client->voir && !$user->socid) { + 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) { diff --git a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php index 8125a848fd0..f9d2de4b7fc 100644 --- a/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php +++ b/htdocs/core/boxes/box_supplier_orders_awaiting_reception.php @@ -92,13 +92,14 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes $sql .= ", c.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande_fournisseur as c"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; $sql .= " AND c.entity IN (".getEntity('supplier_order').")"; + $sql .= " AND c.date_livraison IS NOT NULL"; $sql .= " AND c.fk_statut IN (".CommandeFournisseur::STATUS_ORDERSENT.", ".CommandeFournisseur::STATUS_RECEIVED_PARTIALLY.")"; - if (!$user->rights->societe->client->voir && !$user->socid) { + 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) { @@ -161,7 +162,7 @@ class box_supplier_orders_awaiting_reception extends ModeleBoxes $this->info_box_contents[$line][] = array( 'td' => 'class="right"', - 'text' => $delayIcon.' '.dol_print_date($delivery_date, 'day', 'tzuserrel').'', + 'text' => $delayIcon.' '.($delivery_date ? dol_print_date($delivery_date, 'day', 'tzuserrel') : '').'', 'asis' => 1 ); diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php index 9b7cbfc2fe6..e86a1206902 100644 --- a/htdocs/core/boxes/box_task.php +++ b/htdocs/core/boxes/box_task.php @@ -122,7 +122,7 @@ class box_task extends ModeleBoxes $boxcontent .= ''."\n"; $selectArray = array('all' => $langs->trans("NoFilter"), 'im_task_contact' => $langs->trans("WhichIamLinkedTo"), 'im_project_contact' => $langs->trans("WhichIamLinkedToProject")); $boxcontent .= $form->selectArray($cookie_name, $selectArray, $filterValue); - $boxcontent .= ''; + $boxcontent .= ''; $boxcontent .= ''."\n"; $boxcontent .= '
    '."\n"; if (!empty($conf->use_javascript_ajax)) { @@ -145,7 +145,7 @@ class box_task extends ModeleBoxes // Get list of project id allowed to user (in a string list separated by coma) $projectsListId = ''; - if (!$user->rights->projet->all->lire) { + if (empty($user->rights->projet->all->lire)) { $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid); } @@ -168,7 +168,7 @@ class box_task extends ModeleBoxes $sql .= " AND p.fk_statut = ".Project::STATUS_VALIDATED; $sql .= " AND (pt.progress < 100 OR pt.progress IS NULL ) "; // 100% is done and not displayed $sql .= " AND p.usage_task = 1 "; - if (!$user->rights->projet->all->lire) { + if (empty($user->rights->projet->all->lire)) { $sql .= " AND p.rowid IN (".$this->db->sanitize($projectsListId).")"; // public and assigned to, or restricted to company for external users } diff --git a/htdocs/core/boxes/box_validated_projects.php b/htdocs/core/boxes/box_validated_projects.php index 0c4155da6c7..574ee7b7d80 100644 --- a/htdocs/core/boxes/box_validated_projects.php +++ b/htdocs/core/boxes/box_validated_projects.php @@ -101,7 +101,7 @@ class box_validated_projects extends ModeleBoxes // Get list of project id allowed to user (in a string list separated by coma) $projectsListId = ''; - if (!$user->rights->projet->all->lire) { + if (empty($user->rights->projet->all->lire)) { $projectsListId = $projectstatic->getProjectsAuthorizedForUser($user, 0, 1, $socid); } @@ -112,11 +112,11 @@ class box_validated_projects extends ModeleBoxes $sql .= " COUNT(DISTINCT t.rowid) as tasknumber"; $sql .= " FROM ".MAIN_DB_PREFIX."projet AS p"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."projet_task AS t ON p.rowid = t.fk_projet"; - // TODO Replace -1, -2, -3 with ID used for type of contat project_task into llx_c_type_contact. Once done, we can switch widget as stable. + // TODO Replace -1, -2, -3 with ID used for type of contact project_task into llx_c_type_contact. Once done, we can switch widget as stable. $sql .= " INNER JOIN ".MAIN_DB_PREFIX."element_contact as ec ON ec.element_id = t.rowid AND fk_c_type_contact IN (-1, -2, -3)"; $sql .= " WHERE p.fk_statut = 1"; // Only open projects if ($projectsListId) { - $sql .= ' AND p.rowid IN ('.$this->db->sanitize($projectsListId).')'; // Only project we ara allowed + $sql .= ' AND p.rowid IN ('.$this->db->sanitize($projectsListId).')'; // Only project are allowed } $sql .= " AND t.rowid NOT IN (SELECT fk_task FROM ".MAIN_DB_PREFIX."projet_task_time WHERE fk_user = ".((int) $user->id).")"; $sql .= " GROUP BY p.rowid, p.ref, p.fk_soc, p.dateo"; @@ -157,7 +157,7 @@ class box_validated_projects extends ModeleBoxes ); if ($objp->fk_soc > 0) { - $sql = 'SELECT rowid, nom as name FROM '.MAIN_DB_PREFIX.'societe WHERE rowid = '.((int) $objp->fk_soc); + $sql = "SELECT rowid, nom as name FROM ".MAIN_DB_PREFIX."societe WHERE rowid = ".((int) $objp->fk_soc); $resql = $this->db->query($sql); //$socstatic = new Societe($this->db); $obj2 = $this->db->fetch_object($resql); diff --git a/htdocs/core/class/commondocgenerator.class.php b/htdocs/core/class/commondocgenerator.class.php index 18920da3bc2..a92179e7b6a 100644 --- a/htdocs/core/class/commondocgenerator.class.php +++ b/htdocs/core/class/commondocgenerator.class.php @@ -220,6 +220,7 @@ abstract class CommonDocGenerator // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Define array with couple substitution key => substitution value + * For example {company_name}, {company_name_alias} * * @param Societe $object Object * @param Translate $outputlangs Language object for output @@ -398,7 +399,7 @@ abstract class CommonDocGenerator $sumpayed = $sumdeposit = $sumcreditnote = ''; $already_payed_all = 0; - $remain_to_pay = 0; + if ($object->element == 'facture') { $invoice_source = new Facture($this->db); if ($object->fk_facture_source > 0) { @@ -408,7 +409,6 @@ abstract class CommonDocGenerator $sumdeposit = $object->getSumDepositsUsed(); $sumcreditnote = $object->getSumCreditNotesUsed(); $already_payed_all = $sumpayed + $sumdeposit + $sumcreditnote; - $remain_to_pay = $sumpayed - $sumdeposit - $sumcreditnote; if ($object->fk_account > 0) { require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; @@ -420,73 +420,76 @@ abstract class CommonDocGenerator $date = ($object->element == 'contrat' ? $object->date_contrat : $object->date); $resarray = array( - $array_key.'_id'=>$object->id, - $array_key.'_ref'=>$object->ref, - $array_key.'_ref_ext'=>$object->ref_ext, - $array_key.'_ref_customer'=>(!empty($object->ref_client) ? $object->ref_client : (empty($object->ref_customer) ? '' : $object->ref_customer)), - $array_key.'_ref_supplier'=>(!empty($object->ref_fournisseur) ? $object->ref_fournisseur : (empty($object->ref_supplier) ? '' : $object->ref_supplier)), - $array_key.'_source_invoice_ref'=>$invoice_source->ref, - // Dates - $array_key.'_hour'=>dol_print_date($date, 'hour'), - $array_key.'_date'=>dol_print_date($date, 'day'), - $array_key.'_date_rfc'=>dol_print_date($date, 'dayrfc'), - $array_key.'_date_limit'=>(!empty($object->date_lim_reglement) ?dol_print_date($object->date_lim_reglement, 'day') : ''), - $array_key.'_date_end'=>(!empty($object->fin_validite) ?dol_print_date($object->fin_validite, 'day') : ''), - $array_key.'_date_creation'=>dol_print_date($object->date_creation, 'day'), - $array_key.'_date_modification'=>(!empty($object->date_modification) ?dol_print_date($object->date_modification, 'day') : ''), - $array_key.'_date_validation'=>(!empty($object->date_validation) ?dol_print_date($object->date_validation, 'dayhour') : ''), - $array_key.'_date_delivery_planed'=>(!empty($object->date_livraison) ?dol_print_date($object->date_livraison, 'day') : ''), - $array_key.'_date_close'=>(!empty($object->date_cloture) ?dol_print_date($object->date_cloture, 'dayhour') : ''), + $array_key.'_id'=>$object->id, + $array_key.'_ref'=>$object->ref, + $array_key.'_ref_ext'=>$object->ref_ext, + $array_key.'_ref_customer'=>(!empty($object->ref_client) ? $object->ref_client : (empty($object->ref_customer) ? '' : $object->ref_customer)), + $array_key.'_ref_supplier'=>(!empty($object->ref_fournisseur) ? $object->ref_fournisseur : (empty($object->ref_supplier) ? '' : $object->ref_supplier)), + $array_key.'_source_invoice_ref'=>$invoice_source->ref, + // Dates + $array_key.'_hour'=>dol_print_date($date, 'hour'), + $array_key.'_date'=>dol_print_date($date, 'day'), + $array_key.'_date_rfc'=>dol_print_date($date, 'dayrfc'), + $array_key.'_date_limit'=>(!empty($object->date_lim_reglement) ?dol_print_date($object->date_lim_reglement, 'day') : ''), + $array_key.'_date_end'=>(!empty($object->fin_validite) ?dol_print_date($object->fin_validite, 'day') : ''), + $array_key.'_date_creation'=>dol_print_date($object->date_creation, 'day'), + $array_key.'_date_modification'=>(!empty($object->date_modification) ?dol_print_date($object->date_modification, 'day') : ''), + $array_key.'_date_validation'=>(!empty($object->date_validation) ?dol_print_date($object->date_validation, 'dayhour') : ''), + $array_key.'_date_delivery_planed'=>(!empty($object->date_livraison) ?dol_print_date($object->date_livraison, 'day') : ''), + $array_key.'_date_close'=>(!empty($object->date_cloture) ?dol_print_date($object->date_cloture, 'dayhour') : ''), - $array_key.'_payment_mode_code'=>$object->mode_reglement_code, - $array_key.'_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code) != 'PaymentType'.$object->mode_reglement_code ? $outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code) : $object->mode_reglement), - $array_key.'_payment_term_code'=>$object->cond_reglement_code, - $array_key.'_payment_term'=>($outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code) != 'PaymentCondition'.$object->cond_reglement_code ? $outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code) : ($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement)), + $array_key.'_payment_mode_code'=>$object->mode_reglement_code, + $array_key.'_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code) != 'PaymentType'.$object->mode_reglement_code ? $outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code) : $object->mode_reglement), + $array_key.'_payment_term_code'=>$object->cond_reglement_code, + $array_key.'_payment_term'=>($outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code) != 'PaymentCondition'.$object->cond_reglement_code ? $outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code) : ($object->cond_reglement_doc ? $object->cond_reglement_doc : $object->cond_reglement)), - $array_key.'_incoterms'=>(method_exists($object, 'display_incoterms') ? $object->display_incoterms() : ''), + $array_key.'_incoterms'=>(method_exists($object, 'display_incoterms') ? $object->display_incoterms() : ''), - $array_key.'_bank_iban'=>$bank_account->iban, - $array_key.'_bank_bic'=>$bank_account->bic, + $array_key.'_bank_iban'=>$bank_account->iban, + $array_key.'_bank_bic'=>$bank_account->bic, + $array_key.'_bank_label'=>$bank_account->label, + $array_key.'_bank_number'=>$bank_account->number, + $array_key.'_bank_proprio'=>$bank_account->proprio, - $array_key.'_total_ht_locale'=>price($object->total_ht, 0, $outputlangs), - $array_key.'_total_vat_locale'=>(!empty($object->total_vat) ?price($object->total_vat, 0, $outputlangs) : price($object->total_tva, 0, $outputlangs)), - $array_key.'_total_localtax1_locale'=>price($object->total_localtax1, 0, $outputlangs), - $array_key.'_total_localtax2_locale'=>price($object->total_localtax2, 0, $outputlangs), - $array_key.'_total_ttc_locale'=>price($object->total_ttc, 0, $outputlangs), + $array_key.'_total_ht_locale'=>price($object->total_ht, 0, $outputlangs), + $array_key.'_total_vat_locale'=>(!empty($object->total_vat) ?price($object->total_vat, 0, $outputlangs) : price($object->total_tva, 0, $outputlangs)), + $array_key.'_total_localtax1_locale'=>price($object->total_localtax1, 0, $outputlangs), + $array_key.'_total_localtax2_locale'=>price($object->total_localtax2, 0, $outputlangs), + $array_key.'_total_ttc_locale'=>price($object->total_ttc, 0, $outputlangs), - $array_key.'_total_ht'=>price2num($object->total_ht), - $array_key.'_total_vat'=>(!empty($object->total_vat) ?price2num($object->total_vat) : price2num($object->total_tva)), - $array_key.'_total_localtax1'=>price2num($object->total_localtax1), - $array_key.'_total_localtax2'=>price2num($object->total_localtax2), - $array_key.'_total_ttc'=>price2num($object->total_ttc), + $array_key.'_total_ht'=>price2num($object->total_ht), + $array_key.'_total_vat'=>(!empty($object->total_vat) ?price2num($object->total_vat) : price2num($object->total_tva)), + $array_key.'_total_localtax1'=>price2num($object->total_localtax1), + $array_key.'_total_localtax2'=>price2num($object->total_localtax2), + $array_key.'_total_ttc'=>price2num($object->total_ttc), - $array_key.'_multicurrency_code' => $object->multicurrency_code, - $array_key.'_multicurrency_tx' => price2num($object->multicurrency_tx), - $array_key.'_multicurrency_total_ht' => price2num($object->multicurrency_total_ht), - $array_key.'_multicurrency_total_tva' => price2num($object->multicurrency_total_tva), - $array_key.'_multicurrency_total_ttc' => price2num($object->multicurrency_total_ttc), - $array_key.'_multicurrency_total_ht_locale' => price($object->multicurrency_total_ht, 0, $outputlangs), - $array_key.'_multicurrency_total_tva_locale' => price($object->multicurrency_total_tva, 0, $outputlangs), - $array_key.'_multicurrency_total_ttc_locale' => price($object->multicurrency_total_ttc, 0, $outputlangs), + $array_key.'_multicurrency_code' => $object->multicurrency_code, + $array_key.'_multicurrency_tx' => price2num($object->multicurrency_tx), + $array_key.'_multicurrency_total_ht' => price2num($object->multicurrency_total_ht), + $array_key.'_multicurrency_total_tva' => price2num($object->multicurrency_total_tva), + $array_key.'_multicurrency_total_ttc' => price2num($object->multicurrency_total_ttc), + $array_key.'_multicurrency_total_ht_locale' => price($object->multicurrency_total_ht, 0, $outputlangs), + $array_key.'_multicurrency_total_tva_locale' => price($object->multicurrency_total_tva, 0, $outputlangs), + $array_key.'_multicurrency_total_ttc_locale' => price($object->multicurrency_total_ttc, 0, $outputlangs), - $array_key.'_note_private'=>$object->note, - $array_key.'_note_public'=>$object->note_public, - $array_key.'_note'=>$object->note_public, // For backward compatibility + $array_key.'_note_private'=>$object->note, + $array_key.'_note_public'=>$object->note_public, + $array_key.'_note'=>$object->note_public, // For backward compatibility - // Payments - $array_key.'_already_payed_locale'=>price($sumpayed, 0, $outputlangs), - $array_key.'_already_payed'=>price2num($sumpayed), - $array_key.'_already_deposit_locale'=>price($sumdeposit, 0, $outputlangs), - $array_key.'_already_deposit'=>price2num($sumdeposit), - $array_key.'_already_creditnote_locale'=>price($sumcreditnote, 0, $outputlangs), - $array_key.'_already_creditnote'=>price2num($sumcreditnote), + // Payments + $array_key.'_already_payed_locale'=>price($sumpayed, 0, $outputlangs), + $array_key.'_already_payed'=>price2num($sumpayed), + $array_key.'_already_deposit_locale'=>price($sumdeposit, 0, $outputlangs), + $array_key.'_already_deposit'=>price2num($sumdeposit), + $array_key.'_already_creditnote_locale'=>price($sumcreditnote, 0, $outputlangs), + $array_key.'_already_creditnote'=>price2num($sumcreditnote), - $array_key.'_already_payed_all_locale'=>price(price2num($already_payed_all, 'MT'), 0, $outputlangs), - $array_key.'_already_payed_all'=> price2num($already_payed_all, 'MT'), + $array_key.'_already_payed_all_locale'=>price(price2num($already_payed_all, 'MT'), 0, $outputlangs), + $array_key.'_already_payed_all'=> price2num($already_payed_all, 'MT'), - // Remain to pay with all know information (except open direct debit requests) - $array_key.'_remain_to_pay_locale'=>price(price2num($object->total_ttc - $remain_to_pay, 'MT'), 0, $outputlangs), - $array_key.'_remain_to_pay'=>price2num($object->total_ttc - $remain_to_pay, 'MT') + // Remain to pay with all known information (except open direct debit requests) + $array_key.'_remain_to_pay_locale'=>price(price2num($object->total_ttc - $already_payed_all, 'MT'), 0, $outputlangs), + $array_key.'_remain_to_pay'=>price2num($object->total_ttc - $already_payed_all, 'MT') ); if (method_exists($object, 'getTotalDiscount') && in_array(get_class($object), array('Proposal', 'Commande', 'Facture', 'SupplierProposal', 'CommandeFournisseur', 'FactureFournisseur'))) { diff --git a/htdocs/core/class/commonincoterm.class.php b/htdocs/core/class/commonincoterm.class.php index 11af43c2914..d0485acc5a9 100644 --- a/htdocs/core/class/commonincoterm.class.php +++ b/htdocs/core/class/commonincoterm.class.php @@ -60,7 +60,7 @@ 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 ".MAIN_DB_PREFIX."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; $result = $this->db->query($sql); if ($result) { $res = $this->db->fetch_object($result); @@ -80,7 +80,7 @@ trait CommonIncoterm */ public function getIncotermsForPDF() { - $sql = 'SELECT code FROM '.MAIN_DB_PREFIX.'c_incoterms WHERE rowid = '.(int) $this->fk_incoterms; + $sql = "SELECT code FROM ".MAIN_DB_PREFIX."c_incoterms WHERE rowid = ".(int) $this->fk_incoterms; $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -107,7 +107,7 @@ trait CommonIncoterm { if ($this->id && $this->table_element) { $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; - $sql .= " SET fk_incoterms = ".($id_incoterm > 0 ? $id_incoterm : "null"); + $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); dol_syslog(get_class($this).'::setIncoterms', LOG_DEBUG); @@ -116,7 +116,7 @@ trait CommonIncoterm $this->fk_incoterms = $id_incoterm; $this->location_incoterms = $location; - $sql = 'SELECT libelle as label_incotermsFROM '.MAIN_DB_PREFIX.'c_incoterms WHERE rowid = '.(int) $this->fk_incoterms; + $sql = "SELECT libelle as label_incoterms FROM ".MAIN_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 dfabfd24ebe..c7a5beae245 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -226,8 +226,8 @@ abstract class CommonInvoice extends CommonObject $idarray = array(); $sql = 'SELECT rowid'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' WHERE fk_facture_source = '.((int) $this->id); + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " WHERE fk_facture_source = ".((int) $this->id); $sql .= ' AND type = 2'; $resql = $this->db->query($sql); if ($resql) { @@ -253,8 +253,8 @@ abstract class CommonInvoice extends CommonObject public function getIdReplacingInvoice($option = '') { $sql = 'SELECT rowid'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' WHERE fk_facture_source = '.((int) $this->id); + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " WHERE fk_facture_source = ".((int) $this->id); $sql .= ' AND type < 2'; if ($option == 'validated') { $sql .= ' AND fk_statut = 1'; @@ -306,8 +306,8 @@ abstract class CommonInvoice extends CommonObject $sharedentity = 'facture_fourn'; } - $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 = "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 .= " WHERE pf.".$field." = ".((int) $this->id); $sql .= " AND pf.".$field2." = p.rowid"; $sql .= ' AND p.fk_paiement = t.id'; @@ -335,12 +335,12 @@ abstract class CommonInvoice extends CommonObject //look for credit notes and discounts and deposits $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 = "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 .= ' 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 = "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 .= ' 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) @@ -734,7 +734,7 @@ abstract class CommonInvoice extends CommonObject $sql .= 'fk_facture, '; } $sql .= ' amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib, sourcetype, entity)'; - $sql .= ' VALUES ('.((int) $this->id); + $sql .= " VALUES (".((int) $this->id); $sql .= ", ".((float) price2num($amount)); $sql .= ", '".$this->db->idate($now)."'"; $sql .= ", ".((int) $fuser->id); @@ -970,8 +970,8 @@ abstract class CommonInvoiceLine extends CommonObjectLine public $date_end_fill; // If set to 1, when invoice is created from a template invoice, it will also auto set the field date_end at creation public $buy_price_ht; - public $buyprice; // For backward compatibility - public $pa_ht; // For backward compatibility + public $buyprice; // For backward compatibility + public $pa_ht; // For backward compatibility public $marge_tx; public $marque_tx; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ad4ad76a0f2..812353591ed 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1671,7 +1671,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 ".MAIN_DB_PREFIX.$this->table_element." WHERE ".$this->table_ref_field." LIKE '".$this->db->escape($ref)."' LIMIT 1"; $query = $this->db->query($sql); @@ -1733,6 +1733,18 @@ abstract class CommonObject return 0; } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Load the project with id $this->fk_project into this->project + * + * @return int <0 if KO, >=0 if OK + */ + public function fetch_project() + { + // phpcs:enable + return $this->fetch_projet(); + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Load the project with id $this->fk_project into this->project @@ -1839,7 +1851,7 @@ abstract class CommonObject $result = false; $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$table; - $sql .= " WHERE ".$field." = '".$key."'"; + $sql .= " WHERE ".$field." = '".$this->db->escape($key)."'"; if (!empty($element)) { $sql .= " AND entity IN (".getEntity($element).")"; } else { @@ -2036,19 +2048,19 @@ abstract class CommonObject 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 - } elseif ($restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) { + } 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 - } elseif ($restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$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 } - if ($restrictiononfksoc && !$user->rights->societe->client->voir && !$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 .= " 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 && !$user->rights->societe->client->voir && !$socid) { + if ($restrictiononfksoc == 1 && empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND sc.fk_user = ".((int) $user->id); } - if ($restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) { + if ($restrictiononfksoc == 2 && empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND (sc.fk_user = ".((int) $user->id).' OR te.fk_soc IS NULL)'; } if (!empty($filter)) { @@ -2060,7 +2072,7 @@ abstract class CommonObject if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) { $tmparray = explode('@', $this->ismultientitymanaged); $sql .= " AND te.".$tmparray[0]." = ".($tmparray[1] == "societe" ? "s" : "parenttable").".rowid"; // If we need to link to this table to limit select to entity - } elseif ($restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) { + } elseif ($restrictiononfksoc == 1 && $this->element != 'societe' && empty($user->rights->societe->client->voir) && !$socid) { $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid } if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) { @@ -2106,19 +2118,19 @@ abstract class CommonObject 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 - } elseif ($restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) { + } 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 - } elseif ($restrictiononfksoc == 2 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$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 } - if ($restrictiononfksoc && !$user->rights->societe->client->voir && !$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 .= " 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 && !$user->rights->societe->client->voir && !$socid) { + if ($restrictiononfksoc == 1 && empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND sc.fk_user = ".((int) $user->id); } - if ($restrictiononfksoc == 2 && !$user->rights->societe->client->voir && !$socid) { + if ($restrictiononfksoc == 2 && empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND (sc.fk_user = ".((int) $user->id).' OR te.fk_soc IS NULL)'; } if (!empty($filter)) { @@ -2130,7 +2142,7 @@ abstract class CommonObject if (isset($this->ismultientitymanaged) && !is_numeric($this->ismultientitymanaged)) { $tmparray = explode('@', $this->ismultientitymanaged); $sql .= " AND te.".$tmparray[0]." = ".($tmparray[1] == "societe" ? "s" : "parenttable").".rowid"; // If we need to link to this table to limit select to entity - } elseif ($restrictiononfksoc == 1 && $this->element != 'societe' && !$user->rights->societe->client->voir && !$socid) { + } elseif ($restrictiononfksoc == 1 && $this->element != 'societe' && empty($user->rights->societe->client->voir) && !$socid) { $sql .= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to socid } if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) { @@ -2888,7 +2900,7 @@ abstract class CommonObject // 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 ".MAIN_DB_PREFIX.$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); if (!$renum) { $sql .= ' AND rang = 0'; @@ -2910,7 +2922,7 @@ 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 ".MAIN_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'; @@ -2958,7 +2970,7 @@ abstract class CommonObject { $rows = array(); - $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql = "SELECT rowid FROM ".MAIN_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'; @@ -3026,7 +3038,7 @@ abstract class CommonObject * * @param int $rowid Id of line * @param int $rang Position - * @return void + * @return int <0 if KO, >0 if OK */ public function updateRangOfLine($rowid, $rang) { @@ -3042,10 +3054,13 @@ abstract class CommonObject dol_syslog(get_class($this)."::updateRangOfLine", LOG_DEBUG); if (!$this->db->query($sql)) { dol_print_error($this->db); + return -1; + } else { + $parameters=array('rowid'=>$rowid, 'rang'=>$rang, 'fieldposition' => $fieldposition); + $action=''; + $reshook = $hookmanager->executeHooks('afterRankOfLineUpdate', $parameters, $this, $action); + return 1; } - $parameters=array('rowid'=>$rowid, 'rang'=>$rang, 'fieldposition' => $fieldposition); - $action=''; - $reshook = $hookmanager->executeHooks('afterRankOfLineUpdate', $parameters, $this, $action); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -3133,8 +3148,8 @@ abstract class CommonObject */ public function getRangOfLine($rowid) { - $sql = 'SELECT rang FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql .= ' WHERE rowid ='.((int) $rowid); + $sql = "SELECT rang FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql .= " WHERE rowid = ".((int) $rowid); dol_syslog(get_class($this)."::getRangOfLine", LOG_DEBUG); $resql = $this->db->query($sql); @@ -3152,9 +3167,9 @@ abstract class CommonObject */ public function getIdOfLine($rang) { - $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); - $sql .= ' AND rang = '.((int) $rang); + $sql .= " AND rang = ".((int) $rang); $resql = $this->db->query($sql); if ($resql) { $row = $this->db->fetch_row($resql); @@ -3181,7 +3196,7 @@ abstract class CommonObject if ($fk_parent_line) { $sql = "SELECT max(".$positionfield.") FROM ".MAIN_DB_PREFIX.$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); - $sql .= ' AND fk_parent_line = '.((int) $fk_parent_line); + $sql .= " AND fk_parent_line = ".((int) $fk_parent_line); dol_syslog(get_class($this)."::line_max", LOG_DEBUG); $resql = $this->db->query($sql); @@ -3397,7 +3412,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 ".MAIN_DB_PREFIX.$this->table_element_line; $sql .= " WHERE ".$this->fk_element." = ".((int) $this->id); if ($exclspec) { $product_field = 'product_type'; @@ -3527,7 +3542,7 @@ abstract class CommonObject $this->db->free($resql); - // Now update global field total_ht, total_ttc and tva + // Now update global field total_ht, total_ttc, total_tva, total_localtax1, total_localtax2, multicurrency_total_* $fieldht = 'total_ht'; $fieldtva = 'tva'; $fieldlocaltax1 = 'localtax1'; @@ -3557,7 +3572,7 @@ abstract class CommonObject } if (empty($nodatabaseupdate)) { - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET'; + $sql = "UPDATE ".MAIN_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)).","; @@ -3570,6 +3585,7 @@ abstract class CommonObject dol_syslog(get_class($this)."::update_price", LOG_DEBUG); $resql = $this->db->query($sql); + if (!$resql) { $error++; $this->error = $this->db->lasterror(); @@ -3602,7 +3618,7 @@ abstract class CommonObject public function add_object_linked($origin = null, $origin_id = null, $f_user = null, $notrigger = 0) { // phpcs:enable - global $user; + global $user, $hookmanager, $action; $origin = (!empty($origin) ? $origin : $this->origin); $origin_id = (!empty($origin_id) ? $origin_id : $this->origin_id); $f_user = isset($f_user) ? $f_user : $user; @@ -3620,6 +3636,20 @@ abstract class CommonObject if ($origin == 'supplierorder') { $origin = 'order_supplier'; } + + // 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'); + // 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; + + $parameters = array('targettype'=>$targettype); + // Hook for explicitly set the targettype if it must be differtent than $this->element + $reshook = $hookmanager->executeHooks('setLinkedObjectSourceTargetType', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (!empty($hookmanager->resArray['targettype'])) $targettype = $hookmanager->resArray['targettype']; + } + $this->db->begin(); $error = 0; @@ -3632,7 +3662,7 @@ abstract class CommonObject $sql .= ((int) $origin_id); $sql .= ", '" . $this->db->escape($origin) . "'"; $sql .= ", " . ((int) $this->id); - $sql .= ", '" . $this->db->escape($this->element) . "'"; + $sql .= ", '" . $this->db->escape($targettype) . "'"; $sql .= ")"; dol_syslog(get_class($this) . "::add_object_linked", LOG_DEBUG); @@ -3685,7 +3715,7 @@ abstract class CommonObject */ public function fetchObjectLinked($sourceid = null, $sourcetype = '', $targetid = null, $targettype = '', $clause = 'OR', $alsosametype = 1, $orderby = 'sourcetype', $loadalsoobjects = 1) { - global $conf; + global $conf, $hookmanager, $action; $this->linkedObjectsIds = array(); $this->linkedObjects = array(); @@ -3695,6 +3725,16 @@ abstract class CommonObject $withtargettype = false; $withsourcetype = false; + $parameters = array('sourcetype'=>$sourcetype, 'sourceid'=>$sourceid, 'targettype'=>$targettype, 'targetid'=>$targetid); + // Hook for explicitly set the targettype if it must be differtent than $this->element + $reshook = $hookmanager->executeHooks('setLinkedObjectSourceTargetType', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + if (!empty($hookmanager->resArray['sourcetype'])) $sourcetype = $hookmanager->resArray['sourcetype']; + if (!empty($hookmanager->resArray['sourceid'])) $sourceid = $hookmanager->resArray['sourceid']; + if (!empty($hookmanager->resArray['targettype'])) $targettype = $hookmanager->resArray['targettype']; + if (!empty($hookmanager->resArray['targetid'])) $targetid = $hookmanager->resArray['targetid']; + } + if (!empty($sourceid) && !empty($sourcetype) && empty($targetid)) { $justsource = true; // the source (id and type) is a search criteria if (!empty($targettype)) { @@ -3845,8 +3885,14 @@ abstract class CommonObject $classfile = 'conferenceorbooth'; $classname = 'ConferenceOrBooth'; $module = 'eventorganization'; + } elseif ($objecttype == 'mo') { + $classpath = 'mrp/class'; + $classfile = 'mo'; + $classname = 'Mo'; + $module = 'mrp'; } + // Here $module, $classfile and $classname are set if ($conf->$module->enabled && (($element != $this->element) || $alsosametype)) { if ($loadalsoobjects) { @@ -4245,8 +4291,8 @@ abstract class CommonObject */ public function getSpecialCode($lineid) { - $sql = 'SELECT special_code FROM '.MAIN_DB_PREFIX.$this->table_element_line; - $sql .= ' WHERE rowid = '.((int) $lineid); + $sql = "SELECT special_code FROM ".MAIN_DB_PREFIX.$this->table_element_line; + $sql .= " WHERE rowid = ".((int) $lineid); $resql = $this->db->query($sql); if ($resql) { $row = $this->db->fetch_row($resql); @@ -4297,10 +4343,10 @@ abstract class CommonObject //print 'Found into table '.$table.', type '.$langs->transnoentitiesnoconv($elementname).', haschild='.$haschild; $haschild += $obj->nb; if (is_numeric($elementname)) { // old usage - $this->errors[] = $langs->trans("ErrorRecordHasAtLeastOneChildOfType", $table); + $this->errors[] = $langs->transnoentities("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $table); } else // new usage: $elementname=Translation key { - $this->errors[] = $langs->trans("ErrorRecordHasAtLeastOneChildOfType", $langs->transnoentitiesnoconv($elementname)); + $this->errors[] = $langs->transnoentities("ErrorRecordHasAtLeastOneChildOfType", method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref, $langs->transnoentitiesnoconv($elementname)); } break; // We found at least one, we stop here } @@ -5302,7 +5348,7 @@ abstract class CommonObject $ecmfile->gen_or_uploaded = 'generated'; $ecmfile->description = ''; // indexed content $ecmfile->keywords = ''; // keyword content - $ecmfile->src_object_type = $this->table_element; + $ecmfile->src_object_type = $this->table_element; // $this->table_name is 'myobject' or 'mymodule_myobject'. $ecmfile->src_object_id = $this->id; $result = $ecmfile->create($user); @@ -6034,7 +6080,6 @@ abstract class CommonObject } $sql .= ")"; - $resql = $this->db->query($sql); if (!$resql) { $this->error = $this->db->lasterror(); @@ -6288,6 +6333,11 @@ abstract class CommonObject $this->array_options["options_".$key] = $this->db->idate($this->array_options["options_".$key]); } break; + case 'boolean': + if (empty($this->array_options["options_".$key])) { + $this->array_options["options_".$key] = null; + } + break; /* case 'link': $param_list = array_keys($attributeParam['options']); @@ -6442,7 +6492,7 @@ abstract class CommonObject $out = ''; $type = ''; - $isDependList=0; + $isDependList = 0; $param = array(); $param['options'] = array(); $reg = array(); @@ -6665,8 +6715,8 @@ abstract class CommonObject } $sqlwhere = ''; - $sql = 'SELECT '.$keyList; - $sql .= ' FROM '.MAIN_DB_PREFIX.$InfoFieldList[0]; + $sql = "SELECT ".$keyList; + $sql .= " FROM ".MAIN_DB_PREFIX.$InfoFieldList[0]; if (!empty($InfoFieldList[4])) { // can use SELECT request if (strpos($InfoFieldList[4], '$SEL$') !== false) { @@ -6750,7 +6800,7 @@ abstract class CommonObject if (!empty($InfoFieldList[3]) && $parentField) { $parent = $parentName.':'.$obj->{$parentField}; - $isDependList=1; + $isDependList = 1; } $out .= ''; - $sql = "SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, "; + $sql = "SELECT ctc.rowid, ctc.code, ctc.label, ctc.fk_parent, ctc.public, "; $sql .= $this->db->ifsql("ctc.rowid NOT IN (SELECT ctcfather.rowid FROM llx_c_ticket_category as ctcfather JOIN llx_c_ticket_category as ctcjoin ON ctcfather.rowid = ctcjoin.fk_parent)", "'NOTPARENT'", "'PARENT'")." as isparent"; $sql .= " FROM ".MAIN_DB_PREFIX."c_ticket_category as ctc"; - $sql .= " WHERE ctc.active > 0"; + $sql .= " WHERE ctc.active > 0 AND ctc.entity = ".((int) $conf->entity); if ($filtertype == 'public=1') { $sql .= " AND ctc.public = 1"; } $sql .= " AND ctc.fk_parent = 0"; $sql .= $this->db->order('ctc.pos', 'ASC'); + $resql = $this->db->query($sql); if ($resql) { $num_rows_level0 = $this->db->num_rows($resql); @@ -707,23 +803,36 @@ class FormTicket while ($i < $num_rows_level0) { $obj = $this->db->fetch_object($resql); if ($obj) { + $label = ($obj->label != '-' ? $obj->label : ''); + if ($outputlangs->trans("TicketCategoryShort".$obj->code) != ("TicketCategoryShort".$obj->code)) { + $label = $outputlangs->trans("TicketCategoryShort".$obj->code); + } elseif ($outputlangs->trans($obj->code) != $obj->code) { + $label = $outputlangs->trans($obj->code); + } + $grouprowid = $obj->rowid; $groupvalue = $obj->code; - $grouplabel = $obj->label; + $grouplabel = $label; + $isparent = $obj->isparent; - $iselected = $groupticket == $obj->code ?'selected':''; + if (is_array($selectedgroups)) { + $iselected = in_array($obj->code, $selectedgroups) ?'selected':''; + } else { + $iselected = $groupticket == $obj->code ?'selected':''; + } $stringtoprint .= ''; if ($isparent == 'NOTPARENT') { $arraycodenotparent[] = $groupvalue; } - $arrayidused[]=$grouprowid; + $arrayidused[] = $grouprowid; + $arrayidusedconcat[] = $grouprowid; } $i++; } } else { dol_print_error($this->db); } - if ($num_rows_level0 == 1) { + if (count($arrayidused) == 1) { return ''; } else { $stringtoprint .= ''; @@ -731,20 +840,22 @@ class FormTicket } $stringtoprint .= ' '; - $levelid = 1; - while ($levelid <= $use_multilevel) { + $levelid = 1; // The first combobox + while ($levelid <= $use_multilevel) { // Loop to take the child of the combo $tabscript = array(); $stringtoprint .= ''; $stringtoprint .=''; $stringtoprint .= ajax_combobox($htmlname); @@ -1129,7 +1253,7 @@ class FormTicket // External users can't send message email if ($user->rights->ticket->write && !$user->socid) { print ''; - $checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : ''); + $checkbox_selected = (GETPOST('send_email') == "1" ? ' checked' : ($conf->global->TICKETS_MESSAGE_FORCE_MAIL?'checked':'')); print ' '; print ''; print ''; diff --git a/htdocs/core/class/infobox.class.php b/htdocs/core/class/infobox.class.php index fb59e2b7c42..0cd34e13193 100644 --- a/htdocs/core/class/infobox.class.php +++ b/htdocs/core/class/infobox.class.php @@ -37,7 +37,7 @@ class InfoBox { global $conf; - if (empty($conf->global->MAIN_FEATURES_LEVEL) || $conf->global->MAIN_FEATURES_LEVEL < 2) { + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2) { return array( 0 => 'Home', 1 => 'UsersHome', @@ -83,7 +83,7 @@ class InfoBox /** * Return array of boxes qualified for area and user * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param string $mode 'available' or 'activated' * @param int $zone Name or area (-1 for all, 0 for Homepage, 1 for Accountancy, 2 for xxx, ...) * @param User|null $user Object user to filter @@ -91,7 +91,7 @@ class InfoBox * @param int $includehidden Include also hidden boxes * @return array Array of boxes */ - public static function listBoxes($db, $mode, $zone, $user = null, $excludelist = array(), $includehidden = 1) + public static function listBoxes($dbs, $mode, $zone, $user = null, $excludelist = array(), $includehidden = 1) { global $conf; @@ -119,12 +119,12 @@ class InfoBox } dol_syslog(get_class()."::listBoxes get default box list for mode=".$mode." userid=".(is_object($user) ? $user->id : '')."", LOG_DEBUG); - $resql = $db->query($sql); + $resql = $dbs->query($sql); if ($resql) { - $num = $db->num_rows($resql); + $num = $dbs->num_rows($resql); $j = 0; while ($j < $num) { - $obj = $db->fetch_object($resql); + $obj = $dbs->fetch_object($resql); if (!in_array($obj->box_id, $excludelist)) { $regs = array(); @@ -144,14 +144,14 @@ class InfoBox // Goal is to avoid making a "new" done for each boxes returned by select. dol_include_once($relsourcefile); if (class_exists($boxname)) { - $box = new $boxname($db, $obj->note); // Constructor may set properties like box->enabled. obj->note is note into box def, not user params. + $box = new $boxname($dbs, $obj->note); // Constructor may set properties like box->enabled. obj->note is note into box def, not user params. //$box=new stdClass(); // box properties $box->rowid = (empty($obj->rowid) ? '' : $obj->rowid); $box->id = (empty($obj->box_id) ? '' : $obj->box_id); $box->position = ((isset($obj->position) && $obj->position == '') ? '' : (isset($obj->position) ? $obj->position : '')); // '0' must stay '0' - $box->box_order = (empty($obj->box_order) ? '' : $obj->box_order); + $box->box_order = (empty($obj->box_order) ? '' : $obj->box_order); $box->fk_user = (empty($obj->fk_user) ? 0 : $obj->fk_user); $box->sourcefile = $relsourcefile; $box->class = $boxname; @@ -204,8 +204,8 @@ class InfoBox $j++; } } else { - dol_syslog($db->lasterror(), LOG_ERR); - return array('error'=>$db->lasterror()); + dol_syslog($dbs->lasterror(), LOG_ERR); + return array('error'=>$dbs->lasterror()); } return $boxes; @@ -215,13 +215,13 @@ class InfoBox /** * Save order of boxes for area and user * - * @param DoliDB $db Database handler + * @param DoliDB $dbs Database handler * @param int $zone Name of area (0 for Homepage, ...) * @param string $boxorder List of boxes with correct order 'A:123,456,...-B:789,321...' * @param int $userid Id of user * @return int <0 if KO, 0=Nothing done, > 0 if OK */ - public static function saveboxorder($db, $zone, $boxorder, $userid = 0) + public static function saveboxorder($dbs, $zone, $boxorder, $userid = 0) { global $conf; @@ -235,18 +235,18 @@ class InfoBox return 0; } - $user = new User($db); + $user = new User($dbs); $user->id = $userid; - $db->begin(); + $dbs->begin(); // Save parameters to say user has a dedicated setup $tab = array(); $confuserzone = 'MAIN_BOXES_'.$zone; $tab[$confuserzone] = 1; - if (dol_set_user_param($db, $conf, $user, $tab) < 0) { - $error = $db->lasterror(); - $db->rollback(); + if (dol_set_user_param($dbs, $conf, $user, $tab) < 0) { + $error = $dbs->lasterror(); + $dbs->rollback(); return -3; } @@ -257,7 +257,7 @@ class InfoBox $sql .= " AND position = ".((int) $zone); dol_syslog(get_class()."::saveboxorder", LOG_DEBUG); - $result = $db->query($sql); + $result = $dbs->query($sql); if ($result) { $colonnes = explode('-', $boxorder); foreach ($colonnes as $collist) { @@ -279,12 +279,12 @@ class InfoBox $sql .= " values ("; $sql .= " ".((int) $id).","; $sql .= " ".((int) $zone).","; - $sql .= " '".$db->escape($colonne.$ii)."',"; + $sql .= " '".$dbs->escape($colonne.$ii)."',"; $sql .= " ".((int) $userid).","; $sql .= " ".((int) $conf->entity); $sql .= ")"; - $result = $db->query($sql); + $result = $dbs->query($sql); if ($result < 0) { $error++; break; @@ -297,10 +297,10 @@ class InfoBox } if ($error) { - $db->rollback(); + $dbs->rollback(); return -2; } else { - $db->commit(); + $dbs->commit(); return 1; } } diff --git a/htdocs/core/class/ldap.class.php b/htdocs/core/class/ldap.class.php index a2e5d450869..4af22683b2c 100644 --- a/htdocs/core/class/ldap.class.php +++ b/htdocs/core/class/ldap.class.php @@ -1,8 +1,8 @@ * Copyright (C) 2004 Benoit Mortier - * Copyright (C) 2005-2017 Regis Houssin - * Copyright (C) 2006-2015 Laurent Destailleur + * Copyright (C) 2005-2021 Regis Houssin + * Copyright (C) 2006-2021 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 @@ -48,6 +48,11 @@ class Ldap */ public $server = array(); + /** + * Current connected server + */ + public $connectedServer; + /** * Base DN (e.g. "dc=foo,dc=com") */ @@ -132,35 +137,33 @@ class Ldap if (!empty($conf->global->LDAP_SERVER_HOST_SLAVE)) { $this->server[] = $conf->global->LDAP_SERVER_HOST_SLAVE; } - $this->serverPort = $conf->global->LDAP_SERVER_PORT; - $this->ldapProtocolVersion = $conf->global->LDAP_SERVER_PROTOCOLVERSION; - $this->dn = $conf->global->LDAP_SERVER_DN; - $this->serverType = $conf->global->LDAP_SERVER_TYPE; + $this->serverPort = getDolGlobalInt('LDAP_SERVER_PORT', 389); + $this->ldapProtocolVersion = getDolGlobalString('LDAP_SERVER_PROTOCOLVERSION'); + $this->dn = getDolGlobalString('LDAP_SERVER_DN'); + $this->serverType = getDolGlobalString('LDAP_SERVER_TYPE'); - $this->domain = $conf->global->LDAP_SERVER_DN; - $this->searchUser = $conf->global->LDAP_ADMIN_DN; - $this->searchPassword = $conf->global->LDAP_ADMIN_PASS; - $this->people = $conf->global->LDAP_USER_DN; - $this->groups = $conf->global->LDAP_GROUP_DN; + $this->domain = getDolGlobalString('LDAP_SERVER_DN'); + $this->searchUser = getDolGlobalString('LDAP_ADMIN_DN'); + $this->searchPassword = getDolGlobalString('LDAP_ADMIN_PASS'); + $this->people = getDolGlobalString('LDAP_USER_DN'); + $this->groups = getDolGlobalString('LDAP_GROUP_DN'); - $this->filter = $conf->global->LDAP_FILTER_CONNECTION; // Filter on user - $this->filtergroup = $conf->global->LDAP_GROUP_FILTER; // Filter on groups - $this->filtermember = $conf->global->LDAP_MEMBER_FILTER; // Filter on member + $this->filter = getDolGlobalString('LDAP_FILTER_CONNECTION'); // Filter on user + $this->filtergroup = getDolGlobalString('LDAP_GROUP_FILTER'); // Filter on groups + $this->filtermember = getDolGlobalString('LDAP_MEMBER_FILTER'); // Filter on member // Users - $this->attr_login = $conf->global->LDAP_FIELD_LOGIN; //unix - $this->attr_sambalogin = $conf->global->LDAP_FIELD_LOGIN_SAMBA; //samba, activedirectory - $this->attr_name = $conf->global->LDAP_FIELD_NAME; - $this->attr_firstname = $conf->global->LDAP_FIELD_FIRSTNAME; - $this->attr_mail = $conf->global->LDAP_FIELD_MAIL; - $this->attr_phone = $conf->global->LDAP_FIELD_PHONE; - $this->attr_skype = $conf->global->LDAP_FIELD_SKYPE; - $this->attr_fax = $conf->global->LDAP_FIELD_FAX; - $this->attr_mobile = $conf->global->LDAP_FIELD_MOBILE; + $this->attr_login = getDolGlobalString('LDAP_FIELD_LOGIN'); //unix + $this->attr_sambalogin = getDolGlobalString('LDAP_FIELD_LOGIN_SAMBA'); //samba, activedirectory + $this->attr_name = getDolGlobalString('LDAP_FIELD_NAME'); + $this->attr_firstname = getDolGlobalString('LDAP_FIELD_FIRSTNAME'); + $this->attr_mail = getDolGlobalString('LDAP_FIELD_MAIL'); + $this->attr_phone = getDolGlobalString('LDAP_FIELD_PHONE'); + $this->attr_skype = getDolGlobalString('LDAP_FIELD_SKYPE'); + $this->attr_fax = getDolGlobalString('LDAP_FIELD_FAX'); + $this->attr_mobile = getDolGlobalString('LDAP_FIELD_MOBILE'); } - - // Connection handling methods ------------------------------------------- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -178,6 +181,8 @@ class Ldap $connected = 0; $this->bind = 0; + $this->error = 0; + $this->connectedServer = ''; // Check parameters if (count($this->server) == 0 || empty($this->server[0])) { @@ -205,16 +210,28 @@ class Ldap if ($this->serverPing($host, $this->serverPort) === true) { $this->connection = ldap_connect($host, $this->serverPort); } else { - continue; + if (preg_match('/^ldaps/i', $host)) { + // With host = ldaps://server, the serverPing to ssl://server sometimes fails, even if the ldap_connect succeed, so + // we test this case and continue in suche a case even if serverPing fails. + $this->connection = ldap_connect($host, $this->serverPort); + } else { + continue; + } } if (is_resource($this->connection)) { - // Begin TLS if requested by the configuration + // Upgrade connexion to TLS, if requested by the configuration if (!empty($conf->global->LDAP_SERVER_USE_TLS)) { - if (!ldap_start_tls($this->connection)) { + // For test/debug + //ldap_set_option($this->connection, LDAP_OPT_DEBUG_LEVEL, 7); + //ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3); + + $resulttls = ldap_start_tls($this->connection); + if (!$resulttls) { dol_syslog(get_class($this)."::connect_bind failed to start tls", LOG_WARNING); + $this->error = 'ldap_start_tls Failed to start TLS '.ldap_errno($this->connection).' '.ldap_error($this->connection); $connected = 0; - $this->close(); + $this->unbind(); } } @@ -249,7 +266,7 @@ class Ldap } // Try in anonymous if (!$this->bind) { - dol_syslog(get_class($this)."::connect_bind try bind on ".$host, LOG_DEBUG); + dol_syslog(get_class($this)."::connect_bind try bind anonymously on ".$host, LOG_DEBUG); $result = $this->bind(); if ($result) { $this->bind = $this->result; @@ -263,7 +280,9 @@ class Ldap } if (!$connected) { - $this->close(); + $this->unbind(); + } else { + $this->connectedServer = $host; } } } @@ -276,16 +295,18 @@ class Ldap $return = -1; dol_syslog(get_class($this)."::connect_bind return=".$return.' - '.$this->error, LOG_WARNING); } + return $return; } - /** - * Simply closes the connection set up earlier. - * Returns true if OK, false if there was an error. + * Simply closes the connection set up earlier. Returns true if OK, false if there was an error. + * This method seems a duplicate/alias of unbind(). * * @return boolean true or false + * @deprecated ldap_close is an alias of ldap_unbind + * @see unbind() */ public function close() { @@ -337,16 +358,21 @@ class Ldap } /** - * Unbind du serveur ldap. + * Unbind of LDAP server (close connection). * * @return boolean true or false + * @see close() */ public function unbind() { - if (!$this->result = @ldap_unbind($this->connection)) { - return false; - } else { + $this->result = true; + if ($this->connection) { + $this->result = @ldap_unbind($this->connection); + } + if ($this->result) { return true; + } else { + return false; } } @@ -399,7 +425,7 @@ class Ldap */ public function add($dn, $info, $user) { - dol_syslog(get_class($this)."::add dn=".$dn." info=".join(',', $info)); + dol_syslog(get_class($this)."::add dn=".$dn." info=".json_encode($info)); // Check parameters if (!$this->connection) { @@ -474,6 +500,11 @@ class Ldap // For better compatibility with Samba4 AD if ($this->serverType == "activedirectory") { unset($info['cn']); // To avoid error : Operation not allowed on RDN (Code 67) + + // To avoid error : LDAP Error: 53 (Unwilling to perform) + if (isset($info['unicodePwd'])) { + $info['unicodePwd'] = mb_convert_encoding("\"".$info['unicodePwd']."\"", "UTF-16LE", "UTF-8"); + } } $result = @ldap_modify($this->connection, $dn, $info); @@ -689,22 +720,38 @@ class Ldap /** * Ping a server before ldap_connect for avoid waiting * - * @param string $host Server host or address + * @param string $host Server host or address * @param int $port Server port (default 389) - * @param int $timeout Timeout in second (default 1s) + * @param int $timeout Timeout in second (default 1s) * @return boolean true or false */ public function serverPing($host, $port = 389, $timeout = 1) { - // Replace ldaps:// by ssl:// + $regs = array(); if (preg_match('/^ldaps:\/\/([^\/]+)\/?$/', $host, $regs)) { + // Replace ldaps:// by ssl:// $host = 'ssl://'.$regs[1]; - } - // Remove ldap:// - if (preg_match('/^ldap:\/\/([^\/]+)\/?$/', $host, $regs)) { + } elseif (preg_match('/^ldap:\/\/([^\/]+)\/?$/', $host, $regs)) { + // Remove ldap:// $host = $regs[1]; } + + //var_dump($newhostforstream); var_dump($host); var_dump($port); + //$host = 'ssl://ldap.test.local:636'; + //$port = 636; + + $errno = $errstr = 0; + /* + if ($methodtochecktcpconnect == 'socket') { + Try to use socket_create() method. + Method that use stream_context_create() works only on registered listed in stream stream_get_wrappers(): http, https, ftp, ... + } + */ + + // Use the method fsockopen to test tcp connect. No way to ignore ssl certificate errors with this method ! $op = @fsockopen($host, $port, $errno, $errstr, $timeout); + + //var_dump($op); if (!$op) { return false; //DC is N/A } else { diff --git a/htdocs/core/class/link.class.php b/htdocs/core/class/link.class.php index 2a5e0f99c64..eaf4804b213 100644 --- a/htdocs/core/class/link.class.php +++ b/htdocs/core/class/link.class.php @@ -274,24 +274,24 @@ class Link extends CommonObject /** * Return nb of links * - * @param DoliDb $db Database handler + * @param DoliDb $dbs Database handler * @param string $objecttype Type of the associated object in dolibarr * @param int $objectid Id of the associated object in dolibarr * @return int Nb of links, -1 if error **/ - public static function count($db, $objecttype, $objectid) + public static function count($dbs, $objecttype, $objectid) { global $conf; $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."links"; - $sql .= " WHERE objecttype = '".$db->escape($objecttype)."' AND objectid = ".((int) $objectid); + $sql .= " WHERE objecttype = '".$dbs->escape($objecttype)."' AND objectid = ".((int) $objectid); if ($conf->entity != 0) { $sql .= " AND entity = ".$conf->entity; } - $resql = $db->query($sql); + $resql = $dbs->query($sql); if ($resql) { - $obj = $db->fetch_object($resql); + $obj = $dbs->fetch_object($resql); if ($obj) { return $obj->nb; } diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 019618366d1..a88f673405c 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -108,10 +108,26 @@ class Notify */ public function confirmMessage($action, $socid, $object) { - global $langs; + global $conf, $langs; $langs->load("mails"); $listofnotiftodo = $this->getNotificationsArray($action, $socid, $object, 0); + if (!empty($conf->global->NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_USER)) { + foreach ($listofnotiftodo as $val) { + if ($val['type'] == 'touser') { + unset($listofnotiftodo[$val['email']]); + //$listofnotiftodo = array_merge($listofnotiftodo); + } + } + } + if (!empty($conf->global->NOTIFICATION_EMAIL_DISABLE_CONFIRM_MESSAGE_FIX)) { + foreach ($listofnotiftodo as $val) { + if ($val['type'] == 'tofixedemail') { + unset($listofnotiftodo[$val['email']]); + //$listofnotiftodo = array_merge($listofnotiftodo); + } + } + } $texte = ''; $nb = -1; diff --git a/htdocs/core/class/rssparser.class.php b/htdocs/core/class/rssparser.class.php index 6a8a91dbb05..c3c434d1aed 100644 --- a/htdocs/core/class/rssparser.class.php +++ b/htdocs/core/class/rssparser.class.php @@ -240,7 +240,7 @@ class RssParser if (!empty($conf->global->EXTERNALRSS_USE_SIMPLEXML)) { //print 'xx'.LIBXML_NOCDATA; libxml_use_internal_errors(false); - $rss = simplexml_load_string($str, "SimpleXMLElement", LIBXML_NOCDATA); + $rss = simplexml_load_string($str, "SimpleXMLElement", LIBXML_NOCDATA|LIBXML_NOCDATA); } else { if (!function_exists('xml_parser_create')) { $this->error = 'Function xml_parser_create are not supported by your PHP'; diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index 4743d4559b6..dbaaacc2d18 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -464,20 +464,26 @@ class SMTPs $host = 'tls://'.$host; } - $hosth = $host; + $hosth = $host; // so for example 'localhost' or 'smtp-relay.gmail.com' if (!empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) { - // If the from to is 'aaa ', we will keep 'ccc.com' - $hosth = $this->getFrom('addr'); - $hosth = preg_replace('/^.*.*$/', '', $hosth); - $hosth = preg_replace('/.*@/', '', $hosth); + if (!is_numeric($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) { + // If value of MAIL_SMTP_USE_FROM_FOR_HELO is a string, we use it as domain name + $hosth = $conf->global->MAIL_SMTP_USE_FROM_FOR_HELO; + } else { + // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from. + // So if the from to is 'aaa ', we will keep 'ccc.com' + $hosth = $this->getFrom('addr'); + $hosth = preg_replace('/^.*.*$/', '', $hosth); + $hosth = preg_replace('/.*@/', '', $hosth); + } } if ($_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) { if ($usetls) { /* - The following dialog illustrates how a client and server can start a TLS STARTTLS session + The following dialog illustrates how a client and server can start a TLS STARTTLS session: S: C: S: 220 mail.imc.org SMTP service ready @@ -494,6 +500,39 @@ class SMTPs S: 250-server-domain.com S: 250 AUTH LOGIN C: + S: 250 OK + C: RCPT TO: + S: 250 OK + C: DATA + S: 354 Send message, end with a "." on a line by itself + C: + S . + S: 250 OK, message accepted for delivery: queued as 12345 + C: QUIT + S: 221 Bye */ if (!$_retVal = $this->socket_send_str('STARTTLS', 220)) { $this->_setErr(131, 'STARTTLS connection is not supported.'); @@ -517,10 +556,10 @@ class SMTPs $this->_setErr(132, 'STARTTLS connection failed.'); return $_retVal; } - // Most server servers expect a 2nd pass of EHLO after TLS is established to get another time + // Most servers expect a 2nd pass of EHLO after TLS is established to get another time // the answer with list of supported AUTH methods. They may differs between non STARTTLS and with STARTTLS. - if (!$_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) { - $this->_setErr(126, '"'.$hosth.'" does not support authenticated connections.'); + if (! $_retVal = $this->socket_send_str('EHLO '.$hosth, '250')) { + $this->_setErr(126, '"'.$hosth.'" does not support authenticated connections. Error after sending EHLO '.$hosth); return $_retVal; } } @@ -560,7 +599,7 @@ class SMTPs $this->_setErr(130, 'Invalid Authentication Credentials.'); } } else { - $this->_setErr(126, '"'.$host.'" does not support authenticated connections.'); + $this->_setErr(126, '"'.$host.'" does not support authenticated connections. Error after sending EHLO '.$hosth); } return $_retVal; @@ -603,11 +642,17 @@ class SMTPs $hosth = $host; if (!empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) { - // If the from to is 'aaa ', we will keep 'ccc.com' - $hosth = $this->getFrom('addr'); - $hosth = preg_replace('/^.*.*$/', '', $hosth); - $hosth = preg_replace('/.*@/', '', $hosth); + if (!is_numeric($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) { + // If value of MAIL_SMTP_USE_FROM_FOR_HELO is a string, we use it as domain name + $hosth = $conf->global->MAIL_SMTP_USE_FROM_FOR_HELO; + } else { + // If value of MAIL_SMTP_USE_FROM_FOR_HELO is 1, we use the domain in the from. + // If the from to is 'aaa ', we will keep 'ccc.com' + $hosth = $this->getFrom('addr'); + $hosth = preg_replace('/^.*.*$/', '', $hosth); + $hosth = preg_replace('/.*@/', '', $hosth); + } } $_retVal = $this->socket_send_str('HELO '.$hosth, '250'); @@ -1422,7 +1467,7 @@ class SMTPs $this->_msgContent[$strType]['dataText'] = $strContentAltText; if ($this->getMD5flag()) { - $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3); + $this->_msgContent[$strType]['md5'] = dol_hash($strContent, 3); } //} } @@ -1622,7 +1667,7 @@ class SMTPs $this->_msgContent['image'][$strImageName]['data'] = $strContent; if ($this->getMD5flag()) { - $this->_msgContent['image'][$strImageName]['md5'] = dol_hash($strContent, 3); + $this->_msgContent['image'][$strImageName]['md5'] = dol_hash($strContent, 3); } } } diff --git a/htdocs/core/class/stats.class.php b/htdocs/core/class/stats.class.php index 4ac164b1d3a..ae9a8e56e58 100644 --- a/htdocs/core/class/stats.class.php +++ b/htdocs/core/class/stats.class.php @@ -617,4 +617,31 @@ abstract class Stats return $result; } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Returns the summed amounts per year for a given number of past years ending now + * @param string $sql SQL + * @return array + */ + protected function _getAmountByYear($sql) + { + $result = array(); + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) { + $row = $this->db->fetch_row($resql); + $j = (int) $row[0]; + $result[] = [ + 0 => (int) $row[0], + 1 => (int) $row[1], + ]; + $i++; + } + $this->db->free($resql); + } + return $result; + } } diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index b535d2b3585..e741adc84b5 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -589,7 +589,7 @@ class Translate } /* Disabled. There is too many cases where translation of $newstr is not defined is normal (like when output with setEventMessage an already translated string) - if (! empty($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL >= 2) + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { dol_syslog(__METHOD__." MAIN_FEATURES_LEVEL=DEVELOP: missing translation for key '".$newstr."' in ".$_SERVER["PHP_SELF"], LOG_DEBUG); }*/ diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index fd89a00a810..d56fcddafa7 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2021 Regis Houssin * * 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 @@ -202,7 +203,7 @@ class Utils require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; // Check compression parameter - if (!in_array($compression, array('none', 'gz', 'bz', 'zip'))) { + if (!in_array($compression, array('none', 'gz', 'bz', 'zip', 'zstd'))) { $langs->load("errors"); $this->error = $langs->transnoentitiesnoconv("ErrorBadValueForParameter", $compression, "Compression"); return -1; @@ -248,9 +249,10 @@ class Utils $compression = $compression ? $compression : 'none'; if ($compression == 'gz') { $outputfile .= '.gz'; - } - if ($compression == 'bz') { + } elseif ($compression == 'bz') { $outputfile .= '.bz2'; + } elseif ($compression == 'zstd') { + $outputfile .= '.zst'; } $outputerror = $outputfile.'.err'; dol_mkdir($conf->admin->dir_output.'/backup'); @@ -337,12 +339,12 @@ class Utils $fullcommandclear = $command." ".$paramclear." 2>&1"; if ($compression == 'none') { $handle = fopen($outputfile, 'w'); - } - if ($compression == 'gz') { + } elseif ($compression == 'gz') { $handle = gzopen($outputfile, 'w'); - } - if ($compression == 'bz') { + } elseif ($compression == 'bz') { $handle = bzopen($outputfile, 'w'); + } elseif ($compression == 'zstd') { + $handle = fopen($outputfile, 'w'); } $ok = 0; @@ -408,12 +410,12 @@ class Utils if ($compression == 'none') { fclose($handle); - } - if ($compression == 'gz') { + } elseif ($compression == 'gz') { gzclose($handle); - } - if ($compression == 'bz') { + } elseif ($compression == 'bz') { bzclose($handle); + } elseif ($compression == 'zstd') { + fclose($handle); } if (!empty($conf->global->MAIN_UMASK)) { @@ -428,12 +430,12 @@ class Utils // Get errorstring if ($compression == 'none') { $handle = fopen($outputfile, 'r'); - } - if ($compression == 'gz') { + } elseif ($compression == 'gz') { $handle = gzopen($outputfile, 'r'); - } - if ($compression == 'bz') { + } elseif ($compression == 'bz') { $handle = bzopen($outputfile, 'r'); + } elseif ($compression == 'zstd') { + $handle = fopen($outputfile, 'r'); } if ($handle) { // Get 2048 first chars of error message. @@ -443,12 +445,12 @@ class Utils // Close file if ($compression == 'none') { fclose($handle); - } - if ($compression == 'gz') { + } elseif ($compression == 'gz') { gzclose($handle); - } - if ($compression == 'bz') { + } elseif ($compression == 'bz') { bzclose($handle); + } elseif ($compression == 'zstd') { + fclose($handle); } if ($ok && preg_match('/^-- (MySql|MariaDB)/i', $errormsg)) { // No error $errormsg = ''; diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index 3693b52cc74..b7f01de0aeb 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -349,7 +349,7 @@ foreach ($arrayoftype as $key => $val) { } print $form->selectarray('objecttype', $newarrayoftype, $objecttype, 0, 0, 0, '', 1, 0, 0, '', 'minwidth200', 1); if (empty($conf->use_javascript_ajax)) { - print ''; + print ''; } else { print ''; if ($addlink) { - $out .= ' '.$langs->trans("Link").''; + if ($textonlink === 'image') { + $out .= ' '.img_picto('', 'globe').''; + } else { + $out .= ' '.$langs->trans("Link").''; + } } return $out; } @@ -9544,21 +9587,24 @@ function dol_mimetype($file, $default = 'application/octet-stream', $mode = 0) } /** - * Return value from dictionary + * Return the value of a filed into a dictionary for the record $id. + * This also set all the values into a cache for a next search. * - * @param string $tablename name of dictionary - * @param string $field the value to return - * @param int $id id of line - * @param bool $checkentity add filter on entity - * @param string $rowidfield name of the column rowid - * @return string + * @param string $tablename Name of dictionary + * @param string $field The name of field where to find the value to return + * @param int $id Id of line record + * @param bool $checkentity Add filter on entity + * @param string $rowidfield Name of the column rowid (to use for the filter on $id) + * @return string The value of field $field. This also set $dictvalues cache. */ -function getDictvalue($tablename, $field, $id, $checkentity = false, $rowidfield = 'rowid') +function getDictionaryValue($tablename, $field, $id, $checkentity = false, $rowidfield = 'rowid') { - global $dictvalues, $db, $langs; + global $conf, $db; - if (!isset($dictvalues[$tablename])) { - $dictvalues[$tablename] = array(); + $dictvalues = (isset($conf->cache['dictvalues_'.$tablename]) ? $conf->cache['dictvalues_'.$tablename] : null); + + if (is_null($dictvalues)) { + $dictvalues = array(); $sql = "SELECT * FROM ".$tablename." WHERE 1 = 1"; // Here select * is allowed as it is generic code and we don't have list of fields if ($checkentity) { @@ -9568,20 +9614,20 @@ function getDictvalue($tablename, $field, $id, $checkentity = false, $rowidfield $resql = $db->query($sql); if ($resql) { while ($obj = $db->fetch_object($resql)) { - $dictvalues[$tablename][$obj->{$rowidfield}] = $obj; + $dictvalues[$obj->{$rowidfield}] = $obj; } } else { dol_print_error($db); } + + $conf->cache['dictvalues_'.$tablename] = $dictvalues; } - if (!empty($dictvalues[$tablename][$id])) { - return $dictvalues[$tablename][$id]->{$field}; // Found - } else // Not found - { - if ($id > 0) { - return $id; - } + if (!empty($dictvalues[$id])) { + // Found + return $dictvalues[$id]->{$field}; + } else { + // Not found return ''; } } @@ -10016,7 +10062,7 @@ function dolGetButtonTitle($label, $helpText = '', $iconClass = 'fa fa-file', $u } $class = 'btnTitle'; - if (in_array($iconClass, array('fa fa-plus-circle', 'fa fa-comment-dots'))) { + if (in_array($iconClass, array('fa fa-plus-circle', 'fa fa-plus-circle size15x', 'fa fa-comment-dots'))) { $class .= ' btnTitlePlus'; } $useclassfortooltip = 1; @@ -10498,9 +10544,9 @@ function showValueWithClipboardCPButton($valuetocopy, $showonlyonhover = 1, $tex $tag = 'span'; // Using div does not work when using the js copy code. if ($texttoshow) { - $result = '<'.$tag.' class="clipboardCPValue hidewithsize">'.dol_escape_htmltag($valuetocopy, 1, 1).''.dol_escape_htmltag($texttoshow, 1, 1).''; + $result = '<'.$tag.' class="clipboardCPValue hidewithsize">'.dol_escape_htmltag($valuetocopy, 1, 1).''.dol_escape_htmltag($texttoshow, 1, 1).''; } else { - $result = '<'.$tag.' class="clipboardCPValue">'.dol_escape_htmltag($valuetocopy, 1, 1).''; + $result = '<'.$tag.' class="clipboardCPValue">'.dol_escape_htmltag($valuetocopy, 1, 1).''; } return $result; diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 5ea704881e3..26c56d45463 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -2166,6 +2166,9 @@ function dolGetElementUrl($objectid, $objecttype, $withpicto = 0, $option = '') $classpath = 'fichinter/class'; $module = 'ficheinter'; $myobject = 'fichinter'; + } elseif ($objecttype == 'project') { + $classpath = 'projet/class'; + $module = 'projet'; } elseif ($objecttype == 'task') { $classpath = 'projet/class'; $module = 'projet'; diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index 3398189a771..be7e1ffa80b 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -249,7 +249,10 @@ function getURLContent($url, $postorget = 'GET', $param = '', $followlocation = $request = curl_getinfo($ch, CURLINFO_HEADER_OUT); // Reading of request must be done after sending request dol_syslog("getURLContent request=".$request); - //dol_syslog("getURLContent response =".response); // This may contains binary data, so we dont output it + if (!empty($conf->global->MAIN_GETURLCONTENT_OUTPUT_RESPONSE)) { + // This may contains binary data, so we dont output reponse by default. + dol_syslog("getURLContent response =".$response); + } dol_syslog("getURLContent response size=".strlen($response)); // This may contains binary data, so we dont output it $rep = array(); diff --git a/htdocs/core/lib/hrm.lib.php b/htdocs/core/lib/hrm.lib.php index e24c503f449..e53cc9b3965 100644 --- a/htdocs/core/lib/hrm.lib.php +++ b/htdocs/core/lib/hrm.lib.php @@ -54,6 +54,22 @@ function establishment_prepare_head($object) complete_head_from_modules($conf, $langs, $object, $head, $h, 'establishment', 'remove'); + + + $head[$h][0] = dol_buildpath("/hrm/admin/setup.php", 1); + $head[$h][1] = $langs->trans("Settings"); + $head[$h][2] = 'settings'; + $h++; + + complete_head_from_modules($conf, $langs, null, $head, $h, 'hrm'); + + $head[$h][0] = dol_buildpath("/hrm/admin/about.php", 1); + $head[$h][1] = $langs->trans("About"); + $head[$h][2] = 'about'; + $h++; + + complete_head_from_modules($conf, $langs, null, $head, $h, 'hrm'); + return $head; } diff --git a/htdocs/core/lib/import.lib.php b/htdocs/core/lib/import.lib.php index a9663795988..96ad79f03e6 100644 --- a/htdocs/core/lib/import.lib.php +++ b/htdocs/core/lib/import.lib.php @@ -3,7 +3,7 @@ * Copyright (C) 2007 Rodolphe Quiedeville * Copyright (C) 2010 Regis Houssin * Copyright (C) 2010 Juanjo Menent - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018-2021 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 @@ -24,6 +24,7 @@ * \file htdocs/core/lib/import.lib.php * \brief Ensemble de fonctions de base pour le module import * \ingroup import + */ /** * Function to return list of tabs for import pages @@ -47,7 +48,7 @@ function import_prepare_head($param, $maxstep = 0) if ($i < 6) { $head[$h][0] = DOL_URL_ROOT.'/imports/import.php?step='.$i.$param; } else { - $head[$h][0] = DOL_URL_ROOT.'/imports/import.php?step=5'.$param; // For step6, link is to step 5 + $head[$h][0] = DOL_URL_ROOT.'/imports/import.php?step=5'.$param; // For step6, link is to step 5 } $head[$h][1] = $langs->trans("Step")." ".$i; $head[$h][2] = 'step'.$i; diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index 28b56efb20d..8b61a690910 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -233,7 +233,7 @@ function getCustomerInvoicePieChart($socid = 0) $sql = "SELECT count(f.rowid), f.fk_statut"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."facture as f"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; @@ -241,7 +241,7 @@ function getCustomerInvoicePieChart($socid = 0) if ($user->socid) { $sql .= ' AND f.fk_soc = '.((int) $user->socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY f.fk_statut"; @@ -353,7 +353,7 @@ function getPurchaseInvoicePieChart($socid = 0) $sql = "SELECT count(f.rowid), f.fk_statut"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."facture_fourn as f"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; @@ -361,7 +361,7 @@ function getPurchaseInvoicePieChart($socid = 0) if ($user->socid) { $sql .= ' AND f.fk_soc = '.((int) $user->socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY f.fk_statut"; @@ -480,10 +480,11 @@ function getNumberInvoicesPieChart($mode) date_add($datenowadd30, $interval30days); date_add($datenowadd15, $interval15days); - $sql = "SELECT sum(".$db->ifsql("f.date_lim_reglement < '".date_format($datenowsub30, 'Y-m-d')."'", 1, 0).") as nblate30"; + $sql = "SELECT"; + $sql .= " sum(".$db->ifsql("f.date_lim_reglement < '".date_format($datenowsub30, 'Y-m-d')."'", 1, 0).") as nblate30"; $sql .= ", sum(".$db->ifsql("f.date_lim_reglement < '".date_format($datenowsub15, 'Y-m-d')."'", 1, 0).") as nblate15"; $sql .= ", sum(".$db->ifsql("f.date_lim_reglement < '".date_format($now, 'Y-m-d')."'", 1, 0).") as nblatenow"; - $sql .= ", sum(".$db->ifsql("f.date_lim_reglement >= '".date_format($now, 'Y-m-d')."'", 1, 0).") as nbnotlatenow"; + $sql .= ", sum(".$db->ifsql("f.date_lim_reglement >= '".date_format($now, 'Y-m-d')."' OR f.date_lim_reglement IS NULL", 1, 0).") as nbnotlatenow"; $sql .= ", sum(".$db->ifsql("f.date_lim_reglement > '".date_format($datenowadd15, 'Y-m-d')."'", 1, 0).") as nbnotlate15"; $sql .= ", sum(".$db->ifsql("f.date_lim_reglement > '".date_format($datenowadd30, 'Y-m-d')."'", 1, 0).") as nbnotlate30"; if ($mode == 'customers') { @@ -508,24 +509,37 @@ function getNumberInvoicesPieChart($mode) while ($i < $num) { $obj = $db->fetch_object($resql); - $dataseries = array(array($langs->trans('InvoiceLate30Days'), $obj->nblate30) + /*$dataseries = array(array($langs->trans('InvoiceLate30Days'), $obj->nblate30) ,array($langs->trans('InvoiceLate15Days'), $obj->nblate15 - $obj->nblate30) ,array($langs->trans('InvoiceLateMinus15Days'), $obj->nblatenow - $obj->nblate15) ,array($langs->trans('InvoiceNotLate'), $obj->nbnotlatenow - $obj->nbnotlate15) ,array($langs->trans('InvoiceNotLate15Days'), $obj->nbnotlate15 - $obj->nbnotlate30) - ,array($langs->trans('InvoiceNotLate30Days'), $obj->nbnotlate30)); + ,array($langs->trans('InvoiceNotLate30Days'), $obj->nbnotlate30));*/ + $dataseries[$i]=array($langs->trans('NbOfOpenInvoices'), $obj->nblate30, $obj->nblate15 - $obj->nblate30, $obj->nblatenow - $obj->nblate15, $obj->nbnotlatenow - $obj->nbnotlate15, $obj->nbnotlate15 - $obj->nbnotlate30, $obj->nbnotlate30); $i++; } - foreach ($dataseries as $key=>$value) { - $total += $value[1]; + if (!empty($dataseries[0])) { + foreach ($dataseries[0] as $key => $value) { + if (is_numeric($value)) { + $total += $value; + } + } } + $legend = array( + $langs->trans('InvoiceLate30Days'), + $langs->trans('InvoiceLate15Days'), + $langs->trans('InvoiceLateMinus15Days'), + $mode == 'customers' ? $langs->trans('InvoiceNotLate') : $langs->trans("InvoiceToPay"), + $mode == 'customers' ? $langs->trans('InvoiceNotLate15Days') : $langs->trans("InvoiceToPay15Days"), + $mode == 'customers' ? $langs->trans('InvoiceNotLate30Days') : $langs->trans("InvoiceToPay30Days"), + ); $colorseries = array($badgeStatus8, $badgeStatus1, $badgeStatus3, $badgeStatus4, $badgeStatus11, '-'.$badgeStatus11); $result = '
    '; $result .= ''; $result .= ''; - $result .= ''; if ($conf->use_javascript_ajax) { + //var_dump($dataseries); $dolgraph = new DolGraph(); $dolgraph->SetData($dataseries); + + $dolgraph->setLegend($legend); + $dolgraph->SetDataColor(array_values($colorseries)); $dolgraph->setShowLegend(2); $dolgraph->setShowPercent(1); - $dolgraph->SetType(['pie']); - $dolgraph->setHeight('150'); - $dolgraph->setWidth('300'); + $dolgraph->SetType(array('bars', 'bars', 'bars', 'bars', 'bars', 'bars')); + $dolgraph->setHeight('160'); + $dolgraph->setWidth('400'); + $dolgraph->setHideXValues(true); if ($mode == 'customers') { $dolgraph->draw('idgraphcustomerinvoices'); } elseif ($mode == 'fourn' || $mode == 'suppliers') { @@ -590,16 +609,16 @@ function getCustomerInvoiceDraftTable($maxCount = 500, $socid = 0) $sql .= ", s.rowid as socid, s.email"; $sql .= ", s.code_client, s.code_compta, s.code_fournisseur, s.code_compta_fournisseur"; $sql .= ", cc.rowid as country_id, cc.code as country_code"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user "; } $sql .= " FROM ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."societe as s LEFT JOIN ".MAIN_DB_PREFIX."c_country as cc ON cc.rowid = s.fk_pays"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.rowid = f.fk_soc AND f.fk_statut = ".Facture::STATUS_DRAFT; $sql .= " AND f.entity IN (".getEntity('invoice').")"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -614,7 +633,7 @@ function getCustomerInvoiceDraftTable($maxCount = 500, $socid = 0) $sql .= " GROUP BY f.rowid, f.ref, f.datef, f.total_ht, f.total_tva, f.total_ttc, f.ref_client, f.type, f.fk_statut, f.paye,"; $sql .= " s.nom, s.rowid, s.email, s.code_client, s.code_compta, s.code_fournisseur, s.code_compta_fournisseur,"; $sql .= " cc.rowid, cc.code"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user"; } @@ -738,12 +757,12 @@ function getDraftSupplierTable($maxCount = 500, $socid = 0) $sql .= ", s.code_fournisseur, s.code_compta_fournisseur"; $sql .= ", cc.rowid as country_id, cc.code as country_code"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f, ".MAIN_DB_PREFIX."societe as s LEFT JOIN ".MAIN_DB_PREFIX."c_country as cc ON cc.rowid = s.fk_pays"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.rowid = f.fk_soc AND f.fk_statut = ".FactureFournisseur::STATUS_DRAFT; $sql .= " AND f.entity IN (".getEntity('invoice').')'; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -860,7 +879,7 @@ function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0) $sql .= " s.nom as socname, s.rowid as socid, s.canvas, s.client"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; @@ -868,7 +887,7 @@ function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0) if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY f.tms DESC"; @@ -965,7 +984,7 @@ function getPurchaseInvoiceLatestEditTable($maxCount = 5, $socid = 0) $sql .= " s.nom as socname, s.rowid as socid, s.canvas, s.client"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; @@ -973,7 +992,7 @@ function getPurchaseInvoiceLatestEditTable($maxCount = 5, $socid = 0) if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY f.tms DESC"; @@ -1084,12 +1103,12 @@ function getCustomerInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $sql .= ", sum(pf.amount) as am"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s LEFT JOIN ".MAIN_DB_PREFIX."c_country as cc ON cc.rowid = s.fk_pays,".MAIN_DB_PREFIX."facture as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf on f.rowid=pf.fk_facture"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.rowid = f.fk_soc AND f.paye = 0 AND f.fk_statut = ".Facture::STATUS_VALIDATED; $sql .= " AND f.entity IN (".getEntity('invoice').')'; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -1218,7 +1237,7 @@ function getCustomerInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) print "\n"; } - print ''; + print ''; print ''; if (!empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) { print ''; @@ -1270,14 +1289,14 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $sql .= ", sum(pf.amount) as am"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."facture_fourn as ff"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf on ff.rowid=pf.fk_facturefourn"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.rowid = ff.fk_soc"; $sql .= " AND ff.entity = ".$conf->entity; $sql .= " AND ff.paye = 0"; $sql .= " AND ff.fk_statut = ".FactureFournisseur::STATUS_VALIDATED; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -1383,7 +1402,7 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) print "\n"; } - print ''; + print ''; print ''; if (!empty($conf->global->MAIN_SHOW_HT_ON_SUMMARY)) { print ''; diff --git a/htdocs/core/lib/ldap.lib.php b/htdocs/core/lib/ldap.lib.php index 9d6e0193108..56a8bcc4285 100644 --- a/htdocs/core/lib/ldap.lib.php +++ b/htdocs/core/lib/ldap.lib.php @@ -1,6 +1,6 @@ - * Copyright (C) 2006-2017 Regis Houssin + * Copyright (C) 2006-2021 Regis Houssin * * 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 @@ -89,7 +89,6 @@ function ldap_prepare_head() return $head; } - /** * Show button test LDAP synchro * @@ -119,7 +118,6 @@ function show_ldap_test_button($butlabel, $testlabel, $key, $dn, $objectclass) print '

    '; } - /** * Show a LDAP array into an HTML output array. * @@ -153,7 +151,7 @@ function show_ldap_content($result, $level, $count, $var, $hide = 0, $subcount = if ("$key" == "dn") { continue; } - if ("$val" == "objectclass") { + if (!is_array($val) && "$val" == "objectclass") { continue; } @@ -181,7 +179,7 @@ function show_ldap_content($result, $level, $count, $var, $hide = 0, $subcount = } print '
    '; } - if ("$val" != $lastkey[$level] && !$subcount) { + if (!is_array($val) && "$val" != $lastkey[$level] && !$subcount) { print '
    '; } } diff --git a/htdocs/core/lib/memory.lib.php b/htdocs/core/lib/memory.lib.php index 1300c1b771f..557bbe6dcf5 100644 --- a/htdocs/core/lib/memory.lib.php +++ b/htdocs/core/lib/memory.lib.php @@ -76,7 +76,7 @@ function dol_setcache($memoryid, $data, $expire = 0) } } - if (!empty($conf->memcached->enabled) && class_exists('Memcached')) { + if (!empty($conf->memcached->enabled) && class_exists('Memcached')) { // Using a memcached server global $dolmemcache; if (empty($dolmemcache) || !is_object($dolmemcache)) { @@ -88,7 +88,7 @@ function dol_setcache($memoryid, $data, $expire = 0) } } - $memoryid = session_name() . '_' . $memoryid; + $memoryid = session_name().'_'.$memoryid; //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false); $dolmemcache->add($memoryid, $data, $expire); // This fails if key already exists $rescode = $dolmemcache->getResultCode(); @@ -109,7 +109,7 @@ function dol_setcache($memoryid, $data, $expire = 0) } } - $memoryid = session_name() . '_' . $memoryid; + $memoryid = session_name().'_'.$memoryid; //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false); $result = $dolmemcache->add($memoryid, $data, false, $expire); // This fails if key already exists if ($result) { @@ -154,7 +154,7 @@ function dol_getcache($memoryid) } } - $memoryid = session_name() . '_' . $memoryid; + $memoryid = session_name().'_'.$memoryid; //$m->setOption(Memcached::OPT_COMPRESSION, false); //print "Get memoryid=".$memoryid; $data = $m->get($memoryid); @@ -179,7 +179,7 @@ function dol_getcache($memoryid) } } - $memoryid = session_name() . '_' . $memoryid; + $memoryid = session_name().'_'.$memoryid; //$m->setOption(Memcached::OPT_COMPRESSION, false); $data = $m->get($memoryid); //print "memoryid=".$memoryid." - rescode=".$rescode." - data=".count($data)."\n
    "; @@ -187,7 +187,7 @@ function dol_getcache($memoryid) if ($data) { return $data; } else { - return null; // There is no way to make a difference between NOTFOUND and error when using Memcache. So do not use it, use Memcached instead. + return null; // There is no way to make a difference between NOTFOUND and error when using Memcache. So do not use it, use Memcached instead. } } elseif (isset($conf->global->MAIN_OPTIMIZE_SPEED) && ($conf->global->MAIN_OPTIMIZE_SPEED & 0x02)) { // This is a really not reliable cache ! Use Memcached instead. // Using shmop @@ -252,7 +252,7 @@ function dol_setshmop($memoryid, $data, $expire) } $shmkey = dol_getshmopaddress($memoryid); if (empty($shmkey)) { - return 0; // No key reserved for this memoryid, we can't cache this memoryid + return 0; // No key reserved for this memoryid, we can't cache this memoryid } $newdata = serialize($data); @@ -268,7 +268,7 @@ function dol_setshmop($memoryid, $data, $expire) shmop_close($handle); return ($shm_bytes_written1 + $shm_bytes_written2); } else { - print 'Error in shmop_open for memoryid=' . $memoryid . ' shmkey=' . $shmkey . ' 6+size=6+' . $size; + print 'Error in shmop_open for memoryid='.$memoryid.' shmkey='.$shmkey.' 6+size=6+'.$size; return -1; } } @@ -290,7 +290,7 @@ function dol_getshmop($memoryid) } $shmkey = dol_getshmopaddress($memoryid); if (empty($shmkey)) { - return null; // No key reserved for this memoryid, we can't cache this memoryid + return null; // No key reserved for this memoryid, we can't cache this memoryid } //print 'dol_getshmop memoryid='.$memoryid." shmkey=".$shmkey."
    \n"; @@ -304,7 +304,7 @@ function dol_getshmop($memoryid) } shmop_close($handle); } else { - return null; // Can't open existing block, so we suppose it was not created, so nothing were cached yet for the memoryid + return null; // Can't open existing block, so we suppose it was not created, so nothing were cached yet for the memoryid } return $data; } diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index a5589679b50..d44da05fa38 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -17,8 +17,8 @@ */ /** - * \file htdocs/core/lib/memory.lib.php - * \brief Set of function for memory/cache management + * \file htdocs/core/lib/modulebuilder.lib.php + * \brief Set of function for modulebuilder management */ diff --git a/htdocs/core/lib/order.lib.php b/htdocs/core/lib/order.lib.php index f264eadaf58..0109847c59a 100644 --- a/htdocs/core/lib/order.lib.php +++ b/htdocs/core/lib/order.lib.php @@ -199,7 +199,7 @@ function getCustomerOrderPieChart($socid = 0) $sql = "SELECT count(c.rowid) as nb, c.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande as c"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -207,7 +207,7 @@ function getCustomerOrderPieChart($socid = 0) if ($user->socid) { $sql .= ' AND c.fk_soc = '.((int) $user->socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY c.fk_statut"; diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php index 4621e22d122..2bb1cf1d0cf 100644 --- a/htdocs/core/lib/payments.lib.php +++ b/htdocs/core/lib/payments.lib.php @@ -99,7 +99,7 @@ function bankline_prepare_head($id) */ function payment_supplier_prepare_head(Paiement $object) { - global $langs, $conf; + global $db, $langs, $conf; $h = 0; $head = array(); @@ -120,6 +120,19 @@ function payment_supplier_prepare_head(Paiement $object) $head[$h][2] = 'info'; $h++; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->fournisseur->payment->dir_output.'/'.$object->ref; + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = DOL_URL_ROOT.'/fourn/paiement/document.php?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) { + $head[$h][1] .= ''.($nbFiles + $nbLinks).''; + } + $head[$h][2] = 'documents'; + $h++; + complete_head_from_modules($conf, $langs, $object, $head, $h, 'payment_supplier', 'remove'); return $head; @@ -173,8 +186,9 @@ function showOnlinePaymentUrl($type, $ref) $out = img_picto('', 'globe').' '.$langs->trans("ToOfferALinkForOnlinePayment", $servicename).'
    '; $url = getOnlinePaymentUrl(0, $type, $ref); - $out .= ''; + $out .= ''; $out .= ajax_autoselect("onlinepaymenturl", 0); return $out; } @@ -224,7 +238,7 @@ function getOnlinePaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag } if ($type == 'free') { - $out = $urltouse.'/public/payment/newpayment.php?amount='.($mode ? '' : '').$amount.($mode ? '' : '').'&tag='.($mode ? '' : '').$freetag.($mode ? '' : ''); + $out = $urltouse.'/public/payment/newpayment.php?amount='.($mode ? '' : '').$amount.($mode ? '' : '').'&tag='.($mode ? '' : '').$freetag.($mode ? '' : ''); if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { $out .= '&securekey='.urlencode($conf->global->PAYMENT_SECURITY_TOKEN); @@ -234,120 +248,120 @@ function getOnlinePaymentUrl($mode, $type, $ref = '', $amount = '9.99', $freetag } //if ($mode) $out.='&noidempotency=1'; } elseif ($type == 'order') { - $out = $urltouse.'/public/payment/newpayment.php?source=order&ref='.($mode ? '' : ''); + $out = $urltouse.'/public/payment/newpayment.php?source=order&ref='.($mode ? '' : ''); if ($mode == 1) { $out .= 'order_ref'; } if ($mode == 0) { $out .= urlencode($ref); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { $out .= '&securekey='.urlencode($conf->global->PAYMENT_SECURITY_TOKEN); } else { - $out .= '&securekey='.($mode ? '' : ''); + $out .= '&securekey='.($mode ? '' : ''); if ($mode == 1) { $out .= "hash('".$conf->global->PAYMENT_SECURITY_TOKEN."' + '".$type."' + order_ref)"; } if ($mode == 0) { $out .= dol_hash($conf->global->PAYMENT_SECURITY_TOKEN.$type.$ref, 2); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); } } } elseif ($type == 'invoice') { - $out = $urltouse.'/public/payment/newpayment.php?source=invoice&ref='.($mode ? '' : ''); + $out = $urltouse.'/public/payment/newpayment.php?source=invoice&ref='.($mode ? '' : ''); if ($mode == 1) { $out .= 'invoice_ref'; } if ($mode == 0) { $out .= urlencode($ref); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { $out .= '&securekey='.urlencode($conf->global->PAYMENT_SECURITY_TOKEN); } else { - $out .= '&securekey='.($mode ? '' : ''); + $out .= '&securekey='.($mode ? '' : ''); if ($mode == 1) { $out .= "hash('".$conf->global->PAYMENT_SECURITY_TOKEN."' + '".$type."' + invoice_ref)"; } if ($mode == 0) { $out .= dol_hash($conf->global->PAYMENT_SECURITY_TOKEN.$type.$ref, 2); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); } } } elseif ($type == 'contractline') { - $out = $urltouse.'/public/payment/newpayment.php?source=contractline&ref='.($mode ? '' : ''); + $out = $urltouse.'/public/payment/newpayment.php?source=contractline&ref='.($mode ? '' : ''); if ($mode == 1) { $out .= 'contractline_ref'; } if ($mode == 0) { $out .= urlencode($ref); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { $out .= '&securekey='.urlencode($conf->global->PAYMENT_SECURITY_TOKEN); } else { - $out .= '&securekey='.($mode ? '' : ''); + $out .= '&securekey='.($mode ? '' : ''); if ($mode == 1) { $out .= "hash('".$conf->global->PAYMENT_SECURITY_TOKEN."' + '".$type."' + contractline_ref)"; } if ($mode == 0) { $out .= dol_hash($conf->global->PAYMENT_SECURITY_TOKEN.$type.$ref, 2); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); } } } elseif ($type == 'member' || $type == 'membersubscription') { $newtype = 'member'; - $out = $urltouse.'/public/payment/newpayment.php?source=member&ref='.($mode ? '' : ''); + $out = $urltouse.'/public/payment/newpayment.php?source=member&ref='.($mode ? '' : ''); if ($mode == 1) { $out .= 'member_ref'; } if ($mode == 0) { $out .= urlencode($ref); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { $out .= '&securekey='.urlencode($conf->global->PAYMENT_SECURITY_TOKEN); } else { - $out .= '&securekey='.($mode ? '' : ''); + $out .= '&securekey='.($mode ? '' : ''); if ($mode == 1) { $out .= "hash('".$conf->global->PAYMENT_SECURITY_TOKEN."' + '".$newtype."' + member_ref)"; } if ($mode == 0) { $out .= dol_hash($conf->global->PAYMENT_SECURITY_TOKEN.$newtype.$ref, 2); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); } } } if ($type == 'donation') { - $out = $urltouse.'/public/payment/newpayment.php?source=donation&ref='.($mode ? '' : ''); + $out = $urltouse.'/public/payment/newpayment.php?source=donation&ref='.($mode ? '' : ''); if ($mode == 1) { $out .= 'donation_ref'; } if ($mode == 0) { $out .= urlencode($ref); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { if (empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { $out .= '&securekey='.urlencode($conf->global->PAYMENT_SECURITY_TOKEN); } else { - $out .= '&securekey='.($mode ? '' : ''); + $out .= '&securekey='.($mode ? '' : ''); if ($mode == 1) { $out .= "hash('".$conf->global->PAYMENT_SECURITY_TOKEN."' + '".$type."' + donation_ref)"; } if ($mode == 0) { $out .= dol_hash($conf->global->PAYMENT_SECURITY_TOKEN.$type.$ref, 2); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); } } } @@ -450,7 +464,7 @@ function htmlPrintOnlinePaymentFooter($fromcompany, $langs, $addformmessage = 0, } } - print '

    '."\n"; + print '

    '."\n"; print $fromcompany->name.'
    '; print $line1; if (strlen($line1.$line2) > 50) { @@ -459,5 +473,5 @@ function htmlPrintOnlinePaymentFooter($fromcompany, $langs, $addformmessage = 0, print ' - '; } print $line2; - print '
    '."\n"; + print ''."\n"; } diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index c2257cd20fe..dda52e653fe 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -49,7 +49,7 @@ function pdf_admin_prepare_head() $head = array(); $head[$h][0] = DOL_URL_ROOT.'/admin/pdf.php'; - $head[$h][1] = $langs->trans("Common"); + $head[$h][1] = $langs->trans("Parameters"); $head[$h][2] = 'general'; $h++; @@ -177,8 +177,8 @@ function pdf_getInstance($format = '', $metric = 'mm', $pagetype = 'P') //$metric=$arrayformat['unit']; $pdfa = false; // PDF-1.3 - if (!empty($conf->global->PDF_USE_1A)) { - $pdfa = true; // PDF1/A + if (!empty($conf->global->PDF_USE_A)) { + $pdfa = $conf->global->PDF_USE_A; // PDF/A-1 ou PDF/A-3 } if (class_exists('TCPDI')) { @@ -979,6 +979,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $outputlangs->load("dict"); $line = ''; + $reg = array(); $dims = $pdf->getPageDimensions(); @@ -1045,7 +1046,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $line2 .= ($line2 ? " - " : "").$fromcompany->email; } } - if ($showdetails == 2 || $showdetails == 3 || ($fromcompany->country_code == 'DE')) { + if ($showdetails == 2 || $showdetails == 3 || (!empty($fromcompany->country_code) && $fromcompany->country_code == 'DE')) { // Managers if ($fromcompany->managers) { $line2 .= ($line2 ? " - " : "").$fromcompany->managers; @@ -1054,11 +1055,11 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ // Line 3 of company infos // Juridical status - if ($fromcompany->forme_juridique_code) { + if (!empty($fromcompany->forme_juridique_code) && $fromcompany->forme_juridique_code) { $line3 .= ($line3 ? " - " : "").$outputlangs->convToOutputCharset(getFormeJuridiqueLabel($fromcompany->forme_juridique_code)); } // Capital - if ($fromcompany->capital) { + if (!empty($fromcompany->capital) && $fromcompany->capital) { $tmpamounttoshow = price2num($fromcompany->capital); // This field is a free string if (is_numeric($tmpamounttoshow) && $tmpamounttoshow > 0) { $line3 .= ($line3 ? " - " : "").$outputlangs->transnoentities("CapitalOf", price($tmpamounttoshow, 0, $outputlangs, 0, 0, 0, $conf->currency)); @@ -1067,7 +1068,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ } } // Prof Id 1 - if ($fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) { + if (!empty($fromcompany->idprof1) && $fromcompany->idprof1 && ($fromcompany->country_code != 'FR' || !$fromcompany->idprof2)) { $field = $outputlangs->transcountrynoentities("ProfId1", $fromcompany->country_code); if (preg_match('/\((.*)\)/i', $field, $reg)) { $field = $reg[1]; @@ -1075,7 +1076,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $line3 .= ($line3 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof1); } // Prof Id 2 - if ($fromcompany->idprof2) { + if (!empty($fromcompany->idprof2) && $fromcompany->idprof2) { $field = $outputlangs->transcountrynoentities("ProfId2", $fromcompany->country_code); if (preg_match('/\((.*)\)/i', $field, $reg)) { $field = $reg[1]; @@ -1085,7 +1086,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ // Line 4 of company infos // Prof Id 3 - if ($fromcompany->idprof3) { + if (!empty($fromcompany->idprof3) && $fromcompany->idprof3) { $field = $outputlangs->transcountrynoentities("ProfId3", $fromcompany->country_code); if (preg_match('/\((.*)\)/i', $field, $reg)) { $field = $reg[1]; @@ -1093,7 +1094,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof3); } // Prof Id 4 - if ($fromcompany->idprof4) { + if (!empty($fromcompany->idprof4) && $fromcompany->idprof4) { $field = $outputlangs->transcountrynoentities("ProfId4", $fromcompany->country_code); if (preg_match('/\((.*)\)/i', $field, $reg)) { $field = $reg[1]; @@ -1101,7 +1102,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof4); } // Prof Id 5 - if ($fromcompany->idprof5) { + if (!empty($fromcompany->idprof5) && $fromcompany->idprof5) { $field = $outputlangs->transcountrynoentities("ProfId5", $fromcompany->country_code); if (preg_match('/\((.*)\)/i', $field, $reg)) { $field = $reg[1]; @@ -1109,7 +1110,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof5); } // Prof Id 6 - if ($fromcompany->idprof6) { + if (!empty($fromcompany->idprof6) && $fromcompany->idprof6) { $field = $outputlangs->transcountrynoentities("ProfId6", $fromcompany->country_code); if (preg_match('/\((.*)\)/i', $field, $reg)) { $field = $reg[1]; @@ -1117,7 +1118,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $line4 .= ($line4 ? " - " : "").$field.": ".$outputlangs->convToOutputCharset($fromcompany->idprof6); } // IntraCommunautary VAT - if ($fromcompany->tva_intra != '') { + if (!empty($fromcompany->tva_intra) && $fromcompany->tva_intra != '') { $line4 .= ($line4 ? " - " : "").$outputlangs->transnoentities("VATIntraShort").": ".$outputlangs->convToOutputCharset($fromcompany->tva_intra); } @@ -1273,6 +1274,7 @@ function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $pos // Fix bug of some HTML editors that replace links ]*src=")([^"]*)(&)([^"]*")/', '\1\2&\4', $labelproductservice, -1, $nbrep); //var_dump($labelproductservice);exit; @@ -2214,47 +2216,6 @@ function pdf_getlinetotalwithtax($object, $i, $outputlangs, $hidedetails = 0) return $result; } -/** - * Return total quantity of products and/or services - * - * @param Object $object Object - * @param string $type Type - * @param Translate $outputlangs Object langs for output - * @return integer - * @deprecated Not used by Dolibarr core, so will be removed. - */ -function pdf_getTotalQty($object, $type, $outputlangs) -{ - global $hookmanager; - - $total = 0; - $nblines = count($object->lines); - - // Loop on each lines - for ($i = 0; $i < $nblines; $i++) { - if ($object->lines[$i]->special_code != 3) { - if ($type == 'all') { - $total += $object->lines[$i]->qty; - } elseif ($type == 9 && is_object($hookmanager) && (($object->lines[$i]->product_type == 9 && !empty($object->lines[$i]->special_code)) || !empty($object->lines[$i]->fk_parent_line))) { - $special_code = $object->lines[$i]->special_code; - if (!empty($object->lines[$i]->fk_parent_line)) { - $special_code = $object->getSpecialCode($object->lines[$i]->fk_parent_line); - } - $parameters = array('i'=>$i, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'special_code'=>$special_code); - $action = ''; - $reshook = $hookmanager->executeHooks('pdf_getTotalQty', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks - return $hookmanager->resPrint; - } elseif ($type == 0 && $object->lines[$i]->product_type == 0) { - $total += $object->lines[$i]->qty; - } elseif ($type == 1 && $object->lines[$i]->product_type == 1) { - $total += $object->lines[$i]->qty; - } - } - } - - return $total; -} - /** * Return linked objects to use for document generation. * Warning: To save space, this function returns only one link per link type (all links are concated on same record string). This function is used by pdf_writeLinkedObjects @@ -2263,7 +2224,7 @@ function pdf_getTotalQty($object, $type, $outputlangs) * @param Translate $outputlangs Object lang for output * @return array Linked objects */ -function pdf_getLinkedObjects($object, $outputlangs) +function pdf_getLinkedObjects(&$object, $outputlangs) { global $db, $hookmanager; @@ -2285,7 +2246,17 @@ function pdf_getLinkedObjects($object, $outputlangs) } } elseif ($objecttype == 'commande' || $objecttype == 'supplier_order') { $outputlangs->load('orders'); - foreach ($objects as $elementobject) { + + if (count($objects) > 1) { + $object->note_public .= dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefOrder").' :
    '); + foreach ($objects as $elementobject) { + $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref).($elementobject->ref_client ? ' ('.$elementobject->ref_client.')' : '').($elementobject->ref_supplier ? ' ('.$elementobject->ref_supplier.')' : '').' '); + $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->transnoentities("OrderDate").' : '); + $object->note_public .= dol_concatdesc($object->note_public, dol_print_date($elementobject->date, 'day', '', $outputlangs)); + $object->note_public .= dol_concatdesc($object->note_public, '
    '); + } + } elseif (count($objects) == 1) { + $elementobject = array_shift($objects); $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder"); $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref).($elementobject->ref_client ? ' ('.$elementobject->ref_client.')' : '').($elementobject->ref_supplier ? ' ('.$elementobject->ref_supplier.')' : ''); $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate"); @@ -2310,12 +2281,40 @@ function pdf_getLinkedObjects($object, $outputlangs) } elseif ($objecttype == 'shipping') { $outputlangs->loadLangs(array("orders", "sendings")); - foreach ($objects as $x => $elementobject) { + if (count($objects) > 1) { + $order = null; + if (empty($object->linkedObjects['commande']) && $object->element != 'commande') $object->note_public .= dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending").' :
    '); + else $object->note_public .= dol_concatdesc($object->note_public, '
    '.$outputlangs->transnoentities("RefSending").' :
    '); + // We concat this record info into fields xxx_value. title is overwrote. + foreach ($objects as $elementobject) { + if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { // There is not already a link to order and object is not the order, so we show also info with order + $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0); + if (! empty($elementobject->linkedObjectsIds['commande'])) { + include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; + $order = new Commande($db); + $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande'])); + if ($ret < 1) { + $order = null; + } + } + } + + if (! is_object($order)) { + $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->transnoentities($elementobject->ref)); + $object->note_public .= dol_concatdesc($object->note_public, '
    '); + } else { + $object->note_public .= dol_concatdesc($object->note_public, $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : '')); + $object->note_public .= dol_concatdesc($object->note_public, ' / '.$outputlangs->transnoentities($elementobject->ref)); + $object->note_public .= dol_concatdesc($object->note_public, '
    '); + } + } + } elseif (count($objects) == 1) { + $elementobject = array_shift($objects); $order = null; // We concat this record info into fields xxx_value. title is overwrote. - if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { // There is not already a link to order and object is not the order, so we show also info with order + if (empty($object->linkedObjects['commande']) && $object->element != 'commande') { // There is not already a link to order and object is not the order, so we show also info with order $elementobject->fetchObjectLinked(null, '', null, '', 'OR', 1, 'sourcetype', 0); - if (!empty($elementobject->linkedObjectsIds['commande'])) { + if (! empty($elementobject->linkedObjectsIds['commande'])) { include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; $order = new Commande($db); $ret = $order->fetch(reset($elementobject->linkedObjectsIds['commande'])); @@ -2324,24 +2323,15 @@ function pdf_getLinkedObjects($object, $outputlangs) } } } - if (!is_object($order)) { + + if (! is_object($order)) { $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending"); - if (!empty($linkedobjects[$objecttype]['ref_value'])) { - $linkedobjects[$objecttype]['ref_value'] .= ' / '; - } + if (! empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] .= ' / '; $linkedobjects[$objecttype]['ref_value'] .= $outputlangs->transnoentities($elementobject->ref); - //$linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateShipment"); - //if (! empty($linkedobjects[$objecttype]['date_value'])) $linkedobjects[$objecttype]['date_value'].=' / '; - //$linkedobjects[$objecttype]['date_value'].= dol_print_date($elementobject->date_delivery,'day','',$outputlangs); } else { $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder").' / '.$outputlangs->transnoentities("RefSending"); - if (empty($linkedobjects[$objecttype]['ref_value'])) { - $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''); - } + if (empty($linkedobjects[$objecttype]['ref_value'])) $linkedobjects[$objecttype]['ref_value'] = $outputlangs->convToOutputCharset($order->ref).($order->ref_client ? ' ('.$order->ref_client.')' : ''); $linkedobjects[$objecttype]['ref_value'] .= ' / '.$outputlangs->transnoentities($elementobject->ref); - //$linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate") . ($elementobject->date_delivery ? ' / ' . $outputlangs->transnoentities("DateShipment") : ''); - //if (empty($linkedobjects[$objecttype]['date_value'])) $linkedobjects[$objecttype]['date_value'] = dol_print_date($order->date,'day','',$outputlangs); - //$linkedobjects[$objecttype]['date_value'].= ($elementobject->date_delivery ? ' / ' . dol_print_date($elementobject->date_delivery,'day','',$outputlangs) : ''); } } } diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index 9be293a81ab..28723ab87db 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -157,8 +157,8 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt if ($resql) { $obj = $db->fetch_object($resql); if ($obj) { - $localtax1_rate = (float) $obj->localtax1; // Use float to force to get first numeric value when value is x:y:z - $localtax2_rate = (float) $obj->localtax2; // Use float to force to get first numeric value when value is -19:-15:-9 + $localtax1_rate = (float) $obj->localtax1; // Use float to force to get first numeric value when value is x:y:z + $localtax2_rate = (float) $obj->localtax2; // Use float to force to get first numeric value when value is -19:-15:-9 $localtax1_type = $obj->localtax1_type; $localtax2_type = $obj->localtax2_type; //var_dump($localtax1_rate.' '.$localtax2_rate.' '.$localtax1_type.' '.$localtax2_type); @@ -443,7 +443,7 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt // initialize result array //for ($i=0; $i <= 18; $i++) $result[$i] = (float) $result[$i]; - dol_syslog('Price.lib::calcul_price_total MAIN_ROUNDING_RULE_TOT='.(empty($conf->global->MAIN_ROUNDING_RULE_TOT)?'':$conf->global->MAIN_ROUNDING_RULE_TOT).' pu='.$pu.' qty='.$qty.' price_base_type='.$price_base_type.' total_ht='.$result[0].'-total_vat='.$result[1].'-total_ttc='.$result[2]); + dol_syslog('Price.lib::calcul_price_total MAIN_ROUNDING_RULE_TOT='.(empty($conf->global->MAIN_ROUNDING_RULE_TOT) ? '' : $conf->global->MAIN_ROUNDING_RULE_TOT).' pu='.$pu.' qty='.$qty.' price_base_type='.$price_base_type.' total_ht='.$result[0].'-total_vat='.$result[1].'-total_ttc='.$result[2]); return $result; } diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index 64cc72a8879..10c838b4c43 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -589,12 +589,12 @@ function measuring_units_string($scale = '', $measuring_style = '', $unit = 0, $ /** * Return translation label of a unit key * - * @param int $unit ID of unit (rowid in llx_c_units table) - * @param string $measuring_style Style of unit: 'weight', 'volume', ..., '' = 'net_measure' for option PRODUCT_ADD_NET_MEASURE - * @param string $scale Scale of unit: '0', '-3', '6', ... - * @param int $use_short_label 1=Use short label ('g' instead of 'gram'). Short labels are not translated. + * @param int $unit ID of unit (rowid in llx_c_units table) + * @param string $measuring_style Style of unit: 'weight', 'volume', ..., '' = 'net_measure' for option PRODUCT_ADD_NET_MEASURE + * @param string $scale Scale of unit: '0', '-3', '6', ... + * @param int $use_short_label 1=Use short label ('g' instead of 'gram'). Short labels are not translated. * @param Translate $outputlangs Language object - * @return string Unit string + * @return string Unit string * @see formproduct->selectMeasuringUnits() */ function measuringUnitString($unit, $measuring_style = '', $scale = '', $use_short_label = 0, $outputlangs = null) diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 0eba9dde1b5..e9e06708f7c 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -31,16 +31,17 @@ require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; * Prepare array with list of tabs * * @param Project $project Object related to tabs + * @param string $moreparam More param on url * @return array Array of tabs to show */ -function project_prepare_head(Project $project) +function project_prepare_head(Project $project, $moreparam = '') { global $db, $langs, $conf, $user; $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/projet/card.php?id='.$project->id; + $head[$h][0] = DOL_URL_ROOT.'/projet/card.php?id='.((int) $project->id).($moreparam ? '&'.$moreparam : ''); $head[$h][1] = $langs->trans("Project"); $head[$h][2] = 'project'; $h++; @@ -56,7 +57,7 @@ function project_prepare_head(Project $project) $nbContacts = count($project->liste_contact(-1, 'internal')) + count($project->liste_contact(-1, 'external')); dol_setcache($cachekey, $nbContacts, 120); // If setting cache fails, this is not a problem, so we do not test result. } - $head[$h][0] = DOL_URL_ROOT.'/projet/contact.php?id='.$project->id; + $head[$h][0] = DOL_URL_ROOT.'/projet/contact.php?id='.((int) $project->id).($moreparam ? '&'.$moreparam : ''); $head[$h][1] = $langs->trans("ProjectContact"); if ($nbContacts > 0) { $head[$h][1] .= ''.$nbContacts.''; @@ -80,7 +81,7 @@ function project_prepare_head(Project $project) $nbTasks = count($taskstatic->getTasksArray(0, 0, $project->id, 0, 0)); dol_setcache($cachekey, $nbTasks, 120); // If setting cache fails, this is not a problem, so we do not test result. } - $head[$h][0] = DOL_URL_ROOT.'/projet/tasks.php?id='.$project->id; + $head[$h][0] = DOL_URL_ROOT.'/projet/tasks.php?id='.((int) $project->id).($moreparam ? '&'.$moreparam : ''); $head[$h][1] = $langs->trans("Tasks"); if ($nbTasks > 0) { $head[$h][1] .= ''.($nbTasks).''; @@ -113,7 +114,7 @@ function project_prepare_head(Project $project) } } - $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&projectid='.urlencode($project->id); + $head[$h][0] = DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&projectid='.((int) $project->id).($moreparam ? '&'.$moreparam : ''); $head[$h][1] = $langs->trans("TimeSpent"); if ($nbTimeSpent > 0) { $head[$h][1] .= '...'; @@ -125,7 +126,7 @@ function project_prepare_head(Project $project) if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) || !empty($conf->propal->enabled) || !empty($conf->commande->enabled) || !empty($conf->facture->enabled) || !empty($conf->contrat->enabled) - || !empty($conf->ficheinter->enabled) || !empty($conf->agenda->enabled) || !empty($conf->deplacement->enabled)) { + || !empty($conf->ficheinter->enabled) || !empty($conf->agenda->enabled) || !empty($conf->deplacement->enabled) || !empty($conf->stock->enabled)) { $nbElements = 0; // Enable caching of thirdrparty count Contacts $cachekey = 'count_elements_project_'.$project->id; @@ -133,6 +134,9 @@ function project_prepare_head(Project $project) if (!is_null($dataretrieved)) { $nbElements = $dataretrieved; } else { + if (!empty($conf->stock->enabled)) { + $nbElements += $project->getElementCount('stock', 'entrepot', 'fk_project'); + } if (!empty($conf->propal->enabled)) { $nbElements += $project->getElementCount('propal', 'propal'); } @@ -307,7 +311,7 @@ function project_prepare_head(Project $project) } $head[$h][0] = DOL_URL_ROOT.'/projet/info.php?id='.$project->id; - $head[$h][1] .= $langs->trans("Events"); + $head[$h][1] = $langs->trans("Events"); if (!empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { $head[$h][1] .= '/'; $head[$h][1] .= $langs->trans("Agenda"); @@ -467,14 +471,6 @@ function project_timesheet_prepare_head($mode, $fuser = null) $h++; } - /*if ($conf->global->MAIN_FEATURES_LEVEL >= 2) - { - $head[$h][0] = DOL_URL_ROOT."/projet/activity/perline.php".($param?'?'.$param:''); - $head[$h][1] = $langs->trans("InputDetail"); - $head[$h][2] = 'inputperline'; - $h++; - }*/ - complete_head_from_modules($conf, $langs, null, $head, $h, 'project_timesheet'); complete_head_from_modules($conf, $langs, null, $head, $h, 'project_timesheet', 'remove'); @@ -513,7 +509,7 @@ function project_admin_prepare_head() $head[$h][2] = 'attributes_task'; $h++; - if (! empty($conf->global->MAIN_FEATURES_LEVEL) && $conf->global->MAIN_FEATURES_LEVEL >= 2) { + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { $langs->load("members"); $head[$h][0] = DOL_URL_ROOT.'/projet/admin/website.php'; @@ -568,7 +564,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t $numlines = count($lines); // We declare counter as global because we want to edit them into recursive call - global $total_projectlinesa_spent, $total_projectlinesa_planned, $total_projectlinesa_spent_if_planned, $total_projectlinesa_declared_if_planned, $total_projectlinesa_tobill, $total_projectlinesa_billed; + global $total_projectlinesa_spent, $total_projectlinesa_planned, $total_projectlinesa_spent_if_planned, $total_projectlinesa_declared_if_planned, $total_projectlinesa_tobill, $total_projectlinesa_billed, $total_budget_amount; if ($level == 0) { $total_projectlinesa_spent = 0; @@ -577,6 +573,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t $total_projectlinesa_declared_if_planned = 0; $total_projectlinesa_tobill = 0; $total_projectlinesa_billed = 0; + $total_budget_amount = 0; } for ($i = 0; $i < $numlines; $i++) { @@ -647,6 +644,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t $taskstatic->datee = $lines[$i]->date_end; // deprecated $taskstatic->planned_workload = $lines[$i]->planned_workload; $taskstatic->duration_effective = $lines[$i]->duration; + $taskstatic->budget_amount = $lines[$i]->budget_amount; if ($showproject) { @@ -846,6 +844,12 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } print ''; }*/ + if (count($arrayfields) > 0 && !empty($arrayfields['c.assigned']['checked'])) { + print ''; + } // Contacts of task if (count($arrayfields) > 0 && !empty($arrayfields['c.assigned']['checked'])) { @@ -917,7 +921,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } } - if (($total_projectlinesa_planned > 0 || $total_projectlinesa_spent > 0 || $total_projectlinesa_tobill > 0 || $total_projectlinesa_billed > 0) + if (($total_projectlinesa_planned > 0 || $total_projectlinesa_spent > 0 || $total_projectlinesa_tobill > 0 || $total_projectlinesa_billed > 0 || $total_budget_amount > 0) && $level <= 0) { print ''; print ''; @@ -973,6 +977,7 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } } + // Computed progress if (count($arrayfields) > 0 && !empty($arrayfields['t.progress_calculated']['checked'])) { print ''; } + + // Declared progress if (count($arrayfields) > 0 && !empty($arrayfields['t.progress']['checked'])) { print ''; } } + + if (count($arrayfields) > 0 && !empty($arrayfields['t.budget_amount']['checked'])) { + print ''; + } + // Contacts of task for backward compatibility, if (!empty($conf->global->PROJECT_SHOW_CONTACTS_IN_LIST)) { print ''; diff --git a/htdocs/core/lib/propal.lib.php b/htdocs/core/lib/propal.lib.php index 038ab2a7911..c5d2a647a57 100644 --- a/htdocs/core/lib/propal.lib.php +++ b/htdocs/core/lib/propal.lib.php @@ -178,7 +178,7 @@ function getCustomerProposalPieChart($socid = 0) $sql = "SELECT count(p.rowid) as nb, p.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."propal as p"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE p.entity IN (".getEntity($propalstatic->element).")"; @@ -186,7 +186,7 @@ function getCustomerProposalPieChart($socid = 0) if ($user->socid) { $sql .= ' AND p.fk_soc = '.((int) $user->socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " AND p.fk_statut IN (".$db->sanitize(implode(" ,", $listofstatus)).")"; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index b297c81035e..ede899d7761 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -1,6 +1,6 @@ - * Copyright (C) 2008-2017 Regis Houssin +/* Copyright (C) 2008-2021 Laurent Destailleur + * Copyright (C) 2008-2021 Regis Houssin * Copyright (C) 2020 Ferran Marcet * * This program is free software; you can redistribute it and/or modify @@ -91,7 +91,6 @@ function dol_decode($chain, $key = '1') return $chain; } - /** * Returns a hash of a string. * If constant MAIN_SECURITY_HASH_ALGO is defined, we use this function as hashing function (recommanded value is 'password_hash') @@ -123,7 +122,7 @@ function dol_hash($chain, $type = '0') } elseif ($type == '3' || $type == 'md5') { return md5($chain); } elseif ($type == '4' || $type == 'md5openldap') { - return '{md5}'.base64_encode(mhash(MHASH_MD5, $chain)); // For OpenLdap with md5 (based on an unencrypted password in base) + return '{md5}'.base64_encode(pack("H*", md5($chain))); // For OpenLdap with md5 (based on an unencrypted password in base) } elseif ($type == '5' || $type == 'sha256') { return hash('sha256', $chain); } elseif ($type == '6' || $type == 'password_hash') { @@ -168,7 +167,6 @@ function dol_verifyHash($chain, $hash, $type = '0') return dol_hash($chain, $type) == $hash; } - /** * Check permissions of a user to show a page and an object. Check read permission. * If GETPOST('action','aZ09') defined, we also check write and delete permission. @@ -279,12 +277,12 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f } if ($feature == 'societe') { - if (!$user->rights->societe->lire && !$user->rights->fournisseur->lire) { + if (empty($user->rights->societe->lire) && empty($user->rights->fournisseur->lire)) { $readok = 0; $nbko++; } } elseif ($feature == 'contact') { - if (!$user->rights->societe->contact->lire) { + if (empty($user->rights->societe->contact->lire)) { $readok = 0; $nbko++; } @@ -299,12 +297,12 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f $nbko++; } } elseif ($feature == 'cheque') { - if (!$user->rights->banque->cheque) { + if (empty($user->rights->banque->cheque)) { $readok = 0; $nbko++; } } elseif ($feature == 'projet') { - if (!$user->rights->projet->lire && !$user->rights->projet->all->lire) { + if (!$user->rights->projet->lire && empty($user->rights->projet->all->lire)) { $readok = 0; $nbko++; } @@ -314,7 +312,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f $nbko++; } } elseif ($feature == 'payment_supplier') { - if (!$user->rights->fournisseur->facture->lire) { + if (empty($user->rights->fournisseur->facture->lire)) { $readok = 0; $nbko++; } @@ -364,18 +362,18 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f // Check write permission from module (we need to know write permission to create but also to delete drafts record or to upload files) $createok = 1; $nbko = 0; - $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || GETPOST('action', 'aZ09') == 'create' || GETPOST('action', 'aZ09') == 'update') || GETPOST('roworder', 'alpha', 2); + $wemustcheckpermissionforcreate = (GETPOST('sendit', 'alpha') || GETPOST('linkit', 'alpha') || in_array(GETPOST('action', 'aZ09'), array('create', 'update', 'add_element_resource', 'confirm_delete_linked_resource')) || GETPOST('roworder', 'alpha', 2)); $wemustcheckpermissionfordeletedraft = ((GETPOST("action", "aZ09") == 'confirm_delete' && GETPOST("confirm", "aZ09") == 'yes') || GETPOST("action", "aZ09") == 'delete'); if ($wemustcheckpermissionforcreate || $wemustcheckpermissionfordeletedraft) { foreach ($featuresarray as $feature) { if ($feature == 'contact') { - if (!$user->rights->societe->contact->creer) { + if (empty($user->rights->societe->contact->creer)) { $createok = 0; $nbko++; } } elseif ($feature == 'produit|service') { - if (!$user->rights->produit->creer && !$user->rights->service->creer) { + if (empty($user->rights->produit->creer) && empty($user->rights->service->creer)) { $createok = 0; $nbko++; } @@ -385,22 +383,22 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f $nbko++; } } elseif ($feature == 'commande_fournisseur') { - if (!$user->rights->fournisseur->commande->creer || !$user->rights->supplier_order->creer) { + if (empty($user->rights->fournisseur->commande->creer) || empty($user->rights->supplier_order->creer)) { $createok = 0; $nbko++; } } elseif ($feature == 'banque') { - if (!$user->rights->banque->modifier) { + if (empty($user->rights->banque->modifier)) { $createok = 0; $nbko++; } } elseif ($feature == 'cheque') { - if (!$user->rights->banque->cheque) { + if (empty($user->rights->banque->cheque)) { $createok = 0; $nbko++; } } elseif ($feature == 'import') { - if (!$user->rights->import->run) { + if (empty($user->rights->import->run)) { $createok = 0; $nbko++; } @@ -417,6 +415,9 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f if ($subfeature == 'user' && $user->id == $objectid && $user->rights->user->self->password) { continue; // User can edit its own password } + if ($subfeature == 'user' && $user->id != $objectid && $user->rights->user->user->password) { + continue; // User can edit another user's password + } if (empty($user->rights->$feature->$subfeature->creer) && empty($user->rights->$feature->$subfeature->write) @@ -489,16 +490,20 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f if (!$user->rights->fournisseur->commande->supprimer) { $deleteok = 0; } - } elseif ($feature == 'payment_supplier') { + } elseif ($feature == 'payment_supplier') { // Permission to delete a payment of an invoice is permission to edit an invoice. if (!$user->rights->fournisseur->facture->creer) { $deleteok = 0; } + } elseif ($feature == 'payment') { // Permission to delete a payment of an invoice is permission to edit an invoice. + if (!$user->rights->facture->creer) { + $deleteok = 0; + } } elseif ($feature == 'banque') { - if (!$user->rights->banque->modifier) { + if (empty($user->rights->banque->modifier)) { $deleteok = 0; } } elseif ($feature == 'cheque') { - if (!$user->rights->banque->cheque) { + if (empty($user->rights->banque->cheque)) { $deleteok = 0; } } elseif ($feature == 'ecm') { @@ -513,8 +518,8 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f if (!$user->rights->salaries->delete) { $deleteok = 0; } - } elseif ($feature == 'salaries') { - if (!$user->rights->salaries->delete) { + } elseif ($feature == 'adherent') { + if (empty($user->rights->adherent->supprimer)) { $deleteok = 0; } } elseif (!empty($feature2)) { // This is for permissions on 2 levels @@ -611,11 +616,11 @@ function checkUserAccessToObject($user, array $featuresarray, $objectid = 0, $ta $feature = 'projet_task'; } - $check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'salary', 'website'); // Test on entity only (Objects with no link to company) + $check = array('adherent', 'banque', 'bom', 'don', 'mrp', 'user', 'usergroup', 'payment', 'payment_supplier', 'product', 'produit', 'service', 'produit|service', 'categorie', 'resource', 'expensereport', 'holiday', 'salaries', 'website'); // Test on entity only (Objects with no link to company) $checksoc = array('societe'); // Test for societe object $checkother = array('contact', 'agenda'); // Test on entity + link to third party on field $dbt_keyfield. Allowed if link is empty (Ex: contacts...). $checkproject = array('projet', 'project'); // Test for project object - $checktask = array('projet_task'); // Test for task object + $checktask = array('projet_task'); // Test for task object $nocheck = array('barcode', 'stock'); // No test //$checkdefault = 'all other not already defined'; // Test on entity + link to third party on field $dbt_keyfield. Not allowed if link is empty (Ex: invoice, orders...). @@ -662,7 +667,7 @@ function checkUserAccessToObject($user, array $featuresarray, $objectid = 0, $ta if ($user->socid <> $objectid) { return false; } - } elseif (!empty($conf->societe->enabled) && ($user->rights->societe->lire && !$user->rights->societe->client->voir)) { + } elseif (!empty($conf->societe->enabled) && ($user->rights->societe->lire && empty($user->rights->societe->client->voir))) { // If internal user: Check permission for internal users that are restricted on their objects $sql = "SELECT COUNT(sc.fk_soc) as nb"; $sql .= " FROM (".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -685,7 +690,7 @@ function checkUserAccessToObject($user, array $featuresarray, $objectid = 0, $ta $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; $sql .= " WHERE dbt.".$dbt_select." IN (".$db->sanitize($objectid, 1).")"; $sql .= " AND dbt.fk_soc = ".((int) $user->socid); - } elseif (!empty($conf->societe->enabled) && ($user->rights->societe->lire && !$user->rights->societe->client->voir)) { + } elseif (!empty($conf->societe->enabled) && ($user->rights->societe->lire && empty($user->rights->societe->client->voir))) { // If internal user: Check permission for internal users that are restricted on their objects $sql = "SELECT COUNT(dbt.".$dbt_select.") as nb"; $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; @@ -755,7 +760,7 @@ function checkUserAccessToObject($user, array $featuresarray, $objectid = 0, $ta $sql .= " FROM ".MAIN_DB_PREFIX.$dbtablename." as dbt"; $sql .= " WHERE dbt.rowid IN (".$db->sanitize($objectid, 1).")"; $sql .= " AND dbt.".$dbt_keyfield." = ".((int) $user->socid); - } elseif (!empty($conf->societe->enabled) && !$user->rights->societe->client->voir) { + } elseif (!empty($conf->societe->enabled) && empty($user->rights->societe->client->voir)) { // If internal user: Check permission for internal users that are restricted on their objects if ($feature != 'ticket') { if (empty($dbt_keyfield)) { @@ -853,7 +858,7 @@ function accessforbidden($message = '', $printheader = 1, $printfooter = 1, $sho print $hookmanager->resPrint; if (empty($reshook)) { if ($user->login) { - print $langs->trans("CurrentLogin").': '.$user->login.'
    '; + print $langs->trans("CurrentLogin").': '.$user->login.'
    '; print $langs->trans("ErrorForbidden2", $langs->transnoentitiesnoconv("Home"), $langs->transnoentitiesnoconv("Users")); } else { print $langs->trans("ErrorForbidden3"); diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index e015313ad15..2edb2e629de 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -215,15 +215,20 @@ if (!function_exists('dol_loginfunction')) { } // Execute hook getLoginPageOptions (for table) - $parameters = array('entity' => GETPOST('entity', 'int')); + $parameters = array('entity' => GETPOST('entity', 'int'), 'switchentity' => GETPOST('switchentity', 'int')); $reshook = $hookmanager->executeHooks('getLoginPageOptions', $parameters); // Note that $action and $object may have been modified by some hooks. $morelogincontent = $hookmanager->resPrint; // Execute hook getLoginPageExtraOptions (eg for js) - $parameters = array('entity' => GETPOST('entity', 'int')); + $parameters = array('entity' => GETPOST('entity', 'int'), 'switchentity' => GETPOST('switchentity', 'int')); $reshook = $hookmanager->executeHooks('getLoginPageExtraOptions', $parameters); // Note that $action and $object may have been modified by some hooks. $moreloginextracontent = $hookmanager->resPrint; + //Redirect after connection + $parameters = array('entity' => GETPOST('entity', 'int'), 'switchentity' => GETPOST('switchentity', 'int')); + $reshook = $hookmanager->executeHooks('redirectAfterConnection', $parameters); // Note that $action and $object may have been modified by some hooks. + $php_self = $hookmanager->resPrint; + // Login $login = (!empty($hookmanager->resArray['username']) ? $hookmanager->resArray['username'] : (GETPOST("username", "alpha") ? GETPOST("username", "alpha") : $demologin)); $password = $demopassword; @@ -234,7 +239,7 @@ if (!function_exists('dol_loginfunction')) { if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) { $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/thumbs/'.$mysoc->logo_small); - } elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) { + } elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) { $urllogo = DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=mycompany&file='.urlencode('logos/'.$mysoc->logo); $width = 128; } elseif (!empty($mysoc->logo_squarred_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_squarred_small)) { diff --git a/htdocs/core/lib/signature.lib.php b/htdocs/core/lib/signature.lib.php index 82f446f04c7..13df1ad8d9d 100644 --- a/htdocs/core/lib/signature.lib.php +++ b/htdocs/core/lib/signature.lib.php @@ -39,8 +39,9 @@ function showOnlineSignatureUrl($type, $ref) if ($url == $langs->trans("FeatureOnlineSignDisabled")) { $out .= $url; } else { - $out .= ''; + $out .= ''; } + $out .= ''.img_picto('', 'globe', 'class="paddingleft"').''; $out .= ''; $out .= ajax_autoselect("onlinesignatureurl", 0); return $out; @@ -63,16 +64,16 @@ function getOnlineSignatureUrl($mode, $type, $ref = '') $out = ''; if ($type == 'proposal') { - $out = DOL_MAIN_URL_ROOT.'/public/onlinesign/newonlinesign.php?source=proposal&ref='.($mode ? '' : ''); + $out = DOL_MAIN_URL_ROOT.'/public/onlinesign/newonlinesign.php?source=proposal&ref='.($mode ? '' : ''); if ($mode == 1) { $out .= 'proposal_ref'; } if ($mode == 0) { $out .= urlencode($ref); } - $out .= ($mode ? '' : ''); + $out .= ($mode ? '' : ''); if ($mode == 1) { - $out .= '&hashp=hash_of_file'; + $out .= '&hashp=hash_of_file'; } else { include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; $propaltmp = new Propal($db); diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php index 9506984f4f3..e2067240c45 100644 --- a/htdocs/core/lib/ticket.lib.php +++ b/htdocs/core/lib/ticket.lib.php @@ -101,7 +101,7 @@ function ticket_prepare_head($object) include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $upload_dir = $conf->ticket->dir_output."/".$object->ref; $nbFiles = count(dol_dir_list($upload_dir, 'files')); - $head[$h][0] = dol_buildpath('/ticket/document.php', 1).'?id='.$object->id; + $head[$h][0] = DOL_URL_ROOT.'/ticket/document.php?id='.$object->id; $head[$h][1] = $langs->trans("Documents"); if ($nbFiles > 0) { $head[$h][1] .= ''.$nbFiles.''; @@ -699,7 +699,7 @@ function show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon = '', $no if ($user->rights->agenda->allactions->create || (($actionstatic->authorid == $user->id || $actionstatic->userownerid == $user->id) && $user->rights->agenda->myactions->create)) { - $out .= ''; + $out .= ''; } $out .= ''; diff --git a/htdocs/core/lib/treeview.lib.php b/htdocs/core/lib/treeview.lib.php index fda21e28a21..05e6d51a78d 100644 --- a/htdocs/core/lib/treeview.lib.php +++ b/htdocs/core/lib/treeview.lib.php @@ -190,7 +190,7 @@ function tree_recur($tab, $pere, $rang, $iddivjstree = 'iddivjstree', $donoreset print "\n".'
  • '; if ($showfk) { print '
  • '.$langs->trans("Statistics").' - '; + $result .= ''.$langs->trans("NbOfOpenInvoices").' - '; if ($mode == 'customers') { $result .= $langs->trans("CustomerInvoice"); } elseif ($mode == 'fourn' || $mode == 'suppliers') { @@ -537,14 +551,19 @@ function getNumberInvoicesPieChart($mode) $result .= '
    '.$langs->trans("Total").'   ('.$langs->trans("RemainderToTake").': '.price($total_ttc - $totalam).')
    '.$langs->trans("Total").'   ('.$langs->trans("RemainderToTake").': '.price($total_ttc - $totalam).')  '.price($total).'
    '.$langs->trans("Total").'   ('.$langs->trans("RemainderToPay").': '.price($total_ttc - $totalam).')
    '.$langs->trans("Total").'   ('.$langs->trans("RemainderToPay").': '.price($total_ttc - $totalam).')  '.price($total).'
    '; + print price($lines[$i]->budget_amount, 0, $langs, 1, 0, 0, $conf->currency); + $total_budget_amount += $lines[$i]->budget_amount; + print '
    '.$langs->trans("Total").''; if ($total_projectlinesa_planned) { @@ -980,6 +985,8 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t } print ''; if ($total_projectlinesa_planned) { @@ -1014,6 +1021,13 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t print ''; + print price($total_budget_amount, 0, $langs, 1, 0, 0, $conf->currency); + print '
    '; $html .= ''."\n"; diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php index 0d824d2c7c0..02ba610961d 100644 --- a/htdocs/core/modules/printing/printipp.modules.php +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -1,6 +1,6 @@ + * Copyright (C) 2014-2021 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 @@ -108,10 +108,10 @@ class printing_printipp extends PrintingDriver global $conf; $this->db = $db; - $this->host = $conf->global->PRINTIPP_HOST; - $this->port = $conf->global->PRINTIPP_PORT; - $this->user = $conf->global->PRINTIPP_USER; - $this->password = $conf->global->PRINTIPP_PASSWORD; + $this->host = getDolGlobalString('PRINTIPP_HOST'); + $this->port = getDolGlobalString('PRINTIPP_PORT'); + $this->user = getDolGlobalString('PRINTIPP_USER'); + $this->password = getDolGlobalString('PRINTIPP_PASSWORD'); $this->conf[] = array('varname'=>'PRINTIPP_HOST', 'required'=>1, 'example'=>'localhost', 'type'=>'text'); $this->conf[] = array('varname'=>'PRINTIPP_PORT', 'required'=>1, 'example'=>'631', 'type'=>'text'); $this->conf[] = array('varname'=>'PRINTIPP_USER', 'required'=>0, 'example'=>'', 'type'=>'text', 'moreattributes'=>'autocomplete="off"'); @@ -159,8 +159,8 @@ class printing_printipp extends PrintingDriver $ipp->setCopies($obj->copy); } else { if (!empty($conf->global->PRINTIPP_URI_DEFAULT)) { - dol_syslog("Will use default printer conf->global->PRINTIPP_URI_DEFAULT = ".$conf->global->PRINTIPP_URI_DEFAULT); - $ipp->setPrinterURI($conf->global->PRINTIPP_URI_DEFAULT); + dol_syslog("Will use default printer conf->global->PRINTIPP_URI_DEFAULT = ".getDolGlobalString('PRINTIPP_URI_DEFAULT')); + $ipp->setPrinterURI(getDolGlobalString('PRINTIPP_URI_DEFAULT')); } else { $this->errors[] = 'NoDefaultPrinterDefined'; $error++; @@ -233,7 +233,7 @@ class printing_printipp extends PrintingDriver if ($conf->global->PRINTIPP_URI_DEFAULT == $value) { $html .= img_picto($langs->trans("Default"), 'on'); } else { - $html .= ''.img_picto($langs->trans("Disabled"), 'off').''; + $html .= ''.img_picto($langs->trans("Disabled"), 'off').''; } $html .= ''; $html .= ''."\n"; diff --git a/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php b/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php index 05eef305c37..d702299769e 100644 --- a/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php +++ b/htdocs/core/modules/product/doc/doc_generic_product_odt.modules.php @@ -118,15 +118,10 @@ class doc_generic_product_odt extends ModelePDFProduct $form = new Form($this->db); $texte = $this->description.".
    \n"; - $texte .= '
    '; + $texte .= ''; $texte .= ''; $texte .= ''; $texte .= ''; - if ($conf->global->MAIN_PROPAL_CHOOSE_ODT_DOCUMENT > 0) { - $texte .= ''; - $texte .= ''; - $texte .= ''; - } $texte .= '
    '; - print '   '; + print '   '; print $tab[$x]['title']; print ''; print '  (mainmenu='.$tab[$x]['mainmenu'].' leftmenu='.$tab[$x]['leftmenu'].' - fk_mainmenu='.$tab[$x]['fk_mainmenu'].' fk_leftmenu='.$tab[$x]['fk_leftmenu'].')'; diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index 29f208e5254..84b0ada3487 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -339,7 +339,7 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) $thumbsbyrow = 6; print '
    '; - print ''; + print '
    '; // Title if ($foruserprofile) { @@ -400,7 +400,7 @@ function showSkins($fuser, $edit = 0, $foruserprofile = false) if (!file_exists($file)) { $url = DOL_URL_ROOT.'/public/theme/common/nophoto.png'; } - print ''; + print ''; if ($subdir == $conf->global->MAIN_THEME) { $title = $langs->trans("ThemeCurrentlyActive"); } else { diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 89fd777cd20..8dd4e625d9d 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -528,8 +528,10 @@ function includeContainer($containerref) } /** - * Return HTML content to add structured data for an article, news or Blog Post. - * Use the json-ld format. + * Return HTML content to add structured data for an article, news or Blog Post. Use the json-ld format. + * Example: + * + * 'Name', 'os'=>'Windows', 'price'=>10)); ?> * * @param string $type 'blogpost', 'product', 'software', 'organization', 'qa', ... * @param array $data Array of data parameters for structured data @@ -734,6 +736,81 @@ function getStructuredData($type, $data = array()) return $ret; } +/** + * Return HTML content to add as header card for an article, news or Blog Post or home page. + * + * @param array $params Array of parameters + * @return string HTML content + */ +function getSocialNetworkHeaderCards($params = null) +{ + global $conf, $db, $hookmanager, $langs, $mysoc, $user, $website, $websitepage, $weblangs; // Very important. Required to have var available when running inluded containers. + + $out = ''; + + if ($website->virtualhost) { + $pageurl = $websitepage->pageurl; + $title = $websitepage->title; + $image = $websitepage->image; + $companyname = $mysoc->name; + $description = $websitepage->description; + + $pageurl = str_replace('__WEBSITE_KEY__', $website->ref, $pageurl); + $title = str_replace('__WEBSITE_KEY__', $website->ref, $title); + $image = '/medias'.(preg_match('/^\//', $image) ? '' : '/').str_replace('__WEBSITE_KEY__', $website->ref, $image); + $companyname = str_replace('__WEBSITE_KEY__', $website->ref, $companyname); + $description = str_replace('__WEBSITE_KEY__', $website->ref, $description); + + $shortlangcode = ''; + if ($websitepage->lang) { + $shortlangcode = substr($websitepage->lang, 0, 2); // en_US or en-US -> en + } + if (empty($shortlangcode)) { + $shortlangcode = substr($website->lang, 0, 2); // en_US or en-US -> en + } + + $fullurl = $website->virtualhost.'/'.$websitepage->pageurl.'.php'; + $canonicalurl = $website->virtualhost.(($websitepage->id == $website->fk_default_home) ? '/' : (($shortlangcode != substr($website->lang, 0, 2) ? '/'.$shortlangcode : '').'/'.$websitepage->pageurl.'.php')); + $hashtags = trim(join(' #', array_map('trim', explode(',', $websitepage->keywords)))); + + // Open Graph + $out .= ''."\n"; // TODO If blogpost, use type article + $out .= ''."\n"; + if ($websitepage->image) { + $out .= ''."\n"; + } + $out .= ''."\n"; + + // Twitter + $out .= ''."\n"; + if (!empty($params) && !empty($params['twitter_account'])) { + $out .= ''."\n"; + $out .= ''."\n"; + } + $out .= ''."\n"; + if ($websitepage->description) { + $out .= ''."\n"; + } + if ($websitepage->image) { + $out .= ''."\n"; + } + //$out .= ''; + /* + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + $out .= ''; + */ + } + + return $out; +} + /** * Return HTML content to add structured data for an article, news or Blog Post. * @@ -866,11 +943,11 @@ function getPagesFromSearchCriterias($type, $algo, $searchstring, $max = 25, $so $sql .= " AND ("; $searchalgo = ''; if (preg_match('/meta/', $algo)) { - $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.title LIKE '%".$db->escape($searchstring)."%' OR wp.description LIKE '%".$db->escape($searchstring)."%'"; - $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.keywords LIKE '".$db->escape($searchstring).",%' OR wp.keywords LIKE '% ".$db->escape($searchstring)."%'"; // TODO Use a better way to scan keywords + $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.title LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%' OR wp.description LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%'"; + $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.keywords LIKE '".$db->escapeunderscore($db->escape($searchstring)).",%' OR wp.keywords LIKE '% ".$db->escapeunderscore($db->escape($searchstring))."%'"; // TODO Use a better way to scan keywords } if (preg_match('/content/', $algo)) { - $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.content LIKE '%".$db->escape($searchstring)."%'"; + $searchalgo .= ($searchalgo ? ' OR ' : '')."wp.content LIKE '%".$db->escapeunderscore($db->escape($searchstring))."%'"; } $sql .= $searchalgo; if (is_array($otherfilters) && !empty($otherfilters['category'])) { @@ -879,6 +956,7 @@ function getPagesFromSearchCriterias($type, $algo, $searchstring, $max = 25, $so $sql .= ")"; $sql .= $db->order($sortfield, $sortorder); $sql .= $db->plimit($max); + //print $sql; $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/core/login/functions_ldap.php b/htdocs/core/login/functions_ldap.php index 6b11474995b..2d55ca2815b 100644 --- a/htdocs/core/login/functions_ldap.php +++ b/htdocs/core/login/functions_ldap.php @@ -120,7 +120,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) if ($ldapdebug) { print "DEBUG: User ".$usertotest." must change password
    \n"; } - $ldap->close(); + $ldap->unbind(); sleep(1); $langs->load('ldap'); $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("YouMustChangePassNextLogon", $usertotest, $ldap->domainFQDN); @@ -131,7 +131,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) print "DEBUG: ".$ldap->error."
    \n"; } } - $ldap->close(); + $ldap->unbind(); } // Forge LDAP user and password to test with them @@ -166,14 +166,14 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) $now = dol_now(); if ($tmpuser->datestartvalidity && $db->jdate($tmpuser->datestartvalidity) >= $now) { - $ldap->close(); + $ldap->unbind(); // Load translation files required by the page $langs->loadLangs(array('main', 'errors')); $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorLoginDateValidity"); return '--bad-login-validity--'; } if ($tmpuser->dateendvalidity && $db->jdate($tmpuser->dateendvalidity) <= dol_get_first_hour($now)) { - $ldap->close(); + $ldap->unbind(); // Load translation files required by the page $langs->loadLangs(array('main', 'errors')); $_SESSION["dol_loginmesg"] = $langs->transnoentitiesnoconv("ErrorLoginDateValidity"); @@ -271,7 +271,7 @@ function check_user_password_ldap($usertotest, $passwordtotest, $entitytotest) $_SESSION["dol_loginmesg"] = ($ldap->error ? $ldap->error : $langs->transnoentitiesnoconv("ErrorBadLoginPassword")); } - $ldap->close(); + $ldap->unbind(); } return $login; diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index b191e24b117..6504cfa27a6 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -546,7 +546,7 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t print ''."\n"; $lastlevel0 = 'enabled'; } elseif ($showmenu) { // Not enabled but visible (so greyed) - print ''."\n"; + print ''."\n"; $lastlevel0 = 'greyed'; } else { $lastlevel0 = 'hidden'; @@ -582,7 +582,7 @@ function print_left_auguria_menu($db, $menu_array_before, $menu_array_after, &$t } print ''."\n"; } elseif ($showmenu && $lastlevel0 == 'enabled') { // Not enabled but visible (so greyed), except if parent was not enabled. - print ''."\n"; + print ''."\n"; } } diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php index 77725be2ae7..ebb5edc1c3b 100644 --- a/htdocs/core/menus/standard/auguria_menu.php +++ b/htdocs/core/menus/standard/auguria_menu.php @@ -309,7 +309,7 @@ class MenuManager print ''; } if ($val['enabled'] == 2) { - print ''.$val['titre'].''; + print ''.$val['titre'].''; } print ''; print ''."\n"; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index d960d4d52c7..32dc909f2e2 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -382,12 +382,18 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = 'submenus' => array(), ); - // Tickets and knwoledge base + // Tickets and knowledge base $tmpentry = array( - 'enabled'=>(!empty($conf->ticket->enabled) || !empty($conf->knwoledgemanagement->enabled)), - 'perms'=>(!empty($user->rights->ticket->read) || !empty($user->rights->knwoledgemanagement->read)), - 'module'=>'ticket|knwoledgemanagement' + 'enabled'=>(!empty($conf->ticket->enabled) || !empty($conf->knowledgemanagement->enabled)), + 'perms'=>(!empty($user->rights->ticket->read) || !empty($user->rights->knowledgemanagement->knowledgerecord->read)), + 'module'=>'ticket|knowledgemanagement' ); + $link = ''; + if (!empty($conf->ticket->enabled)) { + $link = '/ticket/index.php?mainmenu=ticket&leftmenu='; + } else { + $link = '/knowledgemanagement/knowledgerecord_list.php?mainmenu=ticket&leftmenu='; + } $menu_arr[] = array( 'name' => 'Ticket', 'link' => '/ticket/index.php?mainmenu=ticket&leftmenu=', @@ -1844,6 +1850,29 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM $newmenu->add("/projet/activity/perweek.php?leftmenu=tasks".($search_project_user ? '&search_project_user='.$search_project_user : ''), $langs->trans("NewTimeSpent"), 0, $user->rights->projet->lire, '', $mainmenu, 'timespent', 0, '', '', '', img_picto('', 'timespent', 'class="pictofixedwidth"')); } } + + if (!empty($conf->hrm->enabled)) { + // Skills + $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("skill"), 0, $user->rights->hrm->all->read, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'shapes', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/skill_card.php?mainmenu=hrm&leftmenu=hrm&action=create", $langs->trans("NewSkill"), 1, $user->rights->hrm->all->write); + $newmenu->add("/hrm/skill_list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("List"), 1, $user->rights->hrm->all->read); + + // Job + $newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("Job"), 0, $user->rights->hrm->all->read, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'technic', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/job_card.php?mainmenu=hrm&leftmenu=hrm&action=create", $langs->transnoentities("NewObject", $langs->trans("Job")), 1, $user->rights->hrm->all->write); + $newmenu->add("/hrm/job_list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("List"), 1, $user->rights->hrm->all->read); + + // Position + $newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("Position"), 0, $user->rights->hrm->all->read, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'user-cog', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/position.php?mainmenu=hrm&leftmenu=hrm&action=create", $langs->transnoentities("NewObject", $langs->trans("Position")), 1, $user->rights->hrm->all->write); + $newmenu->add("/hrm/position_list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("List"), 1, $user->rights->hrm->all->read); + + // Evaluation + $newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("Eval"), 0, $user->rights->hrm->evaluation->read, '', $mainmenu, 'hrm', 0, '', '', '', img_picto('', 'user', 'class="pictofixedwidth"')); + $newmenu->add("/hrm/evaluation_card.php?mainmenu=hrm&leftmenu=hrm&action=create", $langs->trans("NewEval"), 1, $user->rights->hrm->evaluation->write); + $newmenu->add("/hrm/evaluation_list.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("List"), 1, $user->rights->hrm->evaluation->read); + $newmenu->add("/hrm/compare.php?mainmenu=hrm&leftmenu=hrm", $langs->trans("Compare"), 1, $user->rights->hrm->compare->read); + } } @@ -2075,7 +2104,7 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM print ''."\n"; $lastlevel0 = 'enabled'; } elseif ($showmenu) { // Not enabled but visible (so greyed) - print ''."\n"; + print ''."\n"; $lastlevel0 = 'greyed'; } else { $lastlevel0 = 'hidden'; @@ -2092,8 +2121,10 @@ function print_left_eldy_menu($db, $menu_array_before, $menu_array_after, &$tabM $cssmenu = ' menu_contenu'.dol_string_nospecial(preg_replace('/\.php.*$/', '', $menu_array[$i]['url'])); } - if ($menu_array[$i]['enabled'] && $lastlevel0 == 'enabled') { // Enabled so visible, except if parent was not enabled. - print '
    '; + + $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Evaluation"), $langs->transnoentities("Evaluation")); + $tooltip .= $langs->trans("GenericMaskCodes2"); + $tooltip .= $langs->trans("GenericMaskCodes3"); + $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("Evaluation"), $langs->transnoentities("Evaluation")); + $tooltip .= $langs->trans("GenericMaskCodes5"); + + // Parametrage du prefix + $texte .= ''; + $texte .= ''; + + $texte .= ''; + + $texte .= ''; + + $texte .= '
    '.$langs->trans("Mask").':'.$form->textwithpicto('', $tooltip, 1, 1).' 
    '; + $texte .= ''; + + return $texte; + } + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $conf, $db, $langs, $mysoc; + + $object = new Evaluation($db); + $object->initAsSpecimen(); + + /*$old_code_client = $mysoc->code_client; + $old_code_type = $mysoc->typent_code; + $mysoc->code_client = 'CCCCCCCCCC'; + $mysoc->typent_code = 'TTTTTTTTTT';*/ + + $numExample = $this->getNextValue($object); + + /*$mysoc->code_client = $old_code_client; + $mysoc->typent_code = $old_code_type;*/ + + if (!$numExample) { + $numExample = $langs->trans('NotConfigured'); + } + return $numExample; + } + + /** + * Return next free value + * + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($object) + { + global $db, $conf; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + + // We get cursor rule + $mask = $conf->global->HRM_EVALUATION_ADVANCED_MASK; + + if (!$mask) { + $this->error = 'NotConfigured'; + return 0; + } + + $date = $object->date; + + $numFinal = get_next_value($db, $mask, 'hrm_evaluation', 'ref', '', null, $date); + + return $numFinal; + } +} diff --git a/htdocs/core/modules/hrm/mod_evaluation_standard.php b/htdocs/core/modules/hrm/mod_evaluation_standard.php new file mode 100644 index 00000000000..4c5bb083870 --- /dev/null +++ b/htdocs/core/modules/hrm/mod_evaluation_standard.php @@ -0,0 +1,161 @@ + + * Copyright (C) 2005-2009 Regis Houssin + * + * 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 . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/hrm/mod_evaluation_standard.php + * \ingroup hrm + * \brief File of class to manage Evaluation numbering rules standard + */ +dol_include_once('/core/modules/hrm/modules_evaluation.php'); + + +/** + * Class to manage customer order numbering rules standard + */ +class mod_evaluation_standard extends ModeleNumRefEvaluation +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + public $prefix = 'EVAL'; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string name + */ + public $name = 'standard'; + + + /** + * Return description of numbering module + * + * @return string Text with description + */ + public function info() + { + global $langs; + return $langs->trans("SimpleNumRefModelDesc", $this->prefix); + } + + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + return $this->prefix."0501-0001"; + } + + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @param Object $object Object we need next value for + * @return boolean false if conflict, true if ok + */ + public function canBeActivated($object) + { + global $conf, $langs, $db; + + $coyymm = ''; $max = ''; + + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."hrm_evaluation"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + if ($object->ismultientitymanaged == 1) { + $sql .= " AND entity = ".$conf->entity; + } elseif ($object->ismultientitymanaged == 2) { + // TODO + } + + $resql = $db->query($sql); + if ($resql) { + $row = $db->fetch_row($resql); + if ($row) { + $coyymm = substr($row[0], 0, 6); $max = $row[0]; + } + } + if ($coyymm && !preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm)) { + $langs->load("errors"); + $this->error = $langs->trans('ErrorNumRefModel', $max); + return false; + } + + return true; + } + + /** + * Return next free value + * + * @param Object $object Object we need next value for + * @return string Value if KO, <0 if KO + */ + public function getNextValue($object) + { + global $db, $conf; + + // first we get the max value + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."hrm_evaluation"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + if ($object->ismultientitymanaged == 1) { + $sql .= " AND entity = ".$conf->entity; + } elseif ($object->ismultientitymanaged == 2) { + // TODO + } + + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj) { + $max = intval($obj->max); + } else { + $max = 0; + } + } else { + dol_syslog("mod_evaluation_standard::getNextValue", LOG_DEBUG); + return -1; + } + + //$date=time(); + $date = $object->date_creation; + $yymm = strftime("%y%m", $date); + + if ($max >= (pow(10, 4) - 1)) { + $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is + } else { + $num = sprintf("%04s", $max + 1); + } + + dol_syslog("mod_evaluation_standard::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + } +} diff --git a/htdocs/core/modules/hrm/modules_evaluation.php b/htdocs/core/modules/hrm/modules_evaluation.php new file mode 100644 index 00000000000..36fc7e26d81 --- /dev/null +++ b/htdocs/core/modules/hrm/modules_evaluation.php @@ -0,0 +1,158 @@ + + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2012 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 . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/hrm/modules_evaluation.php + * \ingroup hrm + * \brief File that contains parent class for evaluations document models and parent class for evaluations numbering models + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commondocgenerator.class.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; // required for use by classes that inherit + + +/** + * Parent class for documents models + */ +abstract class ModelePDFEvaluation extends CommonDocGenerator +{ + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return list of active generation modules + * + * @param DoliDB $db Database handler + * @param integer $maxfilenamelength Max length of value to show + * @return array List of templates + */ + public static function liste_modeles($db, $maxfilenamelength = 0) + { + // phpcs:enable + global $conf; + + $type = 'evaluation'; + $list = array(); + + include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $list = getListOfModels($db, $type, $maxfilenamelength); + + return $list; + } +} + + + +/** + * Parent class to manage numbering of Evaluation + */ +abstract class ModeleNumRefEvaluation +{ + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * Return if a module can be used or not + * + * @return boolean true if module can be used + */ + public function isEnabled() + { + return true; + } + + /** + * Returns the default description of the numbering template + * + * @return string Texte descripif + */ + public function info() + { + global $langs; + $langs->load("hrm"); + return $langs->trans("NoDescription"); + } + + /** + * Returns an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $langs; + $langs->load("hrm"); + return $langs->trans("NoExample"); + } + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @param Object $object Object we need next value for + * @return boolean false if conflict, true if ok + */ + public function canBeActivated($object) + { + return true; + } + + /** + * Returns next assigned value + * + * @param Object $object Object we need next value for + * @return string Valeur + */ + public function getNextValue($object) + { + global $langs; + return $langs->trans("NotAvailable"); + } + + /** + * Returns version of numbering module + * + * @return string Valeur + */ + public function getVersion() + { + global $langs; + $langs->load("admin"); + + if ($this->version == 'development') { + return $langs->trans("VersionDevelopment"); + } + if ($this->version == 'experimental') { + return $langs->trans("VersionExperimental"); + } + if ($this->version == 'dolibarr') { + return DOL_VERSION; + } + if ($this->version) { + return $this->version; + } + return $langs->trans("NotAvailable"); + } +} diff --git a/htdocs/core/modules/import/import_csv.modules.php b/htdocs/core/modules/import/import_csv.modules.php index 184c99a95e7..9eeb76cc3cf 100644 --- a/htdocs/core/modules/import/import_csv.modules.php +++ b/htdocs/core/modules/import/import_csv.modules.php @@ -586,18 +586,22 @@ class ImportCsv extends ModeleImports $arrayrecord[($key - 1)]['type'] = -1; // If we get empty value, we will use "null" } } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getrefifauto') { - $defaultref = ''; - // TODO provide the $modTask (module of generation of ref) as parameter of import_insert function - $obj = empty($conf->global->PROJECT_TASK_ADDON) ? 'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON; - if (!empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.".php")) { - require_once DOL_DOCUMENT_ROOT."/core/modules/project/task/".$conf->global->PROJECT_TASK_ADDON.'.php'; - $modTask = new $obj; - $defaultref = $modTask->getNextValue(null, null); - } - if (is_numeric($defaultref) && $defaultref <= 0) { + if (strtolower($newval) == 'auto') { $defaultref = ''; + + $classModForNumber = $objimport->array_import_convertvalue[0][$val]['class']; + $pathModForNumber = $objimport->array_import_convertvalue[0][$val]['path']; + + if (!empty($classModForNumber) && !empty($pathModForNumber) && is_readable(DOL_DOCUMENT_ROOT.$pathModForNumber)) { + require_once DOL_DOCUMENT_ROOT.$pathModForNumber; + $modForNumber = new $classModForNumber; + $defaultref = $modForNumber->getNextValue(null, null); + } + if (is_numeric($defaultref) && $defaultref <= 0) { + $defaultref = ''; + } + $newval = $defaultref; } - $newval = $defaultref; } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'compute') { $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']); $class = $objimport->array_import_convertvalue[0][$val]['class']; diff --git a/htdocs/core/modules/import/import_xlsx.modules.php b/htdocs/core/modules/import/import_xlsx.modules.php index aaca0d3bd77..0171eb83ea9 100644 --- a/htdocs/core/modules/import/import_xlsx.modules.php +++ b/htdocs/core/modules/import/import_xlsx.modules.php @@ -627,18 +627,22 @@ class ImportXlsx extends ModeleImports $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null" } } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getrefifauto') { - $defaultref = ''; - // TODO provide the $modTask (module of generation of ref) as parameter of import_insert function - $obj = empty($conf->global->PROJECT_TASK_ADDON) ? 'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON; - if (!empty($conf->global->PROJECT_TASK_ADDON) && is_readable(DOL_DOCUMENT_ROOT . "/core/modules/project/task/" . $conf->global->PROJECT_TASK_ADDON . ".php")) { - require_once DOL_DOCUMENT_ROOT . "/core/modules/project/task/" . $conf->global->PROJECT_TASK_ADDON . '.php'; - $modTask = new $obj; - $defaultref = $modTask->getNextValue(null, null); - } - if (is_numeric($defaultref) && $defaultref <= 0) { + if (strtolower($newval) == 'auto') { $defaultref = ''; + + $classModForNumber = $objimport->array_import_convertvalue[0][$val]['class']; + $pathModForNumber = $objimport->array_import_convertvalue[0][$val]['path']; + + if (!empty($classModForNumber) && !empty($pathModForNumber) && is_readable(DOL_DOCUMENT_ROOT.$pathModForNumber)) { + require_once DOL_DOCUMENT_ROOT.$pathModForNumber; + $modForNumber = new $classModForNumber; + $defaultref = $modForNumber->getNextValue(null, null); + } + if (is_numeric($defaultref) && $defaultref <= 0) { + $defaultref = ''; + } + $newval = $defaultref; } - $newval = $defaultref; } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'compute') { $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']); $class = $objimport->array_import_convertvalue[0][$val]['class']; diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 2d41dfd9725..ef43f05b86a 100644 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -79,8 +79,8 @@ class mailing_contacts1 extends MailingTargets $statssql[0] .= " count(distinct(c.email)) as nb"; $statssql[0] .= " FROM ".MAIN_DB_PREFIX."socpeople as c"; $statssql[0] .= " WHERE c.entity IN (".getEntity('socpeople').")"; - $statssql[0] .= " AND c.email != ''"; // Note that null != '' is false - $statssql[0] .= " AND c.no_email = 0"; + $statssql[0] .= " AND c.email <> ''"; // Note that null != '' is false + $statssql[0] .= " AND (SELECT count(*) FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = c.email) = 0"; $statssql[0] .= " AND c.statut = 1"; return $statssql; @@ -103,8 +103,7 @@ class mailing_contacts1 extends MailingTargets $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc"; $sql .= " WHERE c.entity IN (".getEntity('socpeople').")"; - $sql .= " AND c.email != ''"; // Note that null != '' is false - $sql .= " AND c.no_email = 0"; + $sql .= " AND c.email <> ''"; // Note that null != '' is false $sql .= " AND (SELECT count(*) FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = c.email) = 0"; // exclude unsubscribed users $sql .= " AND c.statut = 1"; @@ -132,10 +131,9 @@ class mailing_contacts1 extends MailingTargets $sql = "SELECT sp.poste, count(distinct(sp.email)) AS nb"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; - /*$sql.= " AND sp.email != ''"; // Note that null != '' is false - $sql.= " AND sp.no_email = 0"; - $sql.= " AND sp.statut = 1";*/ - $sql .= " AND (sp.poste IS NOT NULL AND sp.poste != '')"; + $sql .= " AND sp.email <> ''"; // Note that null != '' is false + $sql .= " AND sp.statut = 1"; + $sql .= " AND (sp.poste IS NOT NULL AND sp.poste <> '')"; $sql .= " GROUP BY sp.poste"; $sql .= " ORDER BY sp.poste"; $resql = $this->db->query($sql); @@ -169,10 +167,9 @@ class mailing_contacts1 extends MailingTargets $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; $sql .= " ".MAIN_DB_PREFIX."categorie as c,"; $sql .= " ".MAIN_DB_PREFIX."categorie_contact as cs"; - $sql .= " WHERE sp.statut = 1"; // Note that null != '' is false - //$sql.= " AND sp.no_email = 0"; - //$sql.= " AND sp.email != ''"; - //$sql.= " AND sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " AND sp.email <> ''"; // Note that null != '' is false + $sql .= " AND sp.statut = 1"; $sql .= " AND cs.fk_categorie = c.rowid"; $sql .= " AND cs.fk_socpeople = sp.rowid"; $sql .= " GROUP BY c.label"; @@ -244,10 +241,9 @@ class mailing_contacts1 extends MailingTargets $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; $sql .= " ".MAIN_DB_PREFIX."categorie as c,"; $sql .= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $sql .= " WHERE sp.statut = 1"; // Note that null != '' is false - //$sql.= " AND sp.no_email = 0"; - //$sql.= " AND sp.email != ''"; - //$sql.= " AND sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " AND sp.email <> ''"; // Note that null != '' is false + $sql .= " AND sp.statut = 1"; $sql .= " AND cs.fk_categorie = c.rowid"; $sql .= " AND cs.fk_soc = sp.fk_soc"; $sql .= " GROUP BY c.label"; @@ -282,10 +278,9 @@ class mailing_contacts1 extends MailingTargets $sql .= " ".MAIN_DB_PREFIX."socpeople as sp,"; $sql .= " ".MAIN_DB_PREFIX."categorie as c,"; $sql .= " ".MAIN_DB_PREFIX."categorie_fournisseur as cs"; - $sql .= " WHERE sp.statut = 1"; // Note that null != '' is false - //$sql.= " AND sp.no_email = 0"; - //$sql.= " AND sp.email != ''"; - //$sql.= " AND sp.entity IN (".getEntity('socpeople').")"; + $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; + $sql .= " AND sp.email <> ''"; // Note that null != '' is false + $sql .= " AND sp.statut = 1"; $sql .= " AND cs.fk_categorie = c.rowid"; $sql .= " AND cs.fk_soc = sp.fk_soc"; $sql .= " GROUP BY c.label"; @@ -391,7 +386,6 @@ class mailing_contacts1 extends MailingTargets } $sql .= " WHERE sp.entity IN (".getEntity('socpeople').")"; $sql .= " AND sp.email <> ''"; - $sql .= " AND sp.no_email = 0"; $sql .= " AND (SELECT count(*) FROM ".MAIN_DB_PREFIX."mailing_unsubscribe WHERE email = sp.email) = 0"; // Exclude unsubscribed email adresses $sql .= " AND sp.statut = 1"; diff --git a/htdocs/core/modules/mailings/modules_mailings.php b/htdocs/core/modules/mailings/modules_mailings.php index afbf1e22481..9df8d44daf1 100644 --- a/htdocs/core/modules/mailings/modules_mailings.php +++ b/htdocs/core/modules/mailings/modules_mailings.php @@ -224,7 +224,7 @@ class MailingTargets // This can't be abstract as it is used for some method $sql = "UPDATE ".MAIN_DB_PREFIX."mailing_cibles"; $sql .= " SET statut=3"; - $sql .= " WHERE fk_mailing =" .((int) $mailing_id)." AND email IN (SELECT mu.email FROM ".MAIN_DB_PREFIX."mailing_unsubscribe AS mu WHERE mu.entity IN ('".getEntity('mailing')."'))"; + $sql .= " WHERE fk_mailing = ".((int) $mailing_id)." AND email IN (SELECT mu.email FROM ".MAIN_DB_PREFIX."mailing_unsubscribe AS mu WHERE mu.entity IN ('".getEntity('mailing')."'))"; dol_syslog(__METHOD__.":mailing update status to display emails that do not want to be contacted anymore", LOG_DEBUG); $result = $this->db->query($sql); diff --git a/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php b/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php index 7b2af1e0032..593986d4b7d 100644 --- a/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php +++ b/htdocs/core/modules/member/doc/doc_generic_member_odt.class.php @@ -195,9 +195,10 @@ class doc_generic_member_odt extends ModelePDFMember * @param string $srctemplatepath Full path of source filename for generator using a template file * @param string $mode Tell if doc module is called for 'member', ... * @param int $nooutput 1=Generate only file on disk and do not return it on response + * @param string $filename Name of output file (without extension) * @return int 1 if OK, <=0 if KO */ - public function write_file($object, $outputlangs, $srctemplatepath, $mode = 'member', $nooutput = 0) + public function write_file($object, $outputlangs, $srctemplatepath, $mode = 'member', $nooutput = 0, $filename = 'tmp_cards') { // phpcs:enable global $user, $langs, $conf, $mysoc, $hookmanager; @@ -295,11 +296,14 @@ class doc_generic_member_odt extends ModelePDFMember // Recipient name if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/core/modules/member/doc/pdf_standard.class.php b/htdocs/core/modules/member/doc/pdf_standard.class.php index 1d1a892cc56..15f3260c4d2 100644 --- a/htdocs/core/modules/member/doc/pdf_standard.class.php +++ b/htdocs/core/modules/member/doc/pdf_standard.class.php @@ -243,9 +243,10 @@ class pdf_standard extends CommonStickerGenerator * @param string $srctemplatepath Full path of source filename for generator using a template file. Example: '5161', 'AVERYC32010', 'CARD', ... * @param string $mode Tell if doc module is called for 'member', ... * @param int $nooutput 1=Generate only file on disk and do not return it on response + * @param string $filename Name of output file (without extension) * @return int 1=OK, 0=KO */ - public function write_file($object, $outputlangs, $srctemplatepath, $mode = 'member', $nooutput = 0) + public function write_file($object, $outputlangs, $srctemplatepath, $mode = 'member', $nooutput = 0, $filename = 'tmp_cards') { // phpcs:enable global $user, $conf, $langs, $mysoc, $_Avery_Labels; @@ -282,7 +283,7 @@ class pdf_standard extends CommonStickerGenerator '__MONTH__'=>$month, '__DAY__'=>$day, '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT, - '__SERVER__'=>"http://".$_SERVER["SERVER_NAME"]."/" + '__SERVER__'=>"https://".$_SERVER["SERVER_NAME"]."/" ); complete_substitutions_array($substitutionarray, $langs); @@ -320,7 +321,10 @@ class pdf_standard extends CommonStickerGenerator dol_print_error('', 'ErrorBadTypeForCard'.$this->code); exit; } + $this->type = 'pdf'; + $filename .= '.pdf'; + // standard format or custom if ($this->Tformat['paper-size'] != 'custom') { $this->format = $this->Tformat['paper-size']; @@ -349,7 +353,7 @@ class pdf_standard extends CommonStickerGenerator return -1; } - $filename = 'tmp_cards.pdf'; + if (is_object($object)) { $outputdir = $conf->adherent->dir_output; $dir = $outputdir."/".get_exdir(0, 0, 0, 0, $object, 'member'); diff --git a/htdocs/core/modules/member/mod_member_simple.php b/htdocs/core/modules/member/mod_member_simple.php new file mode 100644 index 00000000000..50eccd0f244 --- /dev/null +++ b/htdocs/core/modules/member/mod_member_simple.php @@ -0,0 +1,183 @@ + + * + * 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 . + * or see https://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/member/mod_member_simple.php + * \ingroup member + * \brief File with class to manage the numbering module Simple for member references + */ + +require_once DOL_DOCUMENT_ROOT.'/core/modules/member/modules_member.class.php'; + + +/** + * Class to manage the numbering module Simple for member references + */ +class mod_member_simple extends ModeleNumRefMembers +{ + /** + * Dolibarr version of the loaded document + * @var string + */ + public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' + + public $prefix = 'MEM'; + + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var string Nom du modele + * @deprecated + * @see $name + */ + public $nom = 'Simple'; + + /** + * @var string model name + */ + public $name = 'Simple'; + + + /** + * Return description of numbering module + * + * @return string Text with description + */ + public function info() + { + global $langs; + return $langs->trans("SimpleNumRefModelDesc", $this->prefix); + } + + + /** + * Return an example of numbering module values + * + * @return string Example + */ + public function getExample() + { + return $this->prefix."0501-0001"; + } + + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @return boolean false if conflict, true if ok + */ + public function canBeActivated() + { + global $conf, $langs, $db; + + $coyymm = ''; + $max = ''; + + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."adherent"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + $sql .= " AND entity = ".$conf->entity; + $resql = $db->query($sql); + if ($resql) { + $row = $db->fetch_row($resql); + if ($row) { + $coyymm = substr($row[0], 0, 6); + $max = $row[0]; + } + } + if (!$coyymm || preg_match('/'.$this->prefix.'[0-9][0-9][0-9][0-9]/i', $coyymm)) { + return true; + } else { + $langs->load("errors"); + $this->error = $langs->trans('ErrorNumRefModel', $max); + return false; + } + } + + + /** + * Return next value + * + * @param Societe $objsoc Object third party + * @param Object $object Object we need next value for + * @return string Value if OK, 0 if KO + */ + public function getNextValue($objsoc, $object) + { + global $db, $conf; + + /* + // First, we get the max value + $posindice = strlen($this->prefix) + 6; + $sql = "SELECT MAX(CAST(SUBSTRING(ref FROM ".$posindice.") AS SIGNED)) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."adherent"; + $sql .= " WHERE ref LIKE '".$db->escape($this->prefix)."____-%'"; + $sql .= " AND entity = ".$conf->entity; + + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj) { + $max = intval($obj->max); + } else { + $max = 0; + } + } else { + dol_syslog("mod_member_simple::getNextValue", LOG_DEBUG); + return -1; + } + + $date = empty($object->date_c) ? dol_now() : $object->date_c; + + //$yymm = strftime("%y%m",time()); + $yymm = strftime("%y%m", $date); + + if ($max >= (pow(10, 4) - 1)) { + $num = $max + 1; // If counter > 9999, we do not format on 4 chars, we take number as it is + } else { + $num = sprintf("%04s", $max + 1); + } + + dol_syslog("mod_member_simple::getNextValue return ".$this->prefix.$yymm."-".$num); + return $this->prefix.$yymm."-".$num; + */ + + // For the moment, the ref of a member is the rowid + $sql = "SELECT MAX(rowid) as max"; + $sql .= " FROM ".MAIN_DB_PREFIX."adherent"; + + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj) { + $max = intval($obj->max); + } else { + $max = 0; + } + } else { + dol_syslog("mod_member_simple::getNextValue", LOG_DEBUG); + return -1; + } + return ($max + 1); + } +} diff --git a/htdocs/core/modules/member/modules_cards.php b/htdocs/core/modules/member/modules_cards.php index 937e8a06870..b37b9144d3e 100644 --- a/htdocs/core/modules/member/modules_cards.php +++ b/htdocs/core/modules/member/modules_cards.php @@ -74,9 +74,10 @@ class ModelePDFCards * @param Translate $outputlangs Object langs to use for translation * @param string $outputdir Output directory * @param string $template pdf generenate document class to use default 'standard' + * @param string $filename Name of output file (without extension) * @return int <0 if KO, >0 if OK */ -function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $outputdir = '', $template = 'standard') +function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $outputdir = '', $template = 'standard', $filename = 'tmp_cards') { // phpcs:enable global $conf, $langs; @@ -125,7 +126,7 @@ function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $o foreach (array('doc', 'pdf') as $prefix) { $file = $prefix."_".$template.".class.php"; - // On verifie l'emplacement du modele + // We check that file of doc generaotr exists $file = dol_buildpath($reldir."core/modules/member/doc/".$file, 0); if (file_exists($file)) { $filefound = 1; @@ -148,7 +149,7 @@ function members_card_pdf_create($db, $arrayofmembers, $modele, $outputlangs, $o // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. $sav_charset_output = $outputlangs->charset_output; - if ($obj->write_file($arrayofmembers, $outputlangs, $srctemplatepath) > 0) { + if ($obj->write_file($arrayofmembers, $outputlangs, $srctemplatepath, 'member', 0, $filename) > 0) { $outputlangs->charset_output = $sav_charset_output; return 1; } else { diff --git a/htdocs/core/modules/member/modules_member.class.php b/htdocs/core/modules/member/modules_member.class.php index 3a1b4edcc1d..cdc37231901 100644 --- a/htdocs/core/modules/member/modules_member.class.php +++ b/htdocs/core/modules/member/modules_member.class.php @@ -60,3 +60,97 @@ abstract class ModelePDFMember extends CommonDocGenerator return $list; } } + + + +/** + * Classe mere des modeles de numerotation des references de members + */ +abstract class ModeleNumRefMembers +{ + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * Return if a module can be used or not + * + * @return boolean true if module can be used + */ + public function isEnabled() + { + return true; + } + + /** + * Renvoi la description par defaut du modele de numerotation + * + * @return string Texte descripif + */ + public function info() + { + global $langs; + $langs->load("members"); + return $langs->trans("NoDescription"); + } + + /** + * Return an example of numbering + * + * @return string Example + */ + public function getExample() + { + global $langs; + $langs->load("members"); + return $langs->trans("NoExample"); + } + + /** + * Checks if the numbers already in the database do not + * cause conflicts that would prevent this numbering working. + * + * @return boolean false if conflict, true if ok + */ + public function canBeActivated() + { + return true; + } + + /** + * Renvoi prochaine valeur attribuee + * + * @param Societe $objsoc Object third party + * @param Object $object Object we need next value for + * @return string Valeur + */ + public function getNextValue($objsoc, $object) + { + global $langs; + return $langs->trans("NotAvailable"); + } + + /** + * Renvoi version du module numerotation + * + * @return string Valeur + */ + public function getVersion() + { + global $langs; + $langs->load("admin"); + + if ($this->version == 'development') { + return $langs->trans("VersionDevelopment"); + } elseif ($this->version == 'experimental') { + return $langs->trans("VersionExperimental"); + } elseif ($this->version == 'dolibarr') { + return DOL_VERSION; + } elseif ($this->version) { + return $this->version; + } else { + return $langs->trans("NotAvailable"); + } + } +} diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php index ff0c67408c5..0d4a85e00ae 100644 --- a/htdocs/core/modules/modAdherent.class.php +++ b/htdocs/core/modules/modAdherent.class.php @@ -286,7 +286,7 @@ class modAdherent extends DolibarrModules $this->export_label[$r] = 'MembersAndSubscriptions'; $this->export_permission[$r] = array(array("adherent", "export")); $this->export_fields_array[$r] = array( - 'a.rowid'=>'Id', 'a.civility'=>"UserTitle", 'a.lastname'=>"Lastname", 'a.firstname'=>"Firstname", 'a.login'=>"Login", 'a.gender'=>"Gender", 'a.morphy'=>'Nature', + 'a.rowid'=>'Id', 'a.civility'=>"UserTitle", 'a.lastname'=>"Lastname", 'a.firstname'=>"Firstname", 'a.login'=>"Login", 'a.gender'=>"Gender", 'a.morphy'=>'MemberNature', 'a.societe'=>'Company', 'a.address'=>"Address", 'a.zip'=>"Zip", 'a.town'=>"Town", 'd.nom'=>"State", 'co.code'=>"CountryCode", 'co.label'=>"Country", 'a.phone'=>"PhonePro", 'a.phone_perso'=>"PhonePerso", 'a.phone_mobile'=>"PhoneMobile", 'a.email'=>"Email", 'a.birth'=>"Birthday", 'a.statut'=>"Status", 'a.photo'=>"Photo", 'a.note_public'=>"NotePublic", 'a.note_private'=>"NotePrivate", 'a.datec'=>'DateCreation', 'a.datevalid'=>'DateValidation', @@ -338,8 +338,9 @@ class modAdherent extends DolibarrModules $this->import_tables_array[$r] = array('a'=>MAIN_DB_PREFIX.'adherent', 'extra'=>MAIN_DB_PREFIX.'adherent_extrafields'); $this->import_tables_creator_array[$r] = array('a'=>'fk_user_author'); // Fields to store import user id $this->import_fields_array[$r] = array( + 'a.ref' => 'Member Ref*', 'a.civility'=>"UserTitle", 'a.lastname'=>"Lastname*", 'a.firstname'=>"Firstname", 'a.gender'=>"Gender", 'a.login'=>"Login*", "a.pass"=>"Password", - "a.fk_adherent_type"=>"MemberType*", 'a.morphy'=>'Nature*', 'a.societe'=>'Company', 'a.address'=>"Address", 'a.zip'=>"Zip", 'a.town'=>"Town", + "a.fk_adherent_type"=>"MemberType*", 'a.morphy'=>'MemberNature*', 'a.societe'=>'Company', 'a.address'=>"Address", 'a.zip'=>"Zip", 'a.town'=>"Town", 'a.state_id'=>'StateId', 'a.country'=>"CountryId", 'a.phone'=>"PhonePro", 'a.phone_perso'=>"PhonePerso", 'a.phone_mobile'=>"PhoneMobile", 'a.email'=>"Email", 'a.birth'=>"Birthday", 'a.statut'=>"Status*", 'a.photo'=>"Photo", 'a.note_public'=>"NotePublic", 'a.note_private'=>"NotePrivate", 'a.datec'=>'DateCreation', 'a.datefin'=>'DateEndSubscription' @@ -348,7 +349,7 @@ class modAdherent extends DolibarrModules $this->import_fields_array[$r]['a.fk_soc'] = "ThirdParty"; } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'adherent' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'adherent' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { @@ -358,7 +359,27 @@ class modAdherent extends DolibarrModules } } // End add extra fields - $this->import_convertvalue_array[$r] = array(); + $this->import_convertvalue_array[$r] = array( + 'a.ref'=>array( + 'rule'=>'getrefifauto', + 'class'=>(empty($conf->global->MEMBER_ADDON) ? 'mod_member_simple' : $conf->global->MEMBER_ADDON), + 'path'=>"/core/modules/member/".(empty($conf->global->MEMBER_ADDON) ? 'mod_member_simple' : $conf->global->MEMBER_ADDON).'.php' + ), + 'a.state_id' => array( + 'rule' => 'fetchidfromcodeid', + 'classfile' => '/core/class/cstate.class.php', + 'class' => 'Cstate', + 'method' => 'fetch', + 'dict' => 'DictionaryStateCode' + ), + 'a.country' => array( + 'rule' => 'fetchidfromcodeid', + 'classfile' => '/core/class/ccountry.class.php', + 'class' => 'Ccountry', + 'method' => 'fetch', + 'dict' => 'DictionaryCountry' + ) + ); if (!empty($conf->societe->enabled)) { $this->import_convertvalue_array[$r]['a.fk_soc'] = array('rule'=>'fetchidfromref', 'classfile'=>'/societe/class/societe.class.php', 'class'=>'Societe', 'method'=>'fetch', 'element'=>'ThirdParty'); } @@ -367,6 +388,7 @@ class modAdherent extends DolibarrModules 'a.civility'=>'code@'.MAIN_DB_PREFIX.'c_civility', 'a.fk_adherent_type'=>'rowid@'.MAIN_DB_PREFIX.'adherent_type', 'a.morphy'=>'(phy|mor)', 'a.statut'=>'^[0|1]', 'a.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 'a.datefin'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$'); $this->import_examplevalues_array[$r] = array( + 'a.ref'=>"auto or MEM2010-1234", 'a.civility'=>"MR", 'a.lastname'=>'Smith', 'a.firstname'=>'John', 'a.gender'=>'man or woman', 'a.login'=>'jsmith', 'a.pass'=>'passofjsmith', 'a.fk_adherent_type'=>'1', 'a.morphy'=>'"mor" or "phy"', 'a.societe'=>'JS company', 'a.address'=>'21 jump street', 'a.zip'=>'55000', 'a.town'=>'New York', 'a.country'=>'1', 'a.email'=>'jsmith@example.com', 'a.birth'=>'1972-10-10', 'a.statut'=>"0 or 1", 'a.note_public'=>"This is a public comment on member", @@ -375,6 +397,7 @@ class modAdherent extends DolibarrModules if (!empty($conf->societe->enabled)) { $this->import_examplevalues_array[$r]['a.fk_soc'] = "rowid or name"; } + $this->import_updatekeys_array[$r] = array('a.ref'=>'Member Ref', 'a.login'=>'Login'); // Cronjobs $arraydate = dol_getdate(dol_now()); diff --git a/htdocs/core/modules/modApi.class.php b/htdocs/core/modules/modApi.class.php index ffd274c7096..254e3f86983 100644 --- a/htdocs/core/modules/modApi.class.php +++ b/htdocs/core/modules/modApi.class.php @@ -134,16 +134,18 @@ class modApi extends DolibarrModules // Permissions $this->rights = array(); // Permission array used by this module + $this->rights_admin_allowed = 1; // Admin is always granted of permission (even when module is disabled) + $r = 0; // Add here list of permission defined by an id, a label, a boolean and two constant strings. // Example: - // $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) - // $this->rights[$r][1] = 'Permision label'; // Permission label - // $this->rights[$r][3] = 0; // Permission by default for new user (0/1) - // $this->rights[$r][4] = 'level1'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) - // $this->rights[$r][5] = 'level2'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) - // $r++; + $this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used) + $this->rights[$r][1] = 'Générer / modifier la clé API des utilisateurs'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'apikey'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $this->rights[$r][5] = 'generate'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $r++; // Main menu entries diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index 776c5c76681..c3b7f256b4b 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -164,8 +164,8 @@ class modCategorie extends DolibarrModules $typeexample .= ($typeexample ? " / " : "")."11=Website page"; } - $this->export_fields_array[$r] = array('cat.rowid'=>"CategId", 'cat.label'=>"Label", 'cat.type'=>"Type", 'cat.description'=>"Description", 'cat.fk_parent'=>"ParentCategory", 'pcat.label'=>"ParentCategoryLabel" ); - $this->export_TypeFields_array[$r] = array('cat.label'=>"Text", 'cat.type'=>"Numeric", 'cat.description'=>"Text", 'cat.fk_parent'=>'List:categorie:label:rowid', 'pcat.label'=>'Text' ); + $this->export_fields_array[$r] = array('cat.rowid'=>"CategId", 'cat.label'=>"Label", 'cat.type'=>"Type", 'cat.description'=>"Description", 'cat.fk_parent'=>"ParentCategory", 'pcat.label'=>"ParentCategoryLabel"); + $this->export_TypeFields_array[$r] = array('cat.label'=>"Text", 'cat.type'=>"Numeric", 'cat.description'=>"Text", 'cat.fk_parent'=>'List:categorie:label:rowid', 'pcat.label'=>'Text'); $this->export_entities_array[$r] = array(); // We define here only fields that use another picto $this->export_help_array[$r] = array('cat.type'=>$typeexample); @@ -460,7 +460,7 @@ class modCategorie extends DolibarrModules ); $this->import_examplevalues_array[$r] = array( - 'ca.label'=>"My Category Label", 'ca.type'=>$typeexample, 'ca.description'=>"My Category description", // $typeexample built above in exports + 'ca.label'=>"My Category Label", 'ca.type'=>$typeexample, 'ca.description'=>"My Category description", // $typeexample built above in exports 'ca.fk_parent' => 'rowid or label' ); $this->import_updatekeys_array[$r] = array('ca.label'=>'Label'); @@ -538,7 +538,7 @@ class modCategorie extends DolibarrModules $this->import_convertvalue_array[$r] = array( 'cs.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'), - 'cs.fk_member'=>array('rule'=>'fetchidfromref','classfile'=>'/adherents/class/adherent.class.php','class'=>'Adherent','method'=>'fetch','element'=>'Member') + 'cs.fk_member'=>array('rule'=>'fetchidfromref', 'classfile'=>'/adherents/class/adherent.class.php', 'class'=>'Adherent', 'method'=>'fetch', 'element'=>'Member') ); $this->import_examplevalues_array[$r] = array('cs.fk_categorie'=>"rowid or label", 'cs.fk_member'=>"rowid or ref"); } @@ -579,7 +579,7 @@ class modCategorie extends DolibarrModules $this->import_convertvalue_array[$r] = array( 'cs.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'), - 'cs.fk_project'=>array('rule'=>'fetchidfromref','classfile'=>'/projet/class/project.class.php','class'=>'Project','method'=>'fetch','element'=>'Project') + 'cs.fk_project'=>array('rule'=>'fetchidfromref', 'classfile'=>'/projet/class/project.class.php', 'class'=>'Project', 'method'=>'fetch', 'element'=>'Project') ); $this->import_examplevalues_array[$r] = array('cp.fk_categorie'=>"rowid or label", 'cp.fk_project'=>"rowid or ref"); } @@ -597,7 +597,7 @@ class modCategorie extends DolibarrModules $this->import_convertvalue_array[$r] = array( 'cu.fk_categorie'=>array('rule'=>'fetchidfromref', 'classfile'=>'/categories/class/categorie.class.php', 'class'=>'Categorie', 'method'=>'fetch', 'element'=>'category'), - 'cu.fk_user'=>array('rule'=>'fetchidfromref','classfile'=>'/user/class/user.class.php','class'=>'User','method'=>'fetch','element'=>'User') + 'cu.fk_user'=>array('rule'=>'fetchidfromref', 'classfile'=>'/user/class/user.class.php', 'class'=>'User', 'method'=>'fetch', 'element'=>'User') ); $this->import_examplevalues_array[$r] = array('cu.fk_categorie'=>"rowid or label", 'cu.fk_user'=>"rowid or login"); } diff --git a/htdocs/core/modules/modEventOrganization.class.php b/htdocs/core/modules/modEventOrganization.class.php index 8a3fb3d80cf..6ab1c8acb89 100644 --- a/htdocs/core/modules/modEventOrganization.class.php +++ b/htdocs/core/modules/modEventOrganization.class.php @@ -19,7 +19,7 @@ * \defgroup eventorganization Module EventOrganization * \brief EventOrganization module descriptor. * - * \file htdocs/eventorganization/core/modules/modEventOrganization.class.php + * \file htdocs/core/modules/modEventOrganization.class.php * \ingroup eventorganization * \brief Description and activation file for the EventOrganization */ diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index 2fadb5d86ae..ef341c83e89 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -142,7 +142,7 @@ class modFacture extends DolibarrModules 'objectname'=>'Facture', 'method'=>'sendEmailsRemindersOnInvoiceDueDate', 'parameters'=>"10,all,EmailTemplateCode", - 'comment'=>'Send an emails when the unpaid invoices reach a due date + n days = today. First param is the offset n of days, second parameter is "all" or a payment mode code, last paramater is the code of email template to use (an email template with EmailTemplateCode must exists. the version in the language of the thirdparty will be used in priority).', + 'comment'=>'Send an emails when the unpaid invoices reach a due date + n days = today. First param is the offset n of days, second parameter is "all" or a payment mode code, last parameter is the code of email template to use (an email template with EmailTemplateCode must exists. the version in the language of the thirdparty will be used in priority).', 'frequency'=>1, 'unitfrequency'=>3600 * 24, 'priority'=>50, diff --git a/htdocs/core/modules/modFckeditor.class.php b/htdocs/core/modules/modFckeditor.class.php index 94912030a56..3dfd0f233e5 100644 --- a/htdocs/core/modules/modFckeditor.class.php +++ b/htdocs/core/modules/modFckeditor.class.php @@ -69,12 +69,12 @@ class modFckeditor extends DolibarrModules // Constants $this->const = array(); - $this->const[0] = array("FCKEDITOR_ENABLE_SOCIETE", "yesno", "1", "WYSIWIG for description and note (except products/services)"); - $this->const[1] = array("FCKEDITOR_ENABLE_PRODUCTDESC", "yesno", "1", "WYSIWIG for products/services description and note"); - $this->const[2] = array("FCKEDITOR_ENABLE_MAILING", "yesno", "1", "WYSIWIG for mass emailings"); - $this->const[3] = array("FCKEDITOR_ENABLE_DETAILS", "yesno", "1", "WYSIWIG for products details lines for all entities"); - $this->const[4] = array("FCKEDITOR_ENABLE_USERSIGN", "yesno", "1", "WYSIWIG for user signature"); - $this->const[5] = array("FCKEDITOR_ENABLE_MAIL", "yesno", "1", "WYSIWIG for products details lines for all entities"); + $this->const[0] = array("FCKEDITOR_ENABLE_SOCIETE", "yesno", "1", "WYSIWIG for description and note (except products/services)"); + $this->const[1] = array("FCKEDITOR_ENABLE_PRODUCTDESC", "yesno", "1", "WYSIWIG for products/services description and note"); + $this->const[2] = array("FCKEDITOR_ENABLE_MAILING", "yesno", "1", "WYSIWIG for mass emailings"); + $this->const[3] = array("FCKEDITOR_ENABLE_DETAILS", "yesno", "1", "WYSIWIG for products details lines for all entities"); + $this->const[4] = array("FCKEDITOR_ENABLE_USERSIGN", "yesno", "1", "WYSIWIG for user signature"); + $this->const[5] = array("FCKEDITOR_ENABLE_MAIL", "yesno", "1", "WYSIWIG for products details lines for all entities"); $this->const[6] = array("FCKEDITOR_SKIN", "string", "moono-lisa", "Skin by default for fckeditor"); // Boxes diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 6efebe9a82b..8e0fd6ea126 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -34,7 +34,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; */ class modFournisseur extends DolibarrModules { - /** * Constructor. Define names, constants, directories, boxes, permissions * @@ -430,8 +429,8 @@ class modFournisseur extends DolibarrModules 's.rowid'=>"IdCompany", 's.nom'=>'CompanyName', 'ps.nom'=>'ParentCompany', 's.address'=>'Address', 's.zip'=>'Zip', 's.town'=>'Town', 'c.code'=>'CountryCode', 's.phone'=>'Phone', 's.siren'=>'ProfId1', 's.siret'=>'ProfId2', 's.ape'=>'ProfId3', 's.idprof4'=>'ProfId4', 's.idprof5'=>'ProfId5', 's.idprof6'=>'ProfId6', 's.tva_intra'=>'VATIntra', 'f.rowid'=>"OrderId", 'f.ref'=>"Ref", 'f.ref_supplier'=>"RefSupplier", 'f.date_creation'=>"DateCreation", 'f.date_commande'=>"OrderDate", 'f.date_livraison'=>"DateDeliveryPlanned", - 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.fk_statut'=>'Status', 'f.date_approve'=>'DateApprove', 'f.date_approve2'=>'DateApprove2', - 'f.note_public'=>"NotePublic", 'f.note_private'=>"NotePrivate", 'ua1.login'=>'ApprovedBy', 'ua2.login'=>'ApprovedBy2', 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", + 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.fk_statut'=>'Status', 'f.date_valid'=>'DateValidation', 'f.date_approve'=>'DateApprove', 'f.date_approve2'=>'DateApprove2', + 'f.note_public'=>"NotePublic", 'f.note_private'=>"NotePrivate", 'uv.login'=>'UserValidation', 'ua1.login'=>'ApprovedBy', 'ua2.login'=>'ApprovedBy2', 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", 'fd.total_ttc'=>"LineTotalTTC", 'fd.total_tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.ref'=>'RefSupplier', 'fd.fk_product'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' @@ -451,13 +450,13 @@ class modFournisseur extends DolibarrModules 's.rowid'=>"company", 's.nom'=>'Text', 'ps.nom'=>'Text', 's.address'=>'Text', 's.cp'=>'Text', 's.ville'=>'Text', 'c.code'=>'Text', 's.tel'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.idprof5'=>'Text', 's.idprof6'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", 'f.date_creation'=>"Date", 'f.date_commande'=>"Date", 'f.date_livraison'=>"Date", 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", - 'f.fk_statut'=>'Status', 'f.date_approve'=>'Date', 'f.date_approve2'=>'Date', 'f.note_public'=>"Text", 'f.note_private'=>"Text", 'fd.description'=>"Text", + 'f.fk_statut'=>'Status', 'f.date_valid'=>'Date', 'f.date_approve'=>'Date', 'f.date_approve2'=>'Date', 'f.note_public'=>"Text", 'f.note_private'=>"Text", 'fd.description'=>"Text", 'fd.tva_tx'=>"Numeric", 'fd.qty'=>"Numeric", 'fd.remise_percent'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.total_tva'=>"Numeric", 'fd.product_type'=>'Numeric', 'fd.ref'=>'Text', 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text' ); $this->export_entities_array[$r] = array( 's.rowid'=>"company", 's.nom'=>'company', 'ps.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 's.phone'=>'company', 's.siren'=>'company', - 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company', 's.tva_intra'=>'company', 'ua1.login'=>'user', + 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company', 's.tva_intra'=>'company', 'uv.login'=>'user', 'ua1.login'=>'user', 'ua2.login'=>'user', 'fd.rowid'=>'order_line', 'fd.description'=>"order_line", 'fd.tva_tx'=>"order_line", 'fd.qty'=>"order_line", 'fd.remise_percent'=>"order_line", 'fd.total_ht'=>"order_line", 'fd.total_ttc'=>"order_line", 'fd.total_tva'=>"order_line", 'fd.product_type'=>'order_line', 'fd.ref'=>'order_line', 'fd.fk_product'=>'product', 'p.ref'=>'product', 'p.label'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' @@ -484,6 +483,7 @@ class modFournisseur extends DolibarrModules $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid,'; $this->export_sql_end[$r] .= ' '.MAIN_DB_PREFIX.'commande_fournisseur as f'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet as project on (f.fk_projet = project.rowid)'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as uv ON uv.rowid = f.fk_user_valid'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua1 ON ua1.rowid = f.fk_user_approve'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user as ua2 ON ua2.rowid = f.fk_user_approve2'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'commande_fournisseur_extrafields as extra ON f.rowid = extra.fk_object,'; diff --git a/htdocs/core/modules/modHRM.class.php b/htdocs/core/modules/modHRM.class.php index a50b06201a2..b13e5b6bbba 100644 --- a/htdocs/core/modules/modHRM.class.php +++ b/htdocs/core/modules/modHRM.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2015-2021 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,25 +13,27 @@ * * 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/core/modules/modHRM.class.php - * \ingroup HRM - * \brief Description and activation file for the module HRM + * \defgroup HRM Module hrm + * \file htdocs/core/modules/modHRM.class.php + * \ingroup HRM + * \brief Description and activation file for the module HRM */ include_once DOL_DOCUMENT_ROOT."/core/modules/DolibarrModules.class.php"; + /** - * Class to describe and activate the HRM module + * Description and activation class for module HRM */ class modHRM extends DolibarrModules { /** - * Constructor. - * Define names, constants, directories, boxes, permissions + * Constructor. Define names, constants, directories, boxes, permissions * - * @param DoliDB $db Database handler + * @param DoliDB $db Database handler */ public function __construct($db) { @@ -39,105 +41,238 @@ class modHRM extends DolibarrModules $this->db = $db; + // Id for module (must be unique). + // Use here a free id (See in Home -> System information -> Dolibarr for list of used modules id). $this->numero = 4000; + // Key text used to identify module (for permissions, menus, etc...) $this->rights_class = 'hrm'; + // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' + // It is used to group modules in module setup page $this->family = "hr"; $this->module_position = '50'; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i', '', get_class($this)); - $this->description = "Management of employees carrier and feelings (department, employment contract)"; - + // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) + $this->description = "HRM"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'experimental'; - + $this->version = 'development'; + // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of image file used for this module. // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' $this->picto = 'hrm'; - // define triggers - $this->module_parts = array(); + // Define some features supported by module (triggers, login, substitutions, menus, css, etc...) + $this->module_parts = array( + // Set this to 1 if module has its own trigger directory (core/triggers) + 'triggers' => 0, + // Set this to 1 if module has its own login method file (core/login) + 'login' => 0, + // Set this to 1 if module has its own substitution function file (core/substitutions) + 'substitutions' => 0, + // Set this to 1 if module has its own menus handler directory (core/menus) + 'menus' => 0, + // Set this to 1 if module overwrite template dir (core/tpl) + 'tpl' => 0, + // Set this to 1 if module has its own barcode directory (core/modules/barcode) + 'barcode' => 0, + // Set this to 1 if module has its own models directory (core/modules/xxx) + 'models' => 1, + // Set this to 1 if module has its own printing directory (core/modules/printing) + 'printing' => 0, + // Set this to 1 if module has its own theme directory (theme) + 'theme' => 0, + // Set this to relative path of css file if module has its own css file + 'css' => array( + '/hrm/css/radio_js_number.css', + ), + // Set this to relative path of js file if module must load a js on all pages + 'js' => array( + // '/hrm/js/hrm.js.php', + ), - // Data directories to create when module is enabled - $this->dirs = array(); + // Set this to 1 if features of module are opened to external users + 'moduleforexternal' => 0, + ); - // Config pages - $this->config_page_url = array('admin_hrm.php@hrm'); + // Data directories to create when module is enabled. + // Example: this->dirs = array("/hrm/temp","/hrm/subdir"); + $this->dirs = array("/hrm/temp"); + + // Config pages. Put here list of php page, stored into hrm/admin directory, to use to setup module. + $this->config_page_url = array("hrm.php"); // Dependencies $this->hidden = false; // A condition to hide module $this->depends = array(); // List of module class names as string that must be enabled if this module is enabled - $this->requiredby = array(/*"modSalaries, modExpenseReport, modHoliday"*/); // List of module ids to disable if this one is disabled + $this->requiredby = array(); // List of module ids to disable if this one is disabled $this->conflictwith = array(); // List of module class names as string this module is in conflict with $this->phpmin = array(5, 6); // Minimum version of PHP required by module - $this->need_dolibarr_version = array(3, 9); // Minimum version of Dolibarr required by module + $this->need_dolibarr_version = array(11, 0); // Minimum version of Dolibarr required by module $this->langfiles = array("hrm"); + // Constants + // Example: $this->const=array(0=>array('MYMODULE_MYNEWCONST1','chaine','myvalue','This is a constant to add',0), + // 1=>array('MYMODULE_MYNEWCONST2','chaine','myvalue','This is another constant to add',0) ); + // 2=>array('MAIN_MODULE_MYMODULE_NEEDSMARTY','chaine',1,'Constant to say module need smarty',0) + $this->const = array(); // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 0 or 'allentities') + $r = 0; + + + if (!isset($conf->hrm) || !isset($conf->hrm->enabled)) { + $conf->hrm = new stdClass(); + $conf->hrm->enabled = 0; + } + + // Array to add new pages in new tabs + $this->tabs = array(); + $this->tabs[] = array('data'=>'user:+skill_tab:Skills:hrm:1:/hrm/skill_tab.php?id=__ID__&objecttype=user'); // To add a new tab identified by code tabname1 + //$this->tabs[] = array('data'=>'job:+tabname1:Poste:mylangfile@hrm:1:/hrm/poste_list.php?fk_job=__ID__'); // To add a new tab identified by code tabname1 + // Example: + // $this->tabs[] = array('data'=>'objecttype:+tabname1:Title1:mylangfile@hrm:$user->rights->hrm->read:/hrm/mynewtab1.php?id=__ID__'); // To add a new tab identified by code tabname1 + // $this->tabs[] = array('data'=>'objecttype:+tabname2:SUBSTITUTION_Title2:mylangfile@hrm:$user->rights->othermodule->read:/hrm/mynewtab2.php?id=__ID__', // To add another new tab identified by code tabname2. Label will be result of calling all substitution functions on 'Title2' key. + // $this->tabs[] = array('data'=>'objecttype:-tabname:NU:conditiontoremove'); // To remove an existing tab identified by code tabname + // + // Where objecttype can be + // 'categories_x' to add a tab in category view (replace 'x' by type of category (0=product, 1=supplier, 2=customer, 3=member) + // 'contact' to add a tab in contact view + // 'contract' to add a tab in contract view + // 'group' to add a tab in group view + // 'intervention' to add a tab in intervention view + // 'invoice' to add a tab in customer invoice view + // 'invoice_supplier' to add a tab in supplier invoice view + // 'member' to add a tab in fundation member view + // 'opensurveypoll' to add a tab in opensurvey poll view + // 'order' to add a tab in customer order view + // 'order_supplier' to add a tab in supplier order view + // 'payment' to add a tab in payment view + // 'payment_supplier' to add a tab in supplier payment view + // 'product' to add a tab in product view + // 'propal' to add a tab in propal view + // 'project' to add a tab in project view + // 'stock' to add a tab in stock view + // 'thirdparty' to add a tab in third party view + // 'user' to add a tab in user view + + // Dictionaries $this->dictionaries = array(); - // Constantes - $this->const = array(); - $r = 0; + // Boxes/Widgets + // Add here list of php file(s) stored in hrm/core/boxes that contains a class to show a widget. + $this->boxes = array( + // 0 => array( + // 'file' => 'hrmwidget1.php@hrm', + // 'note' => 'Widget provided by HrmTest', + // 'enabledbydefaulton' => 'Home', + // ), + // ... + ); + + // Cronjobs (List of cron jobs entries to add when module is enabled) + // unit_frequency must be 60 for minute, 3600 for hour, 86400 for day, 604800 for week + $this->cronjobs = array( + // 0 => array( + // 'label' => 'MyJob label', + // 'jobtype' => 'method', + // 'class' => '/hrm/class/poste.class.php', + // 'objectname' => 'Poste', + // 'method' => 'doScheduledJob', + // 'parameters' => '', + // 'comment' => 'Comment', + // 'frequency' => 2, + // 'unitfrequency' => 3600, + // 'status' => 0, + // 'test' => '$conf->hrm->enabled', + // 'priority' => 50, + // ), + ); - // Boxes - $this->boxes = array(); // Permissions $this->rights = array(); // Permission array used by this module $r = 0; - /* - $this->rights[$r][0] = 4001; - $this->rights[$r][1] = 'See employees'; - $this->rights[$r][3] = 0; - $this->rights[$r][4] = 'employee'; - $this->rights[$r][5] = 'read'; + // Skill / Job / Position + $this->rights[$r][0] = 4010; // Permission id (must not be already used) + $this->rights[$r][1] = 'Read skill/job/position'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'all'; + $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->hrm->all->read) $r++; - $this->rights[$r][0] = 4002; - $this->rights[$r][1] = 'Create employees'; - $this->rights[$r][3] = 0; - $this->rights[$r][4] = 'employee'; - $this->rights[$r][5] = 'write'; + $this->rights[$r][0] = 4011; // Permission id (must not be already used) + $this->rights[$r][1] = 'Create/modify skill/job/position'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'all'; + $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->hrm->all->write) $r++; - $this->rights[$r][0] = 4003; - $this->rights[$r][1] = 'Delete employees'; - $this->rights[$r][3] = 0; - $this->rights[$r][4] = 'employee'; - $this->rights[$r][5] = 'delete'; + $this->rights[$r][0] = 4012; // Permission id (must not be already used) + $this->rights[$r][1] = 'Delete skill/job/position'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'all'; + $this->rights[$r][5] = 'delete'; // In php code, permission will be checked by test if ($user->rights->hrm->all->delete) $r++; - $this->rights[$r][0] = 4004; - $this->rights[$r][1] = 'Export employees'; - $this->rights[$r][3] = 0; - $this->rights[$r][4] = 'employee'; - $this->rights[$r][5] = 'export'; + // Evaluation + $this->rights[$r][0] = 4020; // Permission id (must not be already used) + $this->rights[$r][1] = 'Read evaluations'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'evaluation'; + $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->hrm->evaluation->read) $r++; - */ - // Menus - //------- - $this->menu = 1; // This module add menu entries. They are coded into menu manager. + $this->rights[$r][0] = 4021; // Permission id (must not be already used) + $this->rights[$r][1] = 'Create/modify your own evaluation'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'evaluation'; + $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->hrm->evaluation->write) + $r++; + + $this->rights[$r][0] = 4022; // Permission id (must not be already used) + $this->rights[$r][1] = 'Validate evaluation'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'evaluation_advance'; + $this->rights[$r][5] = 'validate'; // In php code, permission will be checked by test if ($user->rights->hrm->evaluation->validate) + $r++; + + $this->rights[$r][0] = 4023; // Permission id (must not be already used) + $this->rights[$r][1] = 'Delete all evaluations'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'evaluation'; + $this->rights[$r][5] = 'delete'; // In php code, permission will be checked by test if ($user->rights->hrm->evaluation->delete) + $r++; + + // Comparison + $this->rights[$r][0] = 4030; // Permission id (must not be already used) + $this->rights[$r][1] = 'See comparison menu'; // Permission label + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'compare_advance'; + $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->hrm->compare_advance->read) + $r++; } /** - * Function called when module is enabled. - * The init function add constants, boxes, permissions and menus - * (defined in constructor) into Dolibarr database. - * It also creates data directories + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories * - * @param string $options Enabling module ('', 'noboxes') - * @return int if OK, 0 if KO + * @param string $options Options when enabling module ('', 'newboxdefonly', 'noboxes') + * @return int 1 if OK, 0 if KO */ public function init($options = '') { // Permissions $this->remove($options); + /*$result = $this->_load_tables('/hrm/sql/'); + if ($result < 0) { + return -1; // Do not activate module if error 'not allowed' returned when loading module SQL queries (the _load_table run sql with run_sql with the error allowed parameter set to 'default') + }*/ + $sql = array(); return $this->_init($sql, $options); diff --git a/htdocs/core/modules/modKnowledgeManagement.class.php b/htdocs/core/modules/modKnowledgeManagement.class.php index c3be87963c8..b3fb24aa7b3 100644 --- a/htdocs/core/modules/modKnowledgeManagement.class.php +++ b/htdocs/core/modules/modKnowledgeManagement.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2018-2019 Nicolas ZABOURI - * Copyright (C) 2019-2020 Frédéric France + * Copyright (C) 2019-2021 Frédéric France * Copyright (C) 2021 SuperAdmin * * This program is free software; you can redistribute it and/or modify @@ -22,7 +22,7 @@ * \defgroup knowledgemanagement Module KnowledgeManagement * \brief KnowledgeManagement module descriptor. * - * \file htdocs/knowledgemanagement/core/modules/modKnowledgeManagement.class.php + * \file htdocs/core/modules/modKnowledgeManagement.class.php * \ingroup knowledgemanagement * \brief Description and activation file for module KnowledgeManagement */ @@ -68,7 +68,7 @@ class modKnowledgeManagement extends DolibarrModules $this->descriptionlong = "Manage a Knowledge Management (KM) or Help-Desk base"; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = 'experimental'; + $this->version = 'dolibarr'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; @@ -362,6 +362,19 @@ class modKnowledgeManagement extends DolibarrModules // 0=Menu for internal users, 1=external users, 2=both 'user'=>2 ); + $this->menu[$r++] = array( + 'fk_menu' => 'fk_mainmenu=ticket,fk_leftmenu=knowledgemanagement_knowledgerecord', + 'type' => 'left', + 'titre' => 'Categories', + 'mainmenu' => 'ticket', + 'url' => '/categories/index.php?type=13', + 'langs' => 'knowledgemanagement', + 'position' => 112, + 'enabled' => '$conf->knowledgemanagement->enabled', + 'perms' => '$user->rights->knowledgemanagement->knowledgerecord->read', + 'target' => '', + 'user' => 0 + ); /* END MODULEBUILDER LEFTMENU KNOWLEDGERECORD */ diff --git a/htdocs/core/modules/modMultiCurrency.class.php b/htdocs/core/modules/modMultiCurrency.class.php index 5bf91ec341e..98d7222f082 100644 --- a/htdocs/core/modules/modMultiCurrency.class.php +++ b/htdocs/core/modules/modMultiCurrency.class.php @@ -300,10 +300,11 @@ class modMultiCurrency extends DolibarrModules { global $conf, $user, $langs; - if (!MultiCurrency::checkCodeAlreadyExists($conf->currency)) { + $multicurrency = new MultiCurrency($this->db); + + if (!$multicurrency->checkCodeAlreadyExists($conf->currency)) { $langs->loadCacheCurrencies(''); - $multicurrency = new MultiCurrency($this->db); $multicurrency->code = $conf->currency; $multicurrency->name = $langs->cache_currencies[$conf->currency]['label'].' ('.$langs->getCurrencySymbol($conf->currency).')'; $r = $multicurrency->create($user); diff --git a/htdocs/core/modules/modPartnership.class.php b/htdocs/core/modules/modPartnership.class.php index a036613fcec..87ce98abb4a 100644 --- a/htdocs/core/modules/modPartnership.class.php +++ b/htdocs/core/modules/modPartnership.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2018-2019 Nicolas ZABOURI - * Copyright (C) 2019-2020 Frédéric France + * Copyright (C) 2019-2021 Frédéric France * Copyright (C) 2021 Dorian Laurent * Copyright (C) 2021 NextGestion * @@ -23,7 +23,7 @@ * \defgroup partnership Module Partnership * \brief Partnership module descriptor. * - * \file htdocs/partnership/core/modules/modPartnership.class.php + * \file htdocs/core/modules/modPartnership.class.php * \ingroup partnership * \brief Description and activation file for module Partnership */ diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 3caf5db88c6..f72dc00cfaf 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -638,7 +638,7 @@ class modProduct extends DolibarrModules // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'product' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index deefea6c2e8..08eb3c58adc 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -296,7 +296,7 @@ class modProjet extends DolibarrModules $this->import_tables_array[$r] = array('t'=>MAIN_DB_PREFIX.'projet_task', 'extra'=>MAIN_DB_PREFIX.'projet_task_extrafields'); // List of tables to insert into (insert done in same order) $this->import_fields_array[$r] = array('t.fk_projet'=>'ProjectRef*', 't.ref'=>'RefTask*', 't.label'=>'LabelTask*', 't.dateo'=>"DateStart", 't.datee'=>"DateEnd", 't.planned_workload'=>"PlannedWorkload", 't.progress'=>"Progress", 't.note_private'=>"NotePrivate", 't.note_public'=>"NotePublic", 't.datec'=>"DateCreation"); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { @@ -309,7 +309,7 @@ class modProjet extends DolibarrModules $this->import_fieldshidden_array[$r] = array('t.fk_user_creat'=>'user->id', 'extra.fk_object'=>'lastrowid-'.MAIN_DB_PREFIX.'projet_task'); // aliastable.field => ('user->id' or 'lastrowid-'.tableparent) $this->import_convertvalue_array[$r] = array( 't.fk_projet'=>array('rule'=>'fetchidfromref', 'classfile'=>'/projet/class/project.class.php', 'class'=>'Project', 'method'=>'fetch', 'element'=>'Project'), - 't.ref'=>array('rule'=>'getrefifauto') + 't.ref'=>array('rule'=>'getrefifauto', 'class'=>(empty($conf->global->PROJECT_TASK_ADDON) ? 'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON), 'path'=>"/core/modules/project/task/".(empty($conf->global->PROJECT_TASK_ADDON) ? 'mod_task_simple' : $conf->global->PROJECT_TASK_ADDON).'.php') ); //$this->import_convertvalue_array[$r]=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t'); $this->import_regex_array[$r] = array('t.dateo'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 't.datee'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]$', 't.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$'); diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php index b46671eae01..1374e70d6d4 100644 --- a/htdocs/core/modules/modPropale.class.php +++ b/htdocs/core/modules/modPropale.class.php @@ -23,7 +23,7 @@ /** * \defgroup propale Module commercial proposals - * \brief Module pour gerer la tenue de propositions commerciales + * \brief Module to manage commercial proposals * \file htdocs/core/modules/modPropale.class.php * \ingroup propale * \brief Description and activation file for the module customer proposal @@ -36,7 +36,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; */ class modPropale extends DolibarrModules { - /** * Constructor. Define names, constants, directories, boxes, permissions * diff --git a/htdocs/core/modules/modRecruitment.class.php b/htdocs/core/modules/modRecruitment.class.php index 02e7cdfbf4c..239c48135d7 100644 --- a/htdocs/core/modules/modRecruitment.class.php +++ b/htdocs/core/modules/modRecruitment.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2018-2019 Nicolas ZABOURI - * Copyright (C) 2019-2020 Frédéric France + * Copyright (C) 2019-2021 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 @@ -21,7 +21,7 @@ * \defgroup recruitment Module Recruitment * \brief Recruitment module descriptor. * - * \file htdocs/recruitment/core/modules/modRecruitment.class.php + * \file htdocs/core/modules/modRecruitment.class.php * \ingroup recruitment * \brief Description and activation file for the module Recruitment */ diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php index 6f2d3f8d409..377d5aadbc4 100644 --- a/htdocs/core/modules/modResource.class.php +++ b/htdocs/core/modules/modResource.class.php @@ -268,7 +268,7 @@ class modResource extends DolibarrModules $this->import_tables_array[$r] = array('r'=>MAIN_DB_PREFIX.'resource', 'extra'=>MAIN_DB_PREFIX.'resource_extrafields'); // List of tables to insert into (insert done in same order) $this->import_fields_array[$r] = array('r.ref'=>"ResourceFormLabel_ref*", 'r.fk_code_type_resource'=>'ResourceTypeCode', 'r.description'=>'ResourceFormLabel_description', 'r.note_private'=>"NotePrivate", 'r.note_public'=>"NotePublic", 'r.asset_number'=>'AssetNumber', 'r.datec'=>'DateCreation'); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'resource' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'resource' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 21a26bdc750..0390a23cc83 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -584,7 +584,7 @@ class modService extends DolibarrModules } // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'product' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index eed6871c465..ca5b484499a 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -281,6 +281,9 @@ class modSociete extends DolibarrModules if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $this->export_fields_array[$r]['s.price_level'] = 'PriceLevel'; } + if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { + $this->export_fields_array[$r] += array('s.accountancy_code_sell'=>'ProductAccountancySellCode', 's.accountancy_code_buy'=>'ProductAccountancyBuyCode'); + } // Add multicompany field if (!empty($conf->global->MULTICOMPANY_ENTITY_IN_EXPORT_IF_SHARED)) { $nbofallowedentities = count(explode(',', getEntity('societe'))); // If project are shared, nb will be > 1 @@ -317,7 +320,8 @@ class modSociete extends DolibarrModules 'payterm.libelle'=>'Text', 'paymode.libelle'=>'Text', 's.outstanding_limit'=>'Numeric', 'pbacc.ref'=>'Text', 'incoterm.code'=>'Text', 'u.login'=>'Text', 'u.firstname'=>'Text', 'u.lastname'=>'Text', - 's.entity'=>'Numeric', 's.price_level'=>'Numeric' + 's.entity'=>'Numeric', 's.price_level'=>'Numeric', + 's.accountancy_code_sell'=>'Text', 's.accountancy_code_buy'=>'Text' ); $this->export_entities_array[$r] = array('u.login'=>'user', 'u.firstname'=>'user', 'u.lastname'=>'user'); // We define here only fields that use another picto @@ -488,8 +492,11 @@ class modSociete extends DolibarrModules if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $this->import_fields_array[$r]['s.price_level'] = 'PriceLevel'; } + if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) { + $this->import_fields_array[$r] += array('s.accountancy_code_sell'=>'ProductAccountancySellCode', 's.accountancy_code_buy'=>'ProductAccountancyBuyCode'); + } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { @@ -621,7 +628,9 @@ class modSociete extends DolibarrModules 's.canvas' => "empty / a custom canvas form layout url e.g. mycanvas@mymodule", 's.datec' => 'formatted as '.dol_print_date(dol_now(), '%Y-%m-%d'), 's.fk_multicurrency' => '0 (use system default currency) / 1 (use local currency)', - 's.multicurrency_code' => 'GBP/USD etc... matches field "code_iso" in table "'.MAIN_DB_PREFIX.'c_currencies"' + 's.multicurrency_code' => 'GBP/USD etc... matches field "code_iso" in table "'.MAIN_DB_PREFIX.'c_currencies"', + 's.accountancy_code_sell' => '707', + 's.accountancy_code_buy' => '607', ); $this->import_updatekeys_array[$r] = array( 's.nom' => 'Name', @@ -665,7 +674,7 @@ class modSociete extends DolibarrModules 's.note_public' => "NotePublic" ); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on an old database (during a migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index d0cfa64c884..00e5a7859c0 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -414,7 +414,7 @@ class modStock extends DolibarrModules ); $this->import_updatekeys_array[$r] = array('ps.fk_product'=>'Product', 'ps.fk_entrepot'=>"Warehouse"); $this->import_run_sql_after_array[$r] = array( // Because we may change data that are denormalized, we must update dernormalized data after. - 'UPDATE '.MAIN_DB_PREFIX.'product p SET p.stock= (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.'product_stock ps WHERE ps.fk_product = p.rowid);' + 'UPDATE '.MAIN_DB_PREFIX.'product as p SET p.stock = (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.'product_stock ps WHERE ps.fk_product = p.rowid);' ); } diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php index e54ac7bd440..4b660e6159a 100644 --- a/htdocs/core/modules/modUser.class.php +++ b/htdocs/core/modules/modUser.class.php @@ -49,7 +49,7 @@ class modUser extends DolibarrModules $this->module_position = '05'; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i', '', get_class($this)); - $this->description = "Gestion des utilisateurs (requis)"; + $this->description = "Management of users and groups of users (mandatory)"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version $this->version = 'dolibarr'; @@ -90,7 +90,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 251; - $this->rights[$r][1] = 'Consulter les autres utilisateurs'; + $this->rights[$r][1] = 'Read information of other users, groups and permissions'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'user'; @@ -98,15 +98,15 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 252; - $this->rights[$r][1] = 'Consulter les permissions des autres utilisateurs'; + $this->rights[$r][1] = 'Read permissions of other users'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; - $this->rights[$r][4] = 'user_advance'; + $this->rights[$r][4] = 'user_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on $this->rights[$r][5] = 'readperms'; $r++; $this->rights[$r][0] = 253; - $this->rights[$r][1] = 'Creer/modifier utilisateurs internes et externes'; + $this->rights[$r][1] = 'Create/modify internal and external users, groups and permissions'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'user'; @@ -114,15 +114,15 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 254; - $this->rights[$r][1] = 'Creer/modifier utilisateurs externes seulement'; + $this->rights[$r][1] = 'Create/modify external users only'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; - $this->rights[$r][4] = 'user_advance'; + $this->rights[$r][4] = 'user_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on $this->rights[$r][5] = 'write'; $r++; $this->rights[$r][0] = 255; - $this->rights[$r][1] = 'Modifier le mot de passe des autres utilisateurs'; + $this->rights[$r][1] = 'Modify the password of other users'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'user'; @@ -130,7 +130,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 256; - $this->rights[$r][1] = 'Supprimer ou desactiver les autres utilisateurs'; + $this->rights[$r][1] = 'Delete or disable other users'; $this->rights[$r][2] = 'd'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'user'; @@ -138,7 +138,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 341; - $this->rights[$r][1] = 'Consulter ses propres permissions'; + $this->rights[$r][1] = 'Read its own permissions'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'self_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on @@ -146,7 +146,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 342; - $this->rights[$r][1] = 'Creer/modifier ses propres infos utilisateur'; + $this->rights[$r][1] = 'Create/modify of its own user'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'self'; @@ -154,7 +154,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 343; - $this->rights[$r][1] = 'Modifier son propre mot de passe'; + $this->rights[$r][1] = 'Modify its own password'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'self'; @@ -162,7 +162,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 344; - $this->rights[$r][1] = 'Modifier ses propres permissions'; + $this->rights[$r][1] = 'Modify its own permissions'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'self_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on @@ -170,7 +170,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 351; - $this->rights[$r][1] = 'Consulter les groupes'; + $this->rights[$r][1] = 'Read groups'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'group_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on @@ -178,7 +178,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 352; - $this->rights[$r][1] = 'Consulter les permissions des groupes'; + $this->rights[$r][1] = 'Read permissions of groups'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'group_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on @@ -186,7 +186,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 353; - $this->rights[$r][1] = 'Creer/modifier les groupes et leurs permissions'; + $this->rights[$r][1] = 'Create/modify groups and permissions'; $this->rights[$r][2] = 'w'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'group_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on @@ -194,7 +194,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 354; - $this->rights[$r][1] = 'Supprimer ou desactiver les groupes'; + $this->rights[$r][1] = 'Delete groups'; $this->rights[$r][2] = 'd'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'group_advance'; // Visible if option MAIN_USE_ADVANCED_PERMS is on @@ -202,7 +202,7 @@ class modUser extends DolibarrModules $r++; $this->rights[$r][0] = 358; - $this->rights[$r][1] = 'Exporter les utilisateurs'; + $this->rights[$r][1] = 'Export all users'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'user'; @@ -298,7 +298,7 @@ class modUser extends DolibarrModules 'u.statut'=>'Status' ); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'user' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type <> 'separate' AND elementtype = 'user' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modWorkstation.class.php b/htdocs/core/modules/modWorkstation.class.php index 3069be8ced5..38c5222401c 100755 --- a/htdocs/core/modules/modWorkstation.class.php +++ b/htdocs/core/modules/modWorkstation.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2018-2019 Nicolas ZABOURI - * Copyright (C) 2019-2020 Frédéric France + * Copyright (C) 2019-2021 Frédéric France * Copyright (C) 2020 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify @@ -22,7 +22,7 @@ * \defgroup workstation Module Workstation * \brief Workstation module descriptor. * - * \file htdocs/workstation/core/modules/modWorkstation.class.php + * \file htdocs/core/modules/modWorkstation.class.php * \ingroup workstation * \brief Description and activation file for the module Workstation */ diff --git a/htdocs/core/modules/movement/doc/pdf_standard.modules.php b/htdocs/core/modules/movement/doc/pdf_standard.modules.php index 528f45ee962..7f487fdcf94 100644 --- a/htdocs/core/modules/movement/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/movement/doc/pdf_standard.modules.php @@ -35,7 +35,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; /** * Class to build documents using ODF templates generator */ -class pdf_stdandard extends ModelePDFMovement +class pdf_standard extends ModelePDFMovement { /** * @var DoliDb Database handler diff --git a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php index b6ad4c6b8ff..c2d697b4a4d 100644 --- a/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php +++ b/htdocs/core/modules/mrp/doc/doc_generic_mo_odt.modules.php @@ -302,11 +302,14 @@ class doc_generic_mo_odt extends ModelePDFMo // Recipient name $contactobject = null; if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php b/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php index 5f6a03f2caa..d116976eb88 100644 --- a/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php +++ b/htdocs/core/modules/mrp/doc/pdf_vinci.modules.php @@ -5,8 +5,8 @@ * Copyright (C) 2010-2014 Juanjo Menent * Copyright (C) 2015 Marcos García * Copyright (C) 2017 Ferran Marcet - * Copyright (C) 2018 Frédéric France - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018-2021 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 @@ -23,7 +23,7 @@ */ /** - * \file htdocs/core/modules/mrp/doc/pdf_vinci.php + * \file htdocs/core/modules/mrp/doc/pdf_vinci.modules.php * \ingroup mrp * \brief File of class to generate MO document from vinci model */ diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index ec53b523336..226ed6c43cd 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -237,7 +237,7 @@ class printing_printgcp extends PrintingDriver if ($conf->global->PRINTING_GCP_DEFAULT == $printer_det['id']) { $html .= img_picto($langs->trans("Default"), 'on'); } else { - $html .= ''.img_picto($langs->trans("Disabled"), 'off').''; + $html .= ''.img_picto($langs->trans("Disabled"), 'off').''; } $html .= '
    '; // List of directories area @@ -165,35 +160,25 @@ class doc_generic_product_odt extends ModelePDFProduct $texte .= '
    '; // Scan directories - if (count($listofdir)) { + $nbofiles = count($listoffiles); + if (!empty($conf->global->PRODUCT_ADDON_PDF_ODT_PATH)) { $texte .= $langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; - - /*if ($conf->global->MAIN_PRODUCT_CHOOSE_ODT_DOCUMENT > 0) - { - // Model for creation - $liste=ModelePDFProduct::liste_modeles($this->db); - $texte.= '
    '; - $texte.= ''; - $texte.= ''; - $texte.= '"; - - $texte.= ''; - $texte.= ''; - $texte.= '"; - $texte.= ''; - - $texte.= ''; - $texte.= '"; - $texte.= '
    '.$langs->trans("DefaultModelPropalCreate").''; - $texte.= $form->selectarray('value2',$liste,$conf->global->PRODUCT_ADDON_PDF_ODT_DEFAULT); - $texte.= "
    '.$langs->trans("DefaultModelPropalToBill").''; - $texte.= $form->selectarray('value3',$liste,$conf->global->PRODUCT_ADDON_PDF_ODT_TOBILL); - $texte.= "
    '.$langs->trans("DefaultModelPropalClosed").''; - $texte.= $form->selectarray('value4',$liste,$conf->global->PRODUCT_ADDON_PDF_ODT_CLOSED); - $texte.= "
    '; - }*/ } + if ($nbofiles) { + $texte .= '
    '; + // Show list of found files + foreach ($listoffiles as $file) { + $texte .= '- '.$file['name'].' '.img_picto('', 'listlight').'
    '; + } + $texte .= '
    '; + } + // Add input to upload a new template file. + $texte .= '
    '.$langs->trans("UploadNewTemplate").' '; + $texte .= ''; + $texte .= ''; + $texte .= '
    '; + $texte .= ''; $texte .= ''; @@ -319,11 +304,14 @@ class doc_generic_product_odt extends ModelePDFProduct // Recipient name $contactobject = null; if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { @@ -344,7 +332,7 @@ class doc_generic_product_odt extends ModelePDFProduct // Line of free text $newfreetext = ''; - $paramfreetext = 'product_FREE_TEXT'; + $paramfreetext = 'PRODUCT_FREE_TEXT'; if (!empty($conf->global->$paramfreetext)) { $newfreetext = make_substitutions($conf->global->$paramfreetext, $substitutionarray); } @@ -372,7 +360,6 @@ class doc_generic_product_odt extends ModelePDFProduct //print html_entity_decode($odfHandler->__toString()); //print exit; - $object->fetch_optionals(); // Make substitutions into odt of freetext try { @@ -399,7 +386,7 @@ class doc_generic_product_odt extends ModelePDFProduct complete_substitutions_array($tmparray, $outputlangs, $object); // Call the ODTSubstitution hook - $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray); + $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray); $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks foreach ($tmparray as $key => $value) { @@ -480,6 +467,7 @@ class doc_generic_product_odt extends ModelePDFProduct } } + $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray); $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (!empty($conf->global->MAIN_UMASK)) { diff --git a/htdocs/core/modules/product_batch/mod_lot_advanced.php b/htdocs/core/modules/product_batch/mod_lot_advanced.php index 0e920483508..d44a261a16b 100644 --- a/htdocs/core/modules/product_batch/mod_lot_advanced.php +++ b/htdocs/core/modules/product_batch/mod_lot_advanced.php @@ -87,9 +87,9 @@ class mod_lot_advanced extends ModeleNumRefBatch // Option to enable custom masks per product $texte .= ''; if ($conf->global->PRODUCTBATCH_LOT_USE_PRODUCT_MASKS) { - $texte .= ''.img_picto($langs->trans("Enabled"), 'on').''; + $texte .= ''.img_picto($langs->trans("Enabled"), 'on').''; } else { - $texte .= ''.img_picto($langs->trans("Disabled"), 'off').''; + $texte .= ''.img_picto($langs->trans("Disabled"), 'off').''; } $texte .= ' '.$langs->trans('CustomMasks')."\n"; $texte .= ''; diff --git a/htdocs/core/modules/product_batch/mod_lot_free.php b/htdocs/core/modules/product_batch/mod_lot_free.php index 0f069143ab1..def14bd37b3 100644 --- a/htdocs/core/modules/product_batch/mod_lot_free.php +++ b/htdocs/core/modules/product_batch/mod_lot_free.php @@ -18,7 +18,7 @@ */ /** - * \file htdocs/core/modules/product/mod_lot_free.php + * \file htdocs/core/modules/product_batch/mod_lot_free.php * \ingroup productbatch * \brief File containing class for numbering model of Lot free */ diff --git a/htdocs/core/modules/product_batch/mod_sn_advanced.php b/htdocs/core/modules/product_batch/mod_sn_advanced.php index ca24a67c781..abe094220d2 100644 --- a/htdocs/core/modules/product_batch/mod_sn_advanced.php +++ b/htdocs/core/modules/product_batch/mod_sn_advanced.php @@ -22,7 +22,7 @@ */ /** - * \file htdocs/core/modules/product_batch/mod_batch_advanced.php + * \file htdocs/core/modules/product_batch/mod_sn_advanced.php * \ingroup productbatch * \brief File containing class for numbering model of SN advanced */ @@ -87,9 +87,9 @@ class mod_sn_advanced extends ModeleNumRefBatch // Option to enable custom masks per product $texte .= ''; if ($conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS) { - $texte .= ''.img_picto($langs->trans("Enabled"), 'on').''; + $texte .= ''.img_picto($langs->trans("Enabled"), 'on').''; } else { - $texte .= ''.img_picto($langs->trans("Disabled"), 'off').''; + $texte .= ''.img_picto($langs->trans("Disabled"), 'off').''; } $texte .= ' '.$langs->trans('CustomMasks')."\n"; $texte .= ''; diff --git a/htdocs/core/modules/product_batch/mod_sn_free.php b/htdocs/core/modules/product_batch/mod_sn_free.php index 95e1bd20359..67d39ec085a 100644 --- a/htdocs/core/modules/product_batch/mod_sn_free.php +++ b/htdocs/core/modules/product_batch/mod_sn_free.php @@ -18,7 +18,7 @@ */ /** - * \file htdocs/core/modules/product/mod_sn_free.php + * \file htdocs/core/modules/product_batch/mod_sn_free.php * \ingroup productbatch * \brief File containing class for numbering model of SN free */ diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index bd2fcfa471f..fb0991c8da1 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -335,11 +335,14 @@ class doc_generic_proposal_odt extends ModelePDFPropales // Recipient name $contactobject = null; if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index bf079c47b66..e964d61cda3 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -1616,7 +1616,7 @@ class pdf_azur extends ModelePDFPropales } // Recipient name - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { $thirdparty = $object->contact; } else { $thirdparty = $object->thirdparty; diff --git a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php index 97f76df31bb..d0e51fb8bc7 100644 --- a/htdocs/core/modules/propale/doc/pdf_cyan.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_cyan.modules.php @@ -1731,7 +1731,7 @@ class pdf_cyan extends ModelePDFPropales } // Recipient name - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { $thirdparty = $object->contact; } else { $thirdparty = $object->thirdparty; @@ -1739,7 +1739,7 @@ class pdf_cyan extends ModelePDFPropales $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); - $mode = 'target'; + $mode = 'target'; $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ($usecontact ? $object->contact : ''), $usecontact, $mode, $object); // Show recipient diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index 5904db84398..215987054ce 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -196,7 +196,7 @@ class pdf_paiement $sql .= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; } $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid AND pf.fk_facture = f.rowid AND pf.fk_paiement = p.rowid"; @@ -205,7 +205,7 @@ class pdf_paiement } $sql .= " AND f.entity IN (".getEntity('invoice').")"; $sql .= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year, $month))."' AND '".$this->db->idate(dol_get_last_day($year, $month))."'"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if (!empty($socid)) { @@ -234,7 +234,7 @@ class pdf_paiement $sql .= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; } $sql .= " ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid AND pf.fk_facturefourn = f.rowid AND pf.fk_paiementfourn = p.rowid"; @@ -243,7 +243,7 @@ class pdf_paiement } $sql .= " AND f.entity IN (".getEntity('invoice').")"; $sql .= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year, $month))."' AND '".$this->db->idate(dol_get_last_day($year, $month))."'"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if (!empty($socid)) { diff --git a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php index 34d34ec3e19..4729231ac8b 100644 --- a/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php +++ b/htdocs/core/modules/reception/doc/doc_generic_reception_odt.modules.php @@ -62,8 +62,7 @@ class doc_generic_reception_odt extends ModelePdfReception { global $conf, $langs, $mysoc; - $langs->load("main"); - $langs->load("companies"); + $langs->loadLangs(array("main", "companies")); $this->db = $db; $this->name = "ODT templates"; @@ -173,6 +172,11 @@ class doc_generic_reception_odt extends ModelePdfReception } $texte .= '
    '; } + // Add input to upload a new template file. + $texte .= '
    '.$langs->trans("UploadNewTemplate").' '; + $texte .= ''; + $texte .= ''; + $texte .= '
    '; $texte .= ''; @@ -223,10 +227,7 @@ class doc_generic_reception_odt extends ModelePdfReception $sav_charset_output = $outputlangs->charset_output; $outputlangs->charset_output = 'UTF-8'; - $outputlangs->load("main"); - $outputlangs->load("dict"); - $outputlangs->load("companies"); - $outputlangs->load("bills"); + $outputlangs->loadLangs(array("main", "dict", "companies", "bills")); if ($conf->reception->dir_output."/reception") { // If $object is id instead of object @@ -288,21 +289,25 @@ class doc_generic_reception_odt extends ModelePdfReception return -1; } - // If BILLING contact defined on invoice, we use it + // If CUSTOMER contact defined on reception, we use it $usecontact = false; - $arrayidcontact = $object->getIdContact('external', 'BILLING'); + $arrayidcontact = $object->getIdContact('external', 'CUSTOMER'); if (count($arrayidcontact) > 0) { $usecontact = true; $result = $object->fetch_contact($arrayidcontact[0]); } // Recipient name + $contactobject = null; if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a BILLING contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { @@ -318,6 +323,7 @@ class doc_generic_reception_odt extends ModelePdfReception '__TOTAL_VAT__' => $object->total_tva ); complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$substitutionarray); $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks @@ -343,6 +349,7 @@ class doc_generic_reception_odt extends ModelePdfReception ); } catch (Exception $e) { $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); return -1; } // After construction $odfHandler->contentXml contains content and @@ -359,67 +366,23 @@ class doc_generic_reception_odt extends ModelePdfReception dol_syslog($e->getMessage(), LOG_INFO); } - // Make substitutions into odt of user info - $tmparray = $this->get_substitutionarray_user($user, $outputlangs); - //var_dump($tmparray); exit; - foreach ($tmparray as $key => $value) { - try { - if (preg_match('/logo$/', $key)) { // Image - //var_dump($value);exit; - if (file_exists($value)) { - $odfHandler->setImage($key, $value); - } else { - $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); - } - } else // Text - { - $odfHandler->setVars($key, $value, true, 'UTF-8'); - } - } catch (OdfException $e) { - dol_syslog($e->getMessage(), LOG_INFO); - } + // Define substitution array + $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object); + $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs); + $array_objet = $this->get_substitutionarray_object($object, $outputlangs); + $array_user = $this->get_substitutionarray_user($user, $outputlangs); + $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs); + $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs); + $array_other = $this->get_substitutionarray_other($outputlangs); + // retrieve contact information for use in object as contact_xxx tags + $array_thirdparty_contact = array(); + if ($usecontact && is_object($contactobject)) { + $array_thirdparty_contact = $this->get_substitutionarray_contact($contactobject, $outputlangs, 'contact'); } - // Make substitutions into odt of mysoc - $tmparray = $this->get_substitutionarray_mysoc($mysoc, $outputlangs); - //var_dump($tmparray); exit; - foreach ($tmparray as $key => $value) { - try { - if (preg_match('/logo$/', $key)) { // Image - //var_dump($value);exit; - if (file_exists($value)) { - $odfHandler->setImage($key, $value); - } else { - $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); - } - } else // Text - { - $odfHandler->setVars($key, $value, true, 'UTF-8'); - } - } catch (OdfException $e) { - dol_syslog($e->getMessage(), LOG_INFO); - } - } - // Make substitutions into odt of thirdparty - $tmparray = $this->get_substitutionarray_thirdparty($socobject, $outputlangs); - foreach ($tmparray as $key => $value) { - try { - if (preg_match('/logo$/', $key)) { // Image - if (file_exists($value)) { - $odfHandler->setImage($key, $value); - } else { - $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); - } - } else // Text - { - $odfHandler->setVars($key, $value, true, 'UTF-8'); - } - } catch (OdfException $e) { - dol_syslog($e->getMessage(), LOG_INFO); - } - } - // Replace tags of object + external modules - $tmparray = $this->get_substitutionarray_reception($object, $outputlangs); + + $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other, $array_thirdparty_contact); complete_substitutions_array($tmparray, $outputlangs, $object); + // Call the ODTSubstitution hook $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray); $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks @@ -441,25 +404,36 @@ class doc_generic_reception_odt extends ModelePdfReception } // Replace tags of lines try { - $listlines = $odfHandler->setSegment('lines'); - foreach ($object->lines as $line) { - $tmparray = $this->get_substitutionarray_reception_lines($line, $outputlangs); - complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); - // Call the ODTSubstitutionLine hook - $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); - $reshook = $hookmanager->executeHooks('ODTSubstitutionLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - foreach ($tmparray as $key => $val) { - try { - $listlines->setVars($key, $val, true, 'UTF-8'); - } catch (OdfException $e) { - dol_syslog($e->getMessage(), LOG_INFO); - } catch (SegmentException $e) { - dol_syslog($e->getMessage(), LOG_INFO); - } - } - $listlines->merge(); + $foundtagforlines = 1; + try { + $listlines = $odfHandler->setSegment('lines'); + } catch (OdfException $e) { + // We may arrive here if tags for lines not present into template + $foundtagforlines = 0; + dol_syslog($e->getMessage(), LOG_INFO); + } + if ($foundtagforlines) { + $linenumber = 0; + foreach ($object->lines as $line) { + $linenumber++; + $tmparray = $this->get_substitutionarray_reception_lines($line, $outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray, 'line'=>$line); + $reshook = $hookmanager->executeHooks('ODTSubstitutionLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + foreach ($tmparray as $key => $val) { + try { + $listlines->setVars($key, $val, true, 'UTF-8'); + } catch (OdfException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } catch (SegmentException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); } - $odfHandler->mergeSegment($listlines); } catch (OdfException $e) { $this->error = $e->getMessage(); dol_syslog($this->error, LOG_WARNING); @@ -486,6 +460,7 @@ class doc_generic_reception_odt extends ModelePdfReception $odfHandler->exportAsAttachedPDF($file); } catch (Exception $e) { $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); return -1; } } else { @@ -493,6 +468,7 @@ class doc_generic_reception_odt extends ModelePdfReception $odfHandler->saveToDisk($file); } catch (Exception $e) { $this->error = $e->getMessage(); + dol_syslog($e->getMessage(), LOG_INFO); return -1; } } @@ -505,6 +481,8 @@ class doc_generic_reception_odt extends ModelePdfReception $odfHandler = null; // Destroy object + $this->result = array('fullpath'=>$file); + return 1; // Success } else { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); diff --git a/htdocs/core/modules/reception/doc/pdf_squille.modules.php b/htdocs/core/modules/reception/doc/pdf_squille.modules.php index 68ceb87ba96..38344a5f486 100644 --- a/htdocs/core/modules/reception/doc/pdf_squille.modules.php +++ b/htdocs/core/modules/reception/doc/pdf_squille.modules.php @@ -972,7 +972,7 @@ class pdf_squille extends ModelePdfReception } // Recipient name - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { $thirdparty = $object->contact; } else { $thirdparty = $object->thirdparty; diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index 8b8069ff34f..6427a6a60a3 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -320,17 +320,22 @@ class doc_generic_odt extends ModeleThirdPartyDoc foreach ($contact_arrray as $array_key => $contact_id) { $res_contact = $contactstatic->fetch($contact_id); - $tmparray = $this->get_substitutionarray_contact($contactstatic, $outputlangs, 'contact'); - foreach ($tmparray as $key => $val) { - try { - $listlines->setVars($key, $val, true, 'UTF-8'); - } catch (OdfException $e) { - dol_syslog($e->getMessage(), LOG_INFO); - } catch (SegmentException $e) { - dol_syslog($e->getMessage(), LOG_INFO); + if ((int) $res_contact > 0) { + $tmparray = $this->get_substitutionarray_contact($contactstatic, $outputlangs, 'contact'); + foreach ($tmparray as $key => $val) { + try { + $listlines->setVars($key, $val, true, 'UTF-8'); + } catch (OdfException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } catch (SegmentException $e) { + dol_syslog($e->getMessage(), LOG_INFO); + } } + $listlines->merge(); + } else { + $this->error = $contactstatic->error; + dol_syslog($this->error, LOG_WARNING); } - $listlines->merge(); } $odfHandler->mergeSegment($listlines); } catch (OdfException $e) { diff --git a/htdocs/core/modules/societe/mod_codeclient_elephant.php b/htdocs/core/modules/societe/mod_codeclient_elephant.php index c18b768a724..67edcb94b8b 100644 --- a/htdocs/core/modules/societe/mod_codeclient_elephant.php +++ b/htdocs/core/modules/societe/mod_codeclient_elephant.php @@ -132,7 +132,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode // Parametrage du prefix customers $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("CustomerCodeModel").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; $texte .= '  '; @@ -140,7 +140,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode // Parametrage du prefix suppliers $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("SupplierCodeModel").'):'; - $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; + $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/societe/mod_codecompta_digitaria.php b/htdocs/core/modules/societe/mod_codecompta_digitaria.php index c4887f01383..91f4bff07c4 100644 --- a/htdocs/core/modules/societe/mod_codecompta_digitaria.php +++ b/htdocs/core/modules/societe/mod_codecompta_digitaria.php @@ -252,17 +252,32 @@ class mod_codecompta_digitaria extends ModeleAccountancyCode */ public function checkIfAccountancyCodeIsAlreadyUsed($db, $code, $type = '') { + global $conf; + if ($type == 'supplier') { - $typethirdparty = 'code_compta_fournisseur'; + if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { + $typethirdparty = 'accountancy_code_supplier'; + } else { + $typethirdparty = 'code_compta_fournisseur'; + } } elseif ($type == 'customer') { - $typethirdparty = 'code_compta'; + if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { + $typethirdparty = 'accountancy_code_customer'; + } else { + $typethirdparty = 'code_compta'; + } } else { $this->error = 'Bad value for parameter type'; return -1; } - $sql = "SELECT ".$typethirdparty." FROM ".MAIN_DB_PREFIX."societe"; - $sql .= " WHERE ".$typethirdparty." = '".$db->escape($code)."'"; + if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { + $sql = "SELECT " . $typethirdparty . " FROM " . MAIN_DB_PREFIX . "societe_perentity"; + $sql .= " WHERE " . $typethirdparty . " = '" . $db->escape($code) . "'"; + } else { + $sql = "SELECT " . $typethirdparty . " FROM " . MAIN_DB_PREFIX . "societe"; + $sql .= " WHERE " . $typethirdparty . " = '" . $db->escape($code) . "'"; + } $resql = $db->query($sql); if ($resql) { diff --git a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php index 2e48160d038..1d02b8003da 100644 --- a/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php +++ b/htdocs/core/modules/stock/doc/doc_generic_stock_odt.modules.php @@ -308,11 +308,14 @@ class doc_generic_stock_odt extends ModelePDFStock // Recipient name $contactobject = null; if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/core/modules/stock/doc/pdf_standard.modules.php b/htdocs/core/modules/stock/doc/pdf_standard.modules.php index 5374245cea4..0c627322d69 100644 --- a/htdocs/core/modules/stock/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/stock/doc/pdf_standard.modules.php @@ -208,8 +208,6 @@ class pdf_standard extends ModelePDFStock // Load traductions files required by page $outputlangs->loadLangs(array("main", "dict", "companies", "bills", "stocks", "orders", "deliveries")); - $nblines = count($object->lines); - if ($conf->stock->dir_output) { // Definition of $dir and $file if ($object->specimen) { diff --git a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php index 3119ffa8dc5..08ccf213b18 100644 --- a/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php +++ b/htdocs/core/modules/supplier_invoice/doc/pdf_canelle.modules.php @@ -133,7 +133,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices $this->db = $db; $this->name = "canelle"; $this->description = $langs->trans('SuppliersInvoiceModel'); - $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template // Page dimensions $this->type = 'pdf'; @@ -1238,7 +1238,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices } // Recipient name - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { $thirdparty = $object->contact; } else { $thirdparty = $mysoc; diff --git a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php index 5fc2737957f..e6838b9c4c4 100644 --- a/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php +++ b/htdocs/core/modules/supplier_invoice/mod_facture_fournisseur_tulip.php @@ -104,7 +104,7 @@ class mod_facture_fournisseur_tulip extends ModeleNumRefSuppliersInvoices $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; $texte .= ''; - if ($conf->global->MAIN_FEATURE_LEVEL >= 2) { + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { // Parametrage du prefix des replacement $texte .= ''.$langs->trans("Mask").' ('.$langs->trans("InvoiceReplacement").'):'; $texte .= ''.$form->textwithpicto('', $tooltip, 1, 1).''; diff --git a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php index 49ba1ec6cdf..dfb05d2d55f 100644 --- a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php +++ b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php @@ -298,11 +298,14 @@ class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders // Recipient name $contactobject = null; if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php index 3e04844119b..436017cda0a 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_cornas.modules.php @@ -1407,7 +1407,7 @@ class pdf_cornas extends ModelePDFSuppliersOrders } // Recipient name - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { $thirdparty = $object->contact; } else { $thirdparty = $object->thirdparty; diff --git a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php index bb12b19c829..76d264f2444 100644 --- a/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/doc/pdf_muscadet.modules.php @@ -135,7 +135,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $this->db = $db; $this->name = "muscadet"; $this->description = $langs->trans('SuppliersCommandModelMuscadet'); - $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template // Page size for A4 format $this->type = 'pdf'; @@ -1127,7 +1127,9 @@ class pdf_muscadet extends ModelePDFSuppliersOrders global $langs, $conf, $mysoc; $ltrdirection = 'L'; - if ($outputlangs->trans("DIRECTION") == 'rtl') $ltrdirection = 'R'; + if ($outputlangs->trans("DIRECTION") == 'rtl') { + $ltrdirection = 'R'; + } // Load translation files required by the page $outputlangs->loadLangs(array("main", "orders", "companies", "bills", "sendings")); @@ -1314,7 +1316,7 @@ class pdf_muscadet extends ModelePDFSuppliersOrders } // Recipient name - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { $thirdparty = $object->contact; } else { $thirdparty = $object->thirdparty; diff --git a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php index b6da2d4c294..5b9ffa062a3 100644 --- a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php @@ -132,7 +132,7 @@ class pdf_standard extends ModelePDFSuppliersPayments $this->db = $db; $this->name = "standard"; $this->description = $langs->trans('DocumentModelStandardPDF'); - $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template // Page size for A4 format $this->type = 'pdf'; @@ -812,6 +812,25 @@ class pdf_standard extends ModelePDFSuppliersPayments $pdf->SetFont('', '', $default_font_size - 1); $pdf->SetXY($posx + 2, $posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); + + // Show default IBAN account + $sql = "SELECT iban_prefix"; + $sql .= " FROM ".MAIN_DB_PREFIX."societe_rib as rib"; + $sql .= " WHERE fk_soc = ".($object->thirdparty->id); + $sql .= " AND rib.default_rib = 1"; + $sql .= " AND rib.type = 'ban'"; + $sql .= " LIMIT 1"; + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + $iban = $obj->iban_prefix; + } + + if (!empty($iban)) { + $pdf->SetFont('', '', $default_font_size - 1); + $pdf->SetXY($posx + 2, $posy + 15); + $pdf->MultiCell($widthrecbox, 4, $langs->trans("IBAN").': '.$iban, 0, 'L'); + } } } diff --git a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php index 8cd572a1bcf..18e5a210aa1 100644 --- a/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/doc_generic_supplier_proposal_odt.modules.php @@ -332,11 +332,14 @@ class doc_generic_supplier_proposal_odt extends ModelePDFSupplierProposal // Recipient name $contactobject = null; if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a BILLING contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index 5bd9b8cf339..c2ab5c99ea6 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -132,7 +132,7 @@ class pdf_aurore extends ModelePDFSupplierProposal $this->db = $db; $this->name = "aurore"; $this->description = $langs->trans('DocModelAuroreDescription'); - $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template + $this->update_main_doc_field = 1; // Save the name of generated file as the main doc when generating a doc with this template // Page size for A4 format $this->type = 'pdf'; @@ -1418,7 +1418,7 @@ class pdf_aurore extends ModelePDFSupplierProposal // Recipient name if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($usecontact && ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { $socname = $object->contact; } else { $socname = $object->thirdparty; diff --git a/htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php b/htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php index 82ce006447e..e20cbf44cf7 100644 --- a/htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php +++ b/htdocs/core/modules/ticket/doc/doc_generic_ticket_odt.modules.php @@ -293,11 +293,14 @@ class doc_generic_ticket_odt extends ModelePDFTicket // Recipient name if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php b/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php index 7e07539aa8e..050eb43d44a 100644 --- a/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php +++ b/htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php @@ -325,7 +325,7 @@ class doc_generic_user_odt extends ModelePDFUser // Recipient name if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { $socobject = $object->contact; } else { $socobject = $object->thirdparty; diff --git a/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php b/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php index cf91120d3f8..134c5e00362 100644 --- a/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php +++ b/htdocs/core/modules/usergroup/doc/doc_generic_usergroup_odt.modules.php @@ -315,11 +315,14 @@ class doc_generic_usergroup_odt extends ModelePDFUserGroup // Recipient name if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/core/modules/workstation/mod_workstation_advanced.php b/htdocs/core/modules/workstation/mod_workstation_advanced.php index 2f1a8ae9d71..6611f8d926e 100755 --- a/htdocs/core/modules/workstation/mod_workstation_advanced.php +++ b/htdocs/core/modules/workstation/mod_workstation_advanced.php @@ -27,7 +27,7 @@ * \brief File containing class for advanced numbering model of Workstation */ -require_once DOL_DOCUMENT_ROOT . '/core/modules/workstation/modules_workstation.php'; +require_once DOL_DOCUMENT_ROOT.'/core/modules/workstation/modules_workstation.php'; /** diff --git a/htdocs/core/multicompany_page.php b/htdocs/core/multicompany_page.php new file mode 100644 index 00000000000..239e5c46392 --- /dev/null +++ b/htdocs/core/multicompany_page.php @@ -0,0 +1,147 @@ + + * + * This file is a modified version of datepicker.php from phpBSM to fix some + * bugs, to add new features and to dramatically increase speed. + * + * 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/multicompany_page.php + * \brief File to return a page with the list of all entities user can switch to + */ + +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Not disabled cause need to load personalized language +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); // Not disabled cause need to do translations +if (!defined('NOCSRFCHECK')) { + define('NOCSRFCHECK', 1); +} +if (!defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', 1); +} +//if (! defined('NOLOGIN')) define('NOLOGIN',1); // Not disabled cause need to load personalized language +if (!defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', 1); +} +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML',1); + +require_once '../main.inc.php'; + +$action = GETPOST('action', 'aZ09'); +$entityid = GETPOST('entity', 'int'); +$backtourl = GETPOST('backtourl'); +if (empty($backtourl)) { + $backtourl = DOL_URL_ROOT; +} + +if (GETPOST('lang', 'aZ09')) { + $langs->setDefaultLang(GETPOST('lang', 'aZ09')); // If language was forced on URL by the main.inc.php +} + +$langs->load("main"); + +$right = ($langs->trans("DIRECTION") == 'rtl' ? 'left' : 'right'); +$left = ($langs->trans("DIRECTION") == 'rtl' ? 'right' : 'left'); + + + +/* + * Actions + */ + +if (GETPOST('acction', 'aZ') == 'switchentity') { + if (is_object($mc)) { + $mc->switchEntity($entityid); + } + + header("Location: ".$backtourl); + exit(0); +} + + + +/* + * View + */ + +$title = $langs->trans("Multicompanies"); + +// URL http://mydolibarr/core/multicompany_page?dol_use_jmobile=1 can be used for tests +$head = ''."\n"; +$arrayofjs = array(); +$arrayofcss = array(); +top_htmlhead($head, $title, 0, 0, $arrayofjs, $arrayofcss); + + +print ''."\n"; +print '
    '; +//print '
    '; + + +if (empty($conf->multicompany->enabled)) { + $langs->load("admin"); + $bookmarkList .= '
    '.$langs->trans("WarningModuleNotActive", $langs->transnoentitiesnoconv("MultiCompany")).''; + $bookmarkList .= '

    '; +} else { + // Instantiate hooks of thirdparty module + $hookmanager->initHooks(array('multicompany')); + + // Define $bookmarks + $multicompanyList = ''; + $searchForm = ''; + + + if (is_object($mc)) { + $listofentities = $mc->getEntitiesList($user->login, false, true); + } + + foreach ($listofentities as $entityid => $entitycursor) { + $url = DOL_URL_ROOT.'/core/multicompany_page.php?action=switchentity&token='.newToken().'&entity='.((int) $entityid).($backtourl ? '&backtourl='.urlencode($backtourl) : ''); + $multicompanyList .= ''; + $multicompanyList .= dol_escape_htmltag($entitycursor); + $multicompanyList .= ''; + } + $multicompanyList .= '
    '; + + $searchForm .= ''; + + + // Execute hook printBookmarks + $parameters = array('multicompany'=>$multicompanyList); + $reshook = $hookmanager->executeHooks('printMultiCompanyEntities', $parameters); // Note that $action and $object may have been modified by some hooks + if (empty($reshook)) { + $multicompanyList .= $hookmanager->resPrint; + } else { + $multicompanyList = $hookmanager->resPrint; + } + + + print "\n"; + print "\n"; + print '
    '; + print ''; + print '
    '."\n"; + print $multicompanyList; + print '
    '."\n"; + print '
    '; + print "\n\n"; +} + +print ''; +print ''."\n"; + +$db->close(); diff --git a/htdocs/core/photos_resize.php b/htdocs/core/photos_resize.php index 374f381c098..7b2feef5c72 100644 --- a/htdocs/core/photos_resize.php +++ b/htdocs/core/photos_resize.php @@ -68,7 +68,7 @@ if ($modulepart == 'produit' || $modulepart == 'product' || $modulepart == 'serv $accessallowed = 1; } elseif ($modulepart == 'member') { $result = restrictedArea($user, 'adherent', $id, '', '', 'fk_soc', 'rowid'); - if (!$user->rights->adherent->lire) { + if (empty($user->rights->adherent->lire)) { accessforbidden(); } $accessallowed = 1; @@ -86,7 +86,7 @@ if ($modulepart == 'produit' || $modulepart == 'product' || $modulepart == 'serv $accessallowed = 1; } elseif ($modulepart == 'bank') { $result = restrictedArea($user, 'banque', $id, 'bank_account'); - if (!$user->rights->banque->lire) { + if (empty($user->rights->banque->lire)) { accessforbidden(); } $accessallowed = 1; @@ -98,7 +98,7 @@ if ($modulepart == 'produit' || $modulepart == 'product' || $modulepart == 'serv $accessallowed = 1; } elseif ($modulepart == 'facture_fourn' || $modulepart == 'facture_fournisseur') { $result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture'); - if (!$user->rights->fournisseur->facture->lire) { + if (empty($user->rights->fournisseur->facture->lire)) { accessforbidden(); } $accessallowed = 1; @@ -475,7 +475,7 @@ if ($action == 'confirm_crop') { * View */ -$title= $langs->trans("ImageEditor"); +$title = $langs->trans("ImageEditor"); $morejs = array('/includes/jquery/plugins/jcrop/js/jquery.Jcrop.min.js', '/core/js/lib_photosresize.js'); $morecss = array('/includes/jquery/plugins/jcrop/css/jquery.Jcrop.css'); diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php index 2f1c113fcf5..0c1d34efa08 100644 --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php @@ -93,7 +93,10 @@ if (isset($extrafields->attributes[$elementtype]['type']) && is_array($extrafiel // Key print "".dol_escape_htmltag($key)."\n"; // Type - print "".dol_escape_htmltag($type2label[$extrafields->attributes[$elementtype]['type'][$key]])."\n"; + $typetoshow = $type2label[$extrafields->attributes[$elementtype]['type'][$key]]; + print ''; + print dol_escape_htmltag($typetoshow); + print "\n"; // Size print ''.dol_escape_htmltag($extrafields->attributes[$elementtype]['size'][$key])."\n"; // Computed field @@ -141,9 +144,9 @@ if (isset($extrafields->attributes[$elementtype]['type']) && is_array($extrafiel } print ''; - print ''; + print ''; print $langs->trans("None"); - print ''; + print ''; print ''; } diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index 88c643c641d..61428170f50 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -61,12 +61,13 @@ $(document).ready(function(){ console.log("tableDND onDrop"); console.log(decodeURI($("#").tableDnDSerialize())); $('# tr[data-element=extrafield]').attr('id', ''); // Set extrafields id to empty value in order to ignore them in tableDnDSerialize function + $('# tr[data-ignoreidfordnd=1]').attr('id', ''); // Set id to empty value in order to ignore them in tableDnDSerialize function var roworder = cleanSerialize(decodeURI($("#").tableDnDSerialize())); var table_element_line = ""; var fk_element = ""; var element_id = ""; var filepath = ""; - var token = ""; // We use old 'token' and not 'newtoken' for Ajax call because the ajax page has the NOTOKENRENEWAL constant set. + var token = ""; // We use old 'token' and not 'newtoken' for Ajax call because the ajax page has the NOTOKENRENEWAL constant set. $.post("/core/ajax/row.php", { roworder: roworder, diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index 143d8d5536c..7cc95c81fe0 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -146,10 +146,6 @@ if ($action == 'presend') { $formmail->trackid = $trackid; - if (!empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) { // If bit 2 is set - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail = dolAddEmailTrackId($formmail->frommail, $trackid); - } $formmail->withfrom = 1; // Fill list of recipient with email inside <>. @@ -184,7 +180,7 @@ if ($action == 'presend') { $listeuser = array(); $fuserdest = new User($db); - $result = $fuserdest->fetchAll('ASC', 't.lastname', 0, 0, array('customsql'=>'t.statut=1 AND t.employee=1 AND t.email IS NOT NULL AND t.email<>\'\''), 'AND', true); + $result = $fuserdest->fetchAll('ASC', 't.lastname', 0, 0, array('customsql'=>"t.statut=1 AND t.employee=1 AND t.email IS NOT NULL AND t.email <> ''"), 'AND', true); if ($result > 0 && is_array($fuserdest->users) && count($fuserdest->users) > 0) { foreach ($fuserdest->users as $uuserdest) { $listeuser[$uuserdest->id] = $uuserdest->user_get_property($uuserdest->id, 'email'); @@ -214,6 +210,9 @@ if ($action == 'presend') { } // Make substitution in email content + if ($object) { + $formmail->setSubstitFromObject($object, $langs); + } $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, $arrayoffamiliestoexclude, $object); $substitutionarray['__CHECK_READ__'] = (is_object($object) && is_object($object->thirdparty)) ? '' : ''; $substitutionarray['__PERSONALIZED__'] = ''; // deprecated diff --git a/htdocs/core/tpl/commonfields_edit.tpl.php b/htdocs/core/tpl/commonfields_edit.tpl.php index abf3144de8f..39103fdbb0a 100644 --- a/htdocs/core/tpl/commonfields_edit.tpl.php +++ b/htdocs/core/tpl/commonfields_edit.tpl.php @@ -86,7 +86,7 @@ foreach ($object->fields as $key => $val) { $value = GETPOSTISSET($key) ? GETPOST($key, 'alpha') : $object->$key; } //var_dump($val.' '.$key.' '.$value); - if ($val['noteditable']) { + if (!empty($val['noteditable'])) { print $object->showOutputField($val, $key, $value, '', '', '', 0); } else { if ($key == 'lang') { diff --git a/htdocs/core/tpl/commonfields_view.tpl.php b/htdocs/core/tpl/commonfields_view.tpl.php index a9f4e084173..29bf3943cea 100644 --- a/htdocs/core/tpl/commonfields_view.tpl.php +++ b/htdocs/core/tpl/commonfields_view.tpl.php @@ -58,7 +58,7 @@ foreach ($object->fields as $key => $val) { $value = $object->$key; print ' 0) print ' fieldrequired'; // No fieldrequired on the view output if ($val['type'] == 'text' || $val['type'] == 'html') { print ' tdtop'; @@ -140,7 +140,7 @@ foreach ($object->fields as $key => $val) { $value = $object->$key; print ' 0) print ' fieldrequired'; // No fieldrequired inthe view output if ($val['type'] == 'text' || $val['type'] == 'html') { print ' tdtop'; @@ -156,7 +156,7 @@ foreach ($object->fields as $key => $val) { if ($val['type'] == 'text') { print ' wordbreak'; } - if ($val['cssview']) { + if (!empty($val['cssview'])) { print ' '.$val['cssview']; } print '">'; diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index 1257d473ced..3def83f4e0d 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -135,19 +135,19 @@ if ($permission) { + '; } ?> -
    +
    socid) ? 0 : $object->socid); $selectedCompany = $formcompany->selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', '', 0, '', 'minwidth300imp'); ?>
    - -
    +
    selectcontacts(($selectedCompany > 0 ? $selectedCompany : -1), '', 'contactid', 3, '', '', 1, 'minwidth100imp'); + print img_object('', 'contact', 'class="pictofixedwidth"').$form->selectcontacts(($selectedCompany > 0 ? $selectedCompany : -1), '', 'contactid', 3, '', '', 1, 'minwidth100imp widthcentpercentminusxx maxwidth400'); $nbofcontacts = $form->num; $newcardbutton = ''; @@ -157,7 +157,7 @@ if ($permission) { print $newcardbutton; ?>
    -
    +
    element == 'shipping' || $object->element == 'reception') && is_object($objectsrc)) { @@ -303,12 +303,12 @@ foreach ($list as $entry) { if ($permission) { $href = $_SERVER["PHP_SELF"]; - $href .= '?id='.$object->id; + $href .= '?id='.((int) $object->id); $href .= '&action=deletecontact&token='.newToken(); - $href .= '&lineid='.$entry->id; + $href .= '&lineid='.((int) $entry->id); - print ""; - print ""; + print ''; + print ''; print img_picto($langs->trans("Unlink"), "unlink"); print ""; print ""; diff --git a/htdocs/core/tpl/document_actions_post_headers.tpl.php b/htdocs/core/tpl/document_actions_post_headers.tpl.php index 4ec69efbac8..42276c24234 100644 --- a/htdocs/core/tpl/document_actions_post_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_post_headers.tpl.php @@ -63,10 +63,10 @@ if (in_array($modulepart, array('product', 'produit', 'societe', 'user', 'ticket /* - * Confirm form to delete + * Confirm form to delete a file */ -if ($action == 'delete') { +if ($action == 'deletefile') { $langs->load("companies"); // Need for string DeleteFile+ConfirmDeleteFiles print $form->formconfirm( $_SERVER["PHP_SELF"].'?id='.$object->id.'&urlfile='.urlencode(GETPOST("urlfile")).'&linkid='.GETPOST('linkid', 'int').(empty($param) ? '' : $param), diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php index 7d547d52dea..80d6cd7da56 100644 --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php @@ -19,13 +19,8 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield foreach ($extrafields->attributes[$extrafieldsobjectkey]['label'] as $key => $val) { if (!empty($arrayfields[$extrafieldsobjectprefix.$key]['checked'])) { - $align = $extrafields->getAlignFlag($key, $extrafieldsobjectkey); - print ''; + $cssclass = $extrafields->getAlignFlag($key, $extrafieldsobjectkey); + $tmpkey = 'options_'.$key; if (in_array($extrafields->attributes[$extrafieldsobjectkey]['type'][$key], array('date', 'datetime', 'timestamp')) && !is_numeric($obj->$tmpkey)) { @@ -47,9 +42,20 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield //var_dump($value); } - print $extrafields->showOutputField($key, $value, '', $extrafieldsobjectkey); + $valuetoshow = $extrafields->showOutputField($key, $value, '', $extrafieldsobjectkey); + $title = dol_string_nohtmltag($valuetoshow); + + print ''; + print $valuetoshow; print ''; + if (!$i) { + if (empty($totalarray)) { + $totalarray['nbfield'] = 0; + } $totalarray['nbfield']++; } @@ -62,7 +68,7 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield $totalarray['totalizable'][$key]['total'] += $obj->$tmpkey; } } - if (!empty($val['isameasure'])) { + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = $extrafieldsobjectprefix.$tmpkey; } diff --git a/htdocs/core/tpl/extrafields_list_search_param.tpl.php b/htdocs/core/tpl/extrafields_list_search_param.tpl.php index 56652b87dd3..7e58e106882 100644 --- a/htdocs/core/tpl/extrafields_list_search_param.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_param.tpl.php @@ -18,17 +18,17 @@ if (!empty($search_array_options) && is_array($search_array_options)) { // $extr if (is_array($val) && array_key_exists('start', $val) && array_key_exists('end', $val)) { // date range from list filters is stored as array('start' => , 'end' => ) // start date - $param .= '&' . $search_options_pattern.$tmpkey.'_startyear=' . dol_print_date($val['start'], '%Y'); - $param .= '&' . $search_options_pattern.$tmpkey.'_startmonth=' . dol_print_date($val['start'], '%m'); - $param .= '&' . $search_options_pattern.$tmpkey.'_startday=' . dol_print_date($val['start'], '%d'); - $param .= '&' . $search_options_pattern.$tmpkey.'_starthour=' . dol_print_date($val['start'], '%H'); - $param .= '&' . $search_options_pattern.$tmpkey.'_startmin=' . dol_print_date($val['start'], '%M'); + $param .= '&'.$search_options_pattern.$tmpkey.'_startyear='.dol_print_date($val['start'], '%Y'); + $param .= '&'.$search_options_pattern.$tmpkey.'_startmonth='.dol_print_date($val['start'], '%m'); + $param .= '&'.$search_options_pattern.$tmpkey.'_startday='.dol_print_date($val['start'], '%d'); + $param .= '&'.$search_options_pattern.$tmpkey.'_starthour='.dol_print_date($val['start'], '%H'); + $param .= '&'.$search_options_pattern.$tmpkey.'_startmin='.dol_print_date($val['start'], '%M'); // end date - $param .= '&' . $search_options_pattern.$tmpkey.'_endyear=' . dol_print_date($val['end'], '%Y'); - $param .= '&' . $search_options_pattern.$tmpkey.'_endmonth=' . dol_print_date($val['end'], '%m'); - $param .= '&' . $search_options_pattern.$tmpkey.'_endday=' . dol_print_date($val['end'], '%d'); - $param .= '&' . $search_options_pattern.$tmpkey.'_endhour=' . dol_print_date($val['end'], '%H'); - $param .= '&' . $search_options_pattern.$tmpkey.'_endmin=' . dol_print_date($val['end'], '%M'); + $param .= '&'.$search_options_pattern.$tmpkey.'_endyear='.dol_print_date($val['end'], '%Y'); + $param .= '&'.$search_options_pattern.$tmpkey.'_endmonth='.dol_print_date($val['end'], '%m'); + $param .= '&'.$search_options_pattern.$tmpkey.'_endday='.dol_print_date($val['end'], '%d'); + $param .= '&'.$search_options_pattern.$tmpkey.'_endhour='.dol_print_date($val['end'], '%H'); + $param .= '&'.$search_options_pattern.$tmpkey.'_endmin='.dol_print_date($val['end'], '%M'); $val = ''; } if ($val != '') { diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 3f2ab773b06..b5656c89339 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -125,7 +125,7 @@ if (empty($reshook) && isset($extrafields->attributes[$object->table_element]['l $lastseparatorkeyfound = $tmpkeyextra; } else { - print 'id) ? '_'.$object->id : ''); /*if ($extrafields_collapse_num && $extrafields_collapse_num_old && $extrafields_collapse_num != $extrafields_collapse_num_old) { print ' trextrafields_collapse_new'; }*/ @@ -194,6 +194,9 @@ if (empty($reshook) && isset($extrafields->attributes[$object->table_element]['l if ($object->element == 'contact') { $permok = $user->rights->societe->contact->creer; } + if ($object->element == 'salary') { + $permok = $user->rights->salaries->read; + } $isdraft = ((isset($object->statut) && $object->statut == 0) || (isset($object->status) && $object->status == 0)); if (($isdraft || !empty($extrafields->attributes[$object->table_element]['alwayseditable'][$tmpkeyextra])) @@ -205,7 +208,7 @@ if (empty($reshook) && isset($extrafields->attributes[$object->table_element]['l $fieldid = 'socid'; } - print ''.img_edit().''; + print ''.img_edit().''; } print ''; print ''; @@ -216,18 +219,18 @@ if (empty($reshook) && isset($extrafields->attributes[$object->table_element]['l // Convert date into timestamp format if (in_array($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra], array('date'))) { - $datenotinstring = $object->array_options['options_'.$tmpkeyextra]; + $datenotinstring = empty($object->array_options['options_'.$tmpkeyextra]) ? '' : $object->array_options['options_'.$tmpkeyextra]; // print 'X'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.'x'; - if (!is_numeric($object->array_options['options_'.$tmpkeyextra])) { // For backward compatibility + if (!empty($object->array_options['options_'.$tmpkeyextra]) && !is_numeric($object->array_options['options_'.$tmpkeyextra])) { // For backward compatibility $datenotinstring = $db->jdate($datenotinstring); } //print 'x'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); $value = GETPOSTISSET("options_".$tmpkeyextra) ? dol_mktime(12, 0, 0, GETPOST("options_".$tmpkeyextra."month", 'int'), GETPOST("options_".$tmpkeyextra."day", 'int'), GETPOST("options_".$tmpkeyextra."year", 'int')) : $datenotinstring; } if (in_array($extrafields->attributes[$object->table_element]['type'][$tmpkeyextra], array('datetime'))) { - $datenotinstring = $object->array_options['options_'.$tmpkeyextra]; + $datenotinstring = empty($object->array_options['options_'.$tmpkeyextra]) ? '' : $object->array_options['options_'.$tmpkeyextra]; // print 'X'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.'x'; - if (!is_numeric($object->array_options['options_'.$tmpkeyextra])) { // For backward compatibility + if (!empty($object->array_options['options_'.$tmpkeyextra]) && !is_numeric($object->array_options['options_'.$tmpkeyextra])) { // For backward compatibility $datenotinstring = $db->jdate($datenotinstring); } //print 'x'.$object->array_options['options_' . $tmpkeyextra].'-'.$datenotinstring.' - '.dol_print_date($datenotinstring, 'dayhour'); diff --git a/htdocs/core/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php index 57a95c48ece..e776388ac53 100644 --- a/htdocs/core/tpl/filemanager.tpl.php +++ b/htdocs/core/tpl/filemanager.tpl.php @@ -233,7 +233,7 @@ if ($action == 'convertimgwebp' && $permtoadd) { if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg_match('/refresh/i', $action) || $action == 'delete') { $langs->load("ecm"); - print ''."\n"; + print '
    '."\n"; print ''."\n"; print ''."\n"; diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 7b20e7209f7..9f2f2f68712 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -57,7 +57,7 @@ if (!empty($conf->dol_use_jmobile)) { $conf->use_javascript_ajax = 1; } -$php_self = dol_escape_htmltag($_SERVER['PHP_SELF']); +$php_self = empty($php_self) ? dol_escape_htmltag($_SERVER['PHP_SELF']) : $php_self; $php_self .= dol_escape_htmltag($_SERVER["QUERY_STRING"]) ? '?'.dol_escape_htmltag($_SERVER["QUERY_STRING"]) : ''; if (!preg_match('/mainmenu=/', $php_self)) { $php_self .= (preg_match('/\?/', $php_self) ? '&' : '?').'mainmenu=home'; @@ -310,7 +310,7 @@ if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->fil print ''.$langs->trans("LoginUsingOpenID").''; } else { $langs->load("errors"); - print ''.$langs->trans("ErrorOpenIDSetupNotComplete", 'MAIN_AUTHENTICATION_OPENID_URL').''; + print ''.$langs->trans("ErrorOpenIDSetupNotComplete", 'MAIN_AUTHENTICATION_OPENID_URL').''; } echo ''; @@ -346,7 +346,7 @@ if (!empty($conf->global->MAIN_EASTER_EGG_COMMITSTRIP)) { $resgetcommitstrip = getURLContent("https://www.commitstrip.com/en/feed/"); } if ($resgetcommitstrip && $resgetcommitstrip['http_code'] == '200') { - $xml = simplexml_load_string($resgetcommitstrip['content']); + $xml = simplexml_load_string($resgetcommitstrip['content'], 'SimpleXMLElement', LIBXML_NOCDATA|LIBXML_NONET); $little = $xml->channel->item[0]->children('content', true); print preg_replace('/width="650" height="658"/', '', $little->encoded); } diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index 4d715ed8797..e1f56974483 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -38,17 +38,17 @@ if ($massaction == 'predelete') { if ($massaction == 'preaffecttag') { require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $categ = new Categorie($db); - $categ_types=array(); - $categ_type_array=$categ->getMapList(); + $categ_types = array(); + $categ_type_array = $categ->getMapList(); foreach ($categ_type_array as $categdef) { - if (isset($object) && $categdef['obj_table']==$object->table_element) { + if (isset($object) && $categdef['obj_table'] == $object->table_element) { if (!array_key_exists($categdef['code'], $categ_types)) { - $categ_types[$categdef['code']] = array('code'=>$categdef['code'],'label'=>$langs->trans($categdef['obj_class'])); + $categ_types[$categdef['code']] = array('code'=>$categdef['code'], 'label'=>$langs->trans($categdef['obj_class'])); } } - if (isset($objecttmp) && $categdef['obj_table']==$objecttmp->table_element) { + if (isset($objecttmp) && $categdef['obj_table'] == $objecttmp->table_element) { if (!array_key_exists($categdef['code'], $categ_types)) { - $categ_types[$categdef['code']] = array('code'=>$categdef['code'],'label'=>$langs->trans($categdef['obj_class'])); + $categ_types[$categdef['code']] = array('code'=>$categdef['code'], 'label'=>$langs->trans($categdef['obj_class'])); } } } @@ -57,12 +57,12 @@ if ($massaction == 'preaffecttag') { if (!empty($categ_types)) { foreach ($categ_types as $categ_type) { $cate_arbo = $form->select_all_categories($categ_type['code'], null, 'parent', null, null, 1); - $formquestion[]=array('type' => 'other', + $formquestion[] = array('type' => 'other', 'name' => 'affecttag_'.$categ_type['code'], 'label' => $langs->trans("Tag").' '.$categ_type['label'], 'value' => $form->multiselectarray('contcats_'.$categ_type['code'], $cate_arbo, GETPOST('contcats_'.$categ_type['code'], 'array'), null, null, null, null, '60%')); } - $formquestion[]=array('type' => 'other', + $formquestion[] = array('type' => 'other', 'name' => 'affecttag_type', 'label' => '', 'value' => ''); @@ -99,12 +99,9 @@ if ($massaction == 'presend') { print ''; - include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; - $formmail = new FormMail($db); - print dol_get_fiche_head(null, '', ''); - // Cree l'objet formulaire mail + // Create mail form include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); $formmail->withform = -1; @@ -114,10 +111,6 @@ if ($massaction == 'presend') { $formmail->fromid = $user->id; } $formmail->trackid = $trackid; - if (!empty($conf->global->MAIN_EMAIL_ADD_TRACK_ID) && ($conf->global->MAIN_EMAIL_ADD_TRACK_ID & 2)) { // If bit 2 is set - include DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - $formmail->frommail = dolAddEmailTrackId($formmail->frommail, $trackid); - } $formmail->withfrom = 1; $liste = $langs->trans("AllRecipientSelected", count($arrayofselected)); if (count($listofselectedthirdparties) == 1) { // Only 1 different recipient selected, we can suggest contacts @@ -154,7 +147,7 @@ if ($massaction == 'presend') { // $formmail->withfile = 2; Not yet supported in mass action $formmail->withmaindocfile = 1; // Add a checkbox "Attach also main document" if ($objecttmp->element != 'societe') { - $formmail->withfile = ''.$langs->trans("OnlyPDFattachmentSupported").''; + $formmail->withfile = ''.$langs->trans("OnlyPDFattachmentSupported").''; $formmail->withmaindocfile = - 1; // Add a checkbox "Attach also main document" but not checked by default } $formmail->withbody = 1; diff --git a/htdocs/core/tpl/object_discounts.tpl.php b/htdocs/core/tpl/object_discounts.tpl.php index df565aea6f9..38e1967c11b 100644 --- a/htdocs/core/tpl/object_discounts.tpl.php +++ b/htdocs/core/tpl/object_discounts.tpl.php @@ -1,5 +1,6 @@ + * Copyright (C) 2021 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 @@ -88,7 +89,7 @@ if ($absolute_discount > 0) { // Is there credit notes availables ? if ($absolute_creditnote > 0) { // If validated, we show link "add credit note to payment" - if ($cannotApplyDiscount || !$isInvoice || $isNewObject || $object->statut != $objclassname::STATUS_VALIDATED || $object->type == $objclassname::TYPE_CREDIT_NOTE) { + if (!empty($cannotApplyDiscount) || !$isInvoice || $isNewObject || $object->statut != $objclassname::STATUS_VALIDATED || $object->type == $objclassname::TYPE_CREDIT_NOTE) { $translationKey = !empty($discount_type) ? 'HasCreditNoteFromSupplier' : 'CompanyHasCreditNote'; $text = $langs->trans($translationKey, price($absolute_creditnote), $langs->transnoentities("Currency".$conf->currency)).'.'; diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index f978a436354..aeac5d038f3 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -68,6 +68,7 @@ if (!empty($conf->multicurrency->enabled) && $this->multicurrency_code != $conf- if (in_array($object->element, array('propal', 'commande', 'order', 'facture', 'facturerec', 'invoice', 'supplier_proposal', 'order_supplier', 'invoice_supplier'))) { $colspan++; // With this, there is a column move button } + //print $object->element; // Lines for extrafield $objectline = null; @@ -673,15 +674,27 @@ if (!empty($usemargins) && $user->rights->margins->creer) { $("#prod_entry_mode_predef").click(); + if (in_array($this->table_element_line, array('propaldet', 'commandedet', 'facturedet'))) { ?> + $("#date_start, #date_end").focusout(function() { + let type = $(this).attr('type'); + let mandatoryP = $(this).attr('mandatoryperiod'); + if (type == 1 && mandatoryP == 1) { + if ($(this).val() == '' && !$(this).hasClass('inputmandatory')) { + $(this).addClass('inputmandatory'); + }else{ + $(this).removeClass('inputmandatory'); + } + } + }); + /* When changing predefined product, we reload list of supplier prices required for margin combo */ $("#idprod, #idprodfournprice").change(function() { console.log("Call method change() after change on #idprod or #idprodfournprice (senderissupplier=). this.val = "+$(this).val()); setforpredef(); // TODO Keep vat combo visible and set it to first entry into list that match result of get_default_tva - jQuery('#trlinefordates').show(); rights->margins->creer) { { 'id': $(this).val(), 'socid': socid; ?> }, function(data) { console.log("Load unit price end, we got value "+data.price_ht); + + $('#date_start').removeAttr('type'); + $('#date_end').removeAttr('type'); + $('#date_start').attr('type', data.type); + $('#date_end').attr('type', data.type); + + $('#date_start').removeAttr('mandatoryperiod'); + $('#date_end').removeAttr('mandatoryperiod'); + $('#date_start').attr('mandatoryperiod', data.mandatory_period); + $('#date_end').attr('mandatoryperiod', data.mandatory_period); + + // service and we setted mandatory_period to true + if (data.mandatory_period == 1 && data.type == 1) { + jQuery('#date_start').addClass('inputmandatory'); + jQuery('#date_end').addClass('inputmandatory'); + }else{ + jQuery('#date_start').removeClass('inputmandatory'); + jQuery('#date_end').removeClass('inputmandatory'); + } + jQuery("#price_ht").val(data.price_ht); global->PRODUIT_AUTOFILL_DESC) && $conf->global->PRODUIT_AUTOFILL_DESC == 1) { @@ -984,6 +1017,7 @@ if (!empty($usemargins) && $user->rights->margins->creer) { jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").show(); jQuery("#fournprice_predef").hide(); } + function setforpredef() { console.log("Call setforpredef. We hide some fields and show dates"); jQuery("#select_type").val(-1); diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index 9094daaa2d1..d1b19495429 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -296,7 +296,8 @@ $coldisplay++; echo ''; } $coldisplay++; - } elseif (!empty($conf->global->DISPLAY_MARK_RATES)) { + } + if (!empty($conf->global->DISPLAY_MARK_RATES)) { $mark_rate = (GETPOSTISSET("np_markRate") ? GETPOST("np_markRate", 'alpha', 2) : price($line->marque_tx)); // if credit note, dont allow to modify margin if ($line->subprice < 0) { @@ -333,9 +334,18 @@ $coldisplay++; if (isset($conf->global->MAIN_DEFAULT_DATE_START_HOUR)) { print 'jQuery("#date_starthour").val("'.$conf->global->MAIN_DEFAULT_DATE_START_HOUR.'");'; } + + if (isset($conf->global->MAIN_DEFAULT_DATE_START_MIN)) { print 'jQuery("#date_startmin").val("'.$conf->global->MAIN_DEFAULT_DATE_START_MIN.'");'; } + + $res = $line->fetch_product(); + if ($res > 0 ) { + if ( $line->product->isMandatoryPeriod() && $line->product->isService()) { + print 'jQuery("#date_start").addClass("error");'; + } + } } if (!$line->date_end) { if (isset($conf->global->MAIN_DEFAULT_DATE_END_HOUR)) { @@ -344,6 +354,14 @@ $coldisplay++; if (isset($conf->global->MAIN_DEFAULT_DATE_END_MIN)) { print 'jQuery("#date_endmin").val("'.$conf->global->MAIN_DEFAULT_DATE_END_MIN.'");'; } + + $res = $line->fetch_product(); + // on doit fetch le product là !!! pour connaître le type + if ($res > 0 ) { + if ($line->product->isMandatoryperiod() && $line->product->isService()) { + print 'jQuery("#date_end").addClass("error");'; + } + } } print '' ?> @@ -451,7 +469,17 @@ jQuery(document).ready(function() } }); - table_element_line, array('propaldet', 'commandedet', 'facturedet'))) { ?> + $("#date_start, #date_end").focusout(function() { + if ( $(this).val() == '' && !$(this).hasClass('inputmandatory') ) { + $(this).addClass('inputmandatory'); + } else { + $(this).removeClass('inputmandatory'); + } + }); + margin->enabled)) { ?> /* Add rule to clear margin when we change some data, so when we change sell or buy price, margin will be recalculated after submitting form */ diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index b50ca83c6f6..c4ddc7d0c4c 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -164,7 +164,7 @@ if (($line->info_bits & 2) == 2) { // Show date range if ($line->element == 'facturedetrec') { if ($line->date_start_fill || $line->date_end_fill) { - print '

    '; + print '
    '; } if ($line->date_start_fill) { print ''.$langs->trans('AutoFillDateFromShort').': '.yn($line->date_start_fill); @@ -180,14 +180,31 @@ if (($line->info_bits & 2) == 2) { } } else { if ($line->date_start || $line->date_end) { - print '
    '.get_date_range($line->date_start, $line->date_end, $format).'
    '; + print '
    '.get_date_range($line->date_start, $line->date_end, $format).'
    '; } + if (!$line->date_start || !$line->date_end) { + // show warning under line + // we need to fetch product associated to line for some test + if ($object->element == 'propal' || $object->element == 'order' || $object->element == 'propal_supplier' || $object->element == 'supplier_proposal' || $object->element == 'commande') { + $res = $line->fetch_product(); + if ($res > 0 ) { + if ($line->product->isService() && $line->product->isMandatoryPeriod()) { + print '
    '.$langs->trans("mandatoryPeriodNeedTobeSet").'
    '; + } + } + } + } + //print get_date_range($line->date_start, $line->date_end, $format); } // Add description in form if ($line->fk_product > 0 && !empty($conf->global->PRODUIT_DESC_IN_FORM)) { - print (!empty($line->description) && $line->description != $line->product_label) ? (($line->date_start || $line->date_end) ? '' : '
    ').'
    '.dol_htmlentitiesbr($line->description) : ''; + if ($line->element == 'facturedetrec') { + print (!empty($line->description) && $line->description != $line->product_label) ? (($line->date_start_fill || $line->date_end_fill) ? '' : '
    ').'
    '.dol_htmlentitiesbr($line->description) : ''; + } else { + print (!empty($line->description) && $line->description != $line->product_label) ? (($line->date_start || $line->date_end) ? '' : '
    ').'
    '.dol_htmlentitiesbr($line->description) : ''; + } } // Line extrafield @@ -368,7 +385,7 @@ if ($this->statut == 0 && !empty($object_rights->creer) && $action != 'selectlin $coldisplay++; if (($line->info_bits & 2) == 2 || !empty($disableedit)) { } else { ?> - id.'#line_'.$line->id; ?>"> + id.'#line_'.$line->id; ?>"> '; } print ''; @@ -376,7 +393,7 @@ if ($this->statut == 0 && !empty($object_rights->creer) && $action != 'selectlin print '
    %'; $coldisplay++; if (!$situationinvoicelinewithparent && empty($disableremove)) { // For situation invoice, deletion is not possible if there is a parent company. - print 'id.'">'; + print 'id.'">'; print img_delete(); print ''; } @@ -386,12 +403,12 @@ if ($this->statut == 0 && !empty($object_rights->creer) && $action != 'selectlin print ''; $coldisplay++; if ($i > 0) { ?> - id; ?>"> + id; ?>"> - id; ?>"> + id; ?>"> -/* Copyright (C) 2017 Charlie Benke + * Copyright (C) 2017 Charlie 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 diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index dd779803026..c45ce9d2406 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -173,11 +173,11 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - if (! empty($conf->expedition->enabled) && ! empty($conf->workflow->enabled) && ! empty($conf->global->WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE)) { + if (!empty($conf->expedition->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE)) { /** @var Facture $object */ $object->fetchObjectLinked('', 'shipping', $object->id, $object->element); - if (! empty($object->linkedObjects)) { + if (!empty($object->linkedObjects)) { /** @var Expedition $shipment */ $shipment = array_shift($object->linkedObjects['shipping']); diff --git a/htdocs/core/triggers/interface_50_modEventOrganization_EventOrganization.class.php b/htdocs/core/triggers/interface_50_modEventOrganization_EventOrganization.class.php index 04f9aaa17cc..dd1462ecf5f 100644 --- a/htdocs/core/triggers/interface_50_modEventOrganization_EventOrganization.class.php +++ b/htdocs/core/triggers/interface_50_modEventOrganization_EventOrganization.class.php @@ -101,8 +101,11 @@ class InterfaceEventOrganization extends DolibarrTriggers $defaultref = ''; } $task->ref = $defaultref; - $task->date_start = $object->date_start; - $task->date_end = $object->date_end; + + // TODO Can set offset for start date or endline from setup of task to create when creating event + $task->date_start = null; + $task->date_end = null; + $result = $task->create($user); if ($result < 0) { $this->errors=array_merge($this->errors, $task->errors); diff --git a/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php b/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php index c8e27f66189..b1eb321f7f5 100644 --- a/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php +++ b/htdocs/core/triggers/interface_90_modSociete_ContactRoles.class.php @@ -78,7 +78,11 @@ class InterfaceContactRoles extends DolibarrTriggers require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; $contactdefault = new Contact($this->db); $contactdefault->socid = $socid; - $TContact = $contactdefault->getContactRoles($object->element); + + $TContact = array(); + if (method_exists($contactdefault, 'getContactRoles')) { // For backward compatibility + $TContact = $contactdefault->getContactRoles($object->element); + } if (is_array($TContact) && !empty($TContact)) { $TContactAlreadyLinked = array(); diff --git a/htdocs/cron/card.php b/htdocs/cron/card.php index 727bf56f836..270fe3f57c4 100644 --- a/htdocs/cron/card.php +++ b/htdocs/cron/card.php @@ -745,7 +745,7 @@ if (($action == "create") || ($action == "edit")) { if (!$user->rights->cron->create) { print ''.$langs->trans("Edit").''; } else { - print ''.$langs->trans("Edit").''; + print ''.$langs->trans("Edit").''; } if ((empty($user->rights->cron->execute))) { @@ -753,7 +753,7 @@ if (($action == "create") || ($action == "edit")) { } elseif (empty($object->status)) { print ''.$langs->trans("CronExecute").''; } else { - print ''.$langs->trans("CronExecute").''; + print ''.$langs->trans("CronExecute").''; } if (!$user->rights->cron->create) { diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index e069ea7a326..4a6d61b6daf 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1432,10 +1432,10 @@ class Cronjob extends CommonObject $moretext .= ' ('.$langs->trans("Error").')'; } - $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Disabled').$moretext; - $this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Scheduled').$moretext; - $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Disabled'); - $this->labelStatusShort[self::STATUS_ENABLED] = $langs->trans('Scheduled'); + $this->labelStatus[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled').$moretext; + $this->labelStatus[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Scheduled').$moretext; + $this->labelStatusShort[self::STATUS_DISABLED] = $langs->transnoentitiesnoconv('Disabled'); + $this->labelStatusShort[self::STATUS_ENABLED] = $langs->transnoentitiesnoconv('Scheduled'); } $statusType = 'status4'; diff --git a/htdocs/datapolicy/admin/setup.php b/htdocs/datapolicy/admin/setup.php index dde8644571e..8f25461eb64 100644 --- a/htdocs/datapolicy/admin/setup.php +++ b/htdocs/datapolicy/admin/setup.php @@ -175,7 +175,7 @@ if ($action == 'edit') { print '
    '; print ''; } diff --git a/htdocs/datapolicy/admin/setupmail.php b/htdocs/datapolicy/admin/setupmail.php index 2ec083b0fa8..535c4383d0d 100644 --- a/htdocs/datapolicy/admin/setupmail.php +++ b/htdocs/datapolicy/admin/setupmail.php @@ -160,7 +160,7 @@ print dol_get_fiche_end(); print '

    '; print $langs->trans('SendAgreementText'); -print ''.$langs->trans('SendAgreement').''; +print ''.$langs->trans('SendAgreement').''; llxFooter(); $db->close(); diff --git a/htdocs/datapolicy/class/actions_datapolicy.class.php b/htdocs/datapolicy/class/actions_datapolicy.class.php index e54086149fe..c58e1634fc2 100644 --- a/htdocs/datapolicy/class/actions_datapolicy.class.php +++ b/htdocs/datapolicy/class/actions_datapolicy.class.php @@ -133,7 +133,7 @@ class ActionsDatapolicy header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv'); header('Pragma: no-cache'); $object->fetch(GETPOST('socid')); - echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;'.PHP_EOL; + echo 'Name;Firstname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;'.PHP_EOL; echo $object->name.';'; echo ';'; echo ';'; @@ -157,7 +157,7 @@ class ActionsDatapolicy header('Pragma: no-cache'); $soc = $object->fetch_thirdparty(); - echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;'.PHP_EOL; + echo 'Name;Firstname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;'.PHP_EOL; echo $object->lastname.';'; echo $object->firstname.';'; echo $object->getCivilityLabel().';'; @@ -181,7 +181,7 @@ class ActionsDatapolicy header('Content-Disposition: attachment; filename=datapolicy_portabilite.csv'); header('Pragma: no-cache'); $soc = $object->fetch_thirdparty(); - echo 'Name;Fistname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;'.PHP_EOL; + echo 'Name;Firstname;Civility;Thirdparty;Function;Address;ZipCode;City;Department;Country;Email;Pro Phone;Perso Phone;Mobile Phone;Instant Mail;Birthday;'.PHP_EOL; echo $object->lastname.';'; echo $object->firstname.';'; echo $object->getCivilityLabel().';'; diff --git a/htdocs/debugbar/class/DataCollector/DolLogsCollector.php b/htdocs/debugbar/class/DataCollector/DolLogsCollector.php index 520a0a20a72..5fd339918fa 100644 --- a/htdocs/debugbar/class/DataCollector/DolLogsCollector.php +++ b/htdocs/debugbar/class/DataCollector/DolLogsCollector.php @@ -73,7 +73,7 @@ class DolLogsCollector extends MessagesCollector { global $conf; - $uselogfile = $conf->global->DEBUGBAR_USE_LOGFILE; + $uselogfile = getDolGlobalInt('DEBUGBAR_USE_LOGFILE'); if ($uselogfile) { $this->getStorageLogs($this->path); diff --git a/htdocs/debugbar/class/DataCollector/DolibarrCollector.php b/htdocs/debugbar/class/DataCollector/DolibarrCollector.php index 2e11887360f..c69ebb9a121 100644 --- a/htdocs/debugbar/class/DataCollector/DolibarrCollector.php +++ b/htdocs/debugbar/class/DataCollector/DolibarrCollector.php @@ -86,12 +86,12 @@ class DolibarrCollector extends DataCollector implements Renderable, AssetProvid global $conf, $langs; global $dolibarr_mailing_limit_sendbyweb; - $info = $langs->trans('Method').': '.$conf->global->MAIN_MAIL_SENDMODE.'
    '; - $info .= $langs->trans('Server').': '.$conf->global->MAIN_MAIL_SMTP_SERVER.'
    '; - $info .= $langs->trans('Port').': '.$conf->global->MAIN_MAIL_SMTP_PORT.'
    '; - $info .= $langs->trans('ID').': '.$conf->global->MAIN_MAIL_SMTPS_ID.'
    '; - $info .= $langs->trans('Pwd').': '.preg_replace('/./', '*', $conf->global->MAIN_MAIL_SMTPS_PW).'
    '; - $info .= $langs->trans('TLS/STARTTLS').': '.(empty($conf->global->MAIN_MAIL_EMAIL_TLS) ? '' : $conf->global->MAIN_MAIL_EMAIL_TLS).' / '.(empty($conf->global->MAIN_MAIL_EMAIL_STARTTLS) ? '' : $conf->global->MAIN_MAIL_EMAIL_STARTTLS).'
    '; + $info = $langs->trans('Method').': '.getDolGlobalString("MAIN_MAIL_SENDMODE").'
    '; + $info .= $langs->trans('Server').': '.getDolGlobalString("MAIN_MAIL_SMTP_SERVER").'
    '; + $info .= $langs->trans('Port').': '.getDolGlobalString("MAIN_MAIL_SMTP_PORT").'
    '; + $info .= $langs->trans('ID').': '.getDolGlobalString("MAIN_MAIL_SMTPS_IDT").'
    '; + $info .= $langs->trans('Pwd').': '.preg_replace('/./', '*', getDolGlobalString("MAIN_MAIL_SMTPS_PW")).'
    '; + $info .= $langs->trans('TLS/STARTTLS').': '.getDolGlobalString("MAIN_MAIL_EMAIL_TLS").' / '.getDolGlobalString("MAIN_MAIL_EMAIL_STARTTLS").'
    '; $info .= $langs->trans('MAIN_DISABLE_ALL_MAILS').': '.(empty($conf->global->MAIN_DISABLE_ALL_MAILS) ? $langs->trans('No') : $langs->trans('Yes')).'
    '; $info .= 'dolibarr_mailing_limit_sendbyweb = '.$dolibarr_mailing_limit_sendbyweb.'
    '; diff --git a/htdocs/debugbar/class/TraceableDB.php b/htdocs/debugbar/class/TraceableDB.php index 267c79ab08e..2d9f70a1eb5 100644 --- a/htdocs/debugbar/class/TraceableDB.php +++ b/htdocs/debugbar/class/TraceableDB.php @@ -250,6 +250,17 @@ class TraceableDB extends DoliDB return $this->db->escape($stringtoencode); } + /** + * Escape a string to insert data + * + * @param string $stringtoencode String to escape + * @return string String escaped + */ + public function escapeunderscore($stringtoencode) + { + return $this->db->escapeunderscore($stringtoencode); + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Get last ID after an insert INSERT diff --git a/htdocs/delivery/card.php b/htdocs/delivery/card.php index 7d4a3b181e0..62955da7f06 100644 --- a/htdocs/delivery/card.php +++ b/htdocs/delivery/card.php @@ -114,7 +114,7 @@ if ($action == 'add') { $idl = "idl".$i; $qtytouse = price2num(GETPOST($qty)); if ($qtytouse > 0) { - $object->addline(GETPOST($idl), price2num($qtytouse)); + $object->addline(GETPOST($idl), price2num($qtytouse), $arrayoptions); } } @@ -330,7 +330,7 @@ if ($action == 'create') { // Create. Seems to no be used $morehtmlref .= '
    '.$langs->trans('Project').' '; if (0) { // Do not change on shipment if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { // $morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $expedition->id, $expedition->socid, $expedition->fk_project, 'projectid', 0, 0, 1, 1); @@ -348,9 +348,10 @@ if ($action == 'create') { // Create. Seems to no be used if (!empty($objectsrc->fk_project)) { $proj = new Project($db); $proj->fetch($objectsrc->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -427,7 +428,7 @@ if ($action == 'create') { // Create. Seems to no be used print ''; if ($action != 'editdate_delivery') { - print 'id.'">'.img_edit($langs->trans('SetDeliveryDate'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetDeliveryDate'), 1).''; } print ''; print ''; @@ -451,7 +452,7 @@ if ($action == 'create') { // Create. Seems to no be used print $langs->trans('IncotermLabel'); print ''; if ($user->rights->expedition->delivery->creer) { - print ''.img_edit().''; + print ''.img_edit().''; } else { print ' '; } @@ -603,23 +604,26 @@ if ($action == 'create') { // Create. Seems to no be used print ""; // Display lines extrafields - if (!empty($extrafields)) { + //if (!empty($extrafields)) { $colspan = 2; $mode = ($object->statut == 0) ? 'edit' : 'view'; $object->lines[$i]->fetch_optionals(); - if ($action == 'create_delivery') { - $srcLine = new ExpeditionLigne($db); + if ($action == 'create_delivery') { + $srcLine = new ExpeditionLigne($db); + $extrafields->fetch_name_optionals_label($srcLine->table_element); + $srcLine->id = $expedition->lines[$i]->id; + $srcLine->fetch_optionals(); + + $object->lines[$i]->array_options = array_merge($object->lines[$i]->array_options, $srcLine->array_options); + } else { + $srcLine = new DeliveryLine($db); $extrafields->fetch_name_optionals_label($srcLine->table_element); - $srcLine->id = $expedition->lines[$i]->id; - $srcLine->fetch_optionals(); - - $object->lines[$i]->array_options = array_merge($object->lines[$i]->array_options, $srcLine->array_options); - } - print $object->lines[$i]->showOptionals($extrafields, $mode, array('style' => 'class="oddeven"', 'colspan' => $colspan), $i); } + print $object->lines[$i]->showOptionals($extrafields, $mode, array('style' => 'class="oddeven"', 'colspan' => $colspan), ''); + //} } $i++; @@ -651,9 +655,9 @@ if ($action == 'create') { // Create. Seems to no be used if ($user->rights->expedition->delivery->supprimer) { if ($conf->expedition_bon->enabled) { - print ''.$langs->trans("Delete").''; + print ''.$langs->trans("Delete").''; } else { - print ''.$langs->trans("Delete").''; + print ''.$langs->trans("Delete").''; } } @@ -689,11 +693,11 @@ if ($action == 'create') { // Create. Seems to no be used } - print '
    '; + print '
    '; // Nothing on right - print '
    '; + print '
    '; } else { /* Expedition non trouvee */ print "Expedition inexistante ou acces refuse"; diff --git a/htdocs/delivery/class/delivery.class.php b/htdocs/delivery/class/delivery.class.php index 60c134661ce..6bfe3a33dd7 100644 --- a/htdocs/delivery/class/delivery.class.php +++ b/htdocs/delivery/class/delivery.class.php @@ -211,7 +211,7 @@ class Delivery extends CommonObject $origin_id = $this->lines[$i]->commande_ligne_id; // For backward compatibility } - if (!$this->create_line($origin_id, $this->lines[$i]->qty, $this->lines[$i]->fk_product, $this->lines[$i]->description)) { + if (!$this->create_line($origin_id, $this->lines[$i]->qty, $this->lines[$i]->fk_product, $this->lines[$i]->description, $this->lines[$i]->array_options)) { $error++; } } @@ -262,9 +262,10 @@ class Delivery extends CommonObject * @param string $qty Quantity * @param string $fk_product Id of predefined product * @param string $description Description + * @param array $array_options Array options * @return int <0 if KO, >0 if OK */ - public function create_line($origin_id, $qty, $fk_product, $description) + public function create_line($origin_id, $qty, $fk_product, $description, $array_options = null) { // phpcs:enable $error = 0; @@ -283,6 +284,15 @@ class Delivery extends CommonObject $error++; } + $id = $this->db->last_insert_id(MAIN_DB_PREFIX."deliverydet"); + + if (is_array($array_options) && count($array_options) > 0) { + $line = new DeliveryLine($this->db); + $line->id = $id; + $line->array_options = $array_options; + $result = $line->insertExtraFields(); + } + if ($error == 0) { return 1; } @@ -385,7 +395,7 @@ class Delivery extends CommonObject $error = 0; if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->delivery->creer)) - || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->delivery_advance->validate))) { + || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->expedition->delivery_advance->validate))) { if (!empty($conf->global->DELIVERY_ADDON_NUMBER)) { // Setting the command numbering module name $modName = $conf->global->DELIVERY_ADDON_NUMBER; @@ -531,7 +541,9 @@ class Delivery extends CommonObject $line->description = $expedition->lines[$i]->description; $line->qty = $expedition->lines[$i]->qty_shipped; $line->fk_product = $expedition->lines[$i]->fk_product; - + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($expedition->lines[$i]->array_options) && count($expedition->lines[$i]->array_options) > 0) { // For avoid conflicts if trigger used + $line->array_options = $expedition->lines[$i]->array_options; + } $this->lines[$i] = $line; } @@ -589,18 +601,23 @@ class Delivery extends CommonObject /** * Add line * - * @param int $origin_id Origin id - * @param int $qty Qty + * @param int $origin_id Origin id + * @param int $qty Qty + * @param array $array_options Array options * @return void */ - public function addline($origin_id, $qty) + public function addline($origin_id, $qty, $array_options = null) { + global $conf; + $num = count($this->lines); $line = new DeliveryLine($this->db); $line->origin_id = $origin_id; $line->qty = $qty; - + if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options) > 0) { // For avoid conflicts if trigger used + $line->array_options = $array_options; + } $this->lines[$num] = $line; } @@ -719,8 +736,8 @@ class Delivery extends CommonObject //if ($option !== 'nolink') //{ - // Add param to save lastsearch_values or not - $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0); + // 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; } @@ -846,12 +863,12 @@ class Delivery extends CommonObject if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("mymodule"); - $this->labelStatus[-1] = $langs->trans('StatusDeliveryCanceled'); - $this->labelStatus[0] = $langs->trans('StatusDeliveryDraft'); - $this->labelStatus[1] = $langs->trans('StatusDeliveryValidated'); - $this->labelStatusShort[-1] = $langs->trans('StatusDeliveryCanceled'); - $this->labelStatusShort[0] = $langs->trans('StatusDeliveryDraft'); - $this->labelStatusShort[1] = $langs->trans('StatusDeliveryValidated'); + $this->labelStatus[-1] = $langs->transnoentitiesnoconv('StatusDeliveryCanceled'); + $this->labelStatus[0] = $langs->transnoentitiesnoconv('StatusDeliveryDraft'); + $this->labelStatus[1] = $langs->transnoentitiesnoconv('StatusDeliveryValidated'); + $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv('StatusDeliveryCanceled'); + $this->labelStatusShort[0] = $langs->transnoentitiesnoconv('StatusDeliveryDraft'); + $this->labelStatusShort[1] = $langs->transnoentitiesnoconv('StatusDeliveryValidated'); } $statusType = 'status0'; @@ -980,7 +997,7 @@ class Delivery extends CommonObject $array[$i]['label'] = $objSourceLine->label ? $objSourceLine->label : $objSourceLine->description; } - $i++; + $i++; } return $array; } else { diff --git a/htdocs/document.php b/htdocs/document.php index 3c06801c9a0..2a708ff3334 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -119,7 +119,7 @@ if ($user->socid > 0) { // For some module part, dir may be privates if (in_array($modulepart, array('facture_paiement', 'unpaid'))) { - if (!$user->rights->societe->client->voir || $socid) { + if (empty($user->rights->societe->client->voir) || $socid) { $original_file = 'private/'.$user->id.'/'.$original_file; // If user has no permission to see all, output dir is specific to user } } @@ -138,6 +138,7 @@ if (in_array($modulepart, array('facture_paiement', 'unpaid'))) { */ // If we have a hash public (hashp), we guess the original_file. +$ecmfile=''; if (!empty($hashp)) { include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; $ecmfile = new EcmFiles($db); @@ -195,9 +196,11 @@ if (!in_array($type, array('text/x-javascript')) && !dolIsAllowedForPreview($ori } // Security: Delete string ../ or ..\ into $original_file +$original_file = preg_replace('/\.\.+/', '..', $original_file); // Replace '... or more' with '..' $original_file = str_replace('../', '/', $original_file); $original_file = str_replace('..\\', '/', $original_file); + // Find the subdirectory name as the reference $refname = basename(dirname($original_file)."/"); diff --git a/htdocs/don/admin/donation.php b/htdocs/don/admin/donation.php index d8b06285be4..c56effea73a 100644 --- a/htdocs/don/admin/donation.php +++ b/htdocs/don/admin/donation.php @@ -251,12 +251,12 @@ if (is_resource($handle)) { print ''; } else { print "\n"; - print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Enabled"), 'switch_on').''; + print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Enabled"), 'switch_on').''; print ''; } } else { print "\n"; - print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print ""; } @@ -267,7 +267,7 @@ if (is_resource($handle)) { print ''; } else { print ""; - print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; + print 'scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; print ''; } diff --git a/htdocs/don/card.php b/htdocs/don/card.php index 2aa4b971e0f..7aa7ea802ce 100644 --- a/htdocs/don/card.php +++ b/htdocs/don/card.php @@ -517,7 +517,7 @@ if ($action == 'create') { $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, 'edit', $parameters); + print $object->showOptionals($extrafields, 'create', $parameters); } print ''; @@ -700,7 +700,7 @@ if (!empty($id) && $action != 'edit') { $morehtmlref .= $langs->trans('Project').' '; if ($user->rights->don->creer) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -717,9 +717,10 @@ if (!empty($id) && $action != 'edit') { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -778,7 +779,6 @@ if (!empty($id) && $action != 'edit') { print ''; print '
    '; - print '
    '; /* * Payments @@ -788,7 +788,7 @@ if (!empty($id) && $action != 'edit') { $sql .= " FROM ".MAIN_DB_PREFIX."payment_donation as p"; $sql .= ", ".MAIN_DB_PREFIX."c_paiement as c "; $sql .= ", ".MAIN_DB_PREFIX."don as d"; - $sql .= " WHERE d.rowid = '".$id."'"; + $sql .= " WHERE d.rowid = ".((int) $id); $sql .= " AND p.fk_donation = d.rowid"; $sql .= " AND d.entity IN (".getEntity('donation').")"; $sql .= " AND p.fk_typepayment = c.id"; @@ -836,7 +836,6 @@ if (!empty($id) && $action != 'edit') { dol_print_error($db); } - print '
    '; print '
    '; print ''; @@ -855,7 +854,7 @@ if (!empty($id) && $action != 'edit') { print ''.$langs->trans("ReOpen").''; } - print ''; + print ''; if ($object->statut == $object::STATUS_DRAFT) { print ''; @@ -870,13 +869,13 @@ if (!empty($id) && $action != 'edit') { if ($remaintopay == 0) { print '
    '.$langs->trans('DoPayment').'
    '; } else { - print ''; + print ''; } } // Classify 'paid' if ($object->statut == $object::STATUS_VALIDATED && round($remaintopay) == 0 && $object->paid == 0 && $user->rights->don->creer) { - print '"; + print '"; } // Delete @@ -919,9 +918,9 @@ if (!empty($id) && $action != 'edit') { print showOnlinePaymentUrl('donation', $object->ref).'
    '; } - print '
    '; + print '
    '; - print '
    '; + print ''; } llxFooter(); diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php index 792edbcc928..7ca70a31aa2 100644 --- a/htdocs/don/class/don.class.php +++ b/htdocs/don/class/don.class.php @@ -1116,7 +1116,7 @@ class Don extends CommonObject return -1; } - $sql = 'SELECT SUM(amount) as sum_amount FROM '.MAIN_DB_PREFIX.'payment_donation WHERE fk_donation = '.((int) $this->id); + $sql = "SELECT SUM(amount) as sum_amount FROM ".MAIN_DB_PREFIX."payment_donation WHERE fk_donation = ".((int) $this->id); $resql = $this->db->query($sql); if (!$resql) { dol_print_error($this->db); diff --git a/htdocs/don/document.php b/htdocs/don/document.php index 374306bc7b0..ab99ba3df1d 100644 --- a/htdocs/don/document.php +++ b/htdocs/don/document.php @@ -80,6 +80,8 @@ $object->fetch($id, $ref); $upload_dir = $conf->don->dir_output.'/'.get_exdir($filename, 0, 0, 0, $object, 'donation').'/'.dol_sanitizeFileName($object->ref); $modulepart = 'don'; +$permissiontoadd = $user->rights->don->creer; // Used by the include of actions_dellink.inc.php + /* * Actions @@ -132,7 +134,7 @@ if ($object->id) { $morehtmlref .= $langs->trans('Project').' '; if ($user->rights->don->creer) { if ($action != 'classify') { - // $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + // $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); @@ -149,9 +151,10 @@ if ($object->id) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/don/index.php b/htdocs/don/index.php index 36323d332b7..85e2eb3e48f 100644 --- a/htdocs/don/index.php +++ b/htdocs/don/index.php @@ -190,7 +190,7 @@ print ''; print ""; -print '
    '; +print '
    '; $max = 10; @@ -252,7 +252,7 @@ if ($resql) { } -print '
    '; +print ''; $parameters = array('user' => $user); $reshook = $hookmanager->executeHooks('dashboardDonation', $parameters, $object); // Note that $action and $object may have been modified by hook diff --git a/htdocs/don/info.php b/htdocs/don/info.php index 8d8f4065dda..0057bf87dce 100644 --- a/htdocs/don/info.php +++ b/htdocs/don/info.php @@ -82,7 +82,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= $langs->trans('Project').' '; if ($user->rights->don->creer) { if ($action != 'classify') { - // $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + // $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); @@ -99,9 +99,10 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/don/note.php b/htdocs/don/note.php index 13f9b1d4a96..1629aa0f28f 100644 --- a/htdocs/don/note.php +++ b/htdocs/don/note.php @@ -105,7 +105,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= $langs->trans('Project').' '; if ($user->rights->don->creer) { if ($action != 'classify') { - // $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + // $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); @@ -122,9 +122,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/don/payment/card.php b/htdocs/don/payment/card.php index 40cf0298895..363ef6d34ef 100644 --- a/htdocs/don/payment/card.php +++ b/htdocs/don/payment/card.php @@ -213,7 +213,7 @@ print '
    '; if (empty($action)) { if ($user->rights->don->supprimer) { if (!$disable_delete) { - print ''.$langs->trans('Delete').''; + print ''.$langs->trans('Delete').''; } else { print ''.$langs->trans('Delete').''; } diff --git a/htdocs/don/stats/index.php b/htdocs/don/stats/index.php index 23e6c0a46c0..bb7d6b314aa 100644 --- a/htdocs/don/stats/index.php +++ b/htdocs/don/stats/index.php @@ -70,7 +70,7 @@ $data = $stats->getNbByMonthWithPrevYear($endyear, $startyear); // $data = array(array('Lib',val1,val2,val3),...) -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filenamenb = $dir.'/shipmentsnbinyear-'.$user->id.'-'.$year.'.png'; } else { $filenamenb = $dir.'/shipmentsnbinyear-'.$year.'.png'; @@ -105,7 +105,7 @@ $data = $stats->getAmountByMonthWithPrevYear($endyear,$startyear); //var_dump($data); // $data = array(array('Lib',val1,val2,val3),...) -if (!$user->rights->societe->client->voir || $user->socid) +if (empty($user->rights->societe->client->voir) || $user->socid) { $filenameamount = $dir.'/shipmentsamountinyear-'.$user->id.'-'.$year.'.png'; } @@ -143,7 +143,7 @@ if (! $mesg) /* $data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); -if (!$user->rights->societe->client->voir || $user->socid) +if (empty($user->rights->societe->client->voir) || $user->socid) { $filename_avg = $dir.'/shipmentsaverage-'.$user->id.'-'.$year.'.png'; } @@ -276,7 +276,7 @@ print ''; print '
    '; -print '
    '; +print '
    '; // Show graphs @@ -293,7 +293,7 @@ if ($mesg) { print ''; -print '
    '; +print ''; print '
    '; print dol_get_fiche_end(); diff --git a/htdocs/don/tpl/linkedobjectblock.tpl.php b/htdocs/don/tpl/linkedobjectblock.tpl.php index 3d6ec68ba2e..4097e73d560 100644 --- a/htdocs/don/tpl/linkedobjectblock.tpl.php +++ b/htdocs/don/tpl/linkedobjectblock.tpl.php @@ -19,7 +19,7 @@ * */ -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/ecm/ajax/ecmdatabase.php b/htdocs/ecm/ajax/ecmdatabase.php index 4d782a3caeb..2ce35973483 100644 --- a/htdocs/ecm/ajax/ecmdatabase.php +++ b/htdocs/ecm/ajax/ecmdatabase.php @@ -17,7 +17,7 @@ /** * \file htdocs/ecm/ajax/ecmdatabase.php - * \brief File to build ecm database + * \brief File to build/refresh the ecm database for directories */ if (!defined('NOTOKENRENEWAL')) { @@ -39,6 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $action = GETPOST('action', 'aZ09'); $element = GETPOST('element', 'alpha'); + /* * View */ @@ -86,7 +87,7 @@ if (isset($action) && !empty($action)) { } if (!$dirisindatabase) { - $txt = "Directory found on disk ".$dirdesc['fullname'].", not found into database so we add it"; + $txt = "Directory found on disk ".$dirdesc['fullname'].", not found into table ecm_directories, so we add it"; dol_syslog($txt); // We must first find the fk_parent of directory to create $dirdesc['fullname'] @@ -155,15 +156,16 @@ if (isset($action) && !empty($action)) { foreach ($sqltree as $dirdesc) { // Loop on each sqltree to check dir is on disk $dirtotest = $conf->$element->dir_output.'/'.$dirdesc['fullrelativename']; if (!dol_is_dir($dirtotest)) { - $mesg .= $dirtotest." not found onto disk. We delete from database dir with id=".$dirdesc['id']."
    \n"; + dol_syslog($dirtotest." not found onto disk. We delete from database dir with id=".$dirdesc['id']); $ecmdirtmp->id = $dirdesc['id']; $ecmdirtmp->delete($user, 'databaseonly'); //exit; } } - $sql = "UPDATE ".MAIN_DB_PREFIX."ecm_directories set cachenbofdoc = -1 WHERE cachenbofdoc < 0"; // If pb into cahce counting, we set to value -1 = "unknown" - dol_syslog("sql = ".$sql); + dol_syslog("Nb of directories added into database = ".$adirwascreated); + + $sql = "UPDATE ".MAIN_DB_PREFIX."ecm_directories set cachenbofdoc = -1 WHERE cachenbofdoc < 0"; // If pb into cache counting, we set to value -1 = "unknown" $db->query($sql); } } diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index 3c7af135922..03413a56eb1 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -144,7 +144,6 @@ class EcmDirectory extends CommonObject // Clean parameters $this->label = dol_sanitizeFileName(trim($this->label)); - $this->fk_parent = trim($this->fk_parent); $this->description = trim($this->description); $this->date_c = $now; $this->fk_user_c = $user->id; @@ -155,7 +154,7 @@ class EcmDirectory extends CommonObject // Check if same directory does not exists with this name $relativepath = $this->label; - if ($this->fk_parent) { + if ($this->fk_parent > 0) { $parent = new EcmDirectory($this->db); $parent->fetch($this->fk_parent); $relativepath = $parent->getRelativePath().$relativepath; @@ -194,11 +193,11 @@ class EcmDirectory extends CommonObject $sql .= ") VALUES ("; $sql .= " '".$this->db->escape($this->label)."',"; $sql .= " '".$this->db->escape($conf->entity)."',"; - $sql .= " '".$this->db->escape($this->fk_parent)."',"; + $sql .= " ".($this->fk_parent > 0 ? ((int) $this->fk_parent) : "null").","; $sql .= " '".$this->db->escape($this->description)."',"; $sql .= " ".((int) $this->cachenbofdoc).","; $sql .= " '".$this->db->idate($this->date_c)."',"; - $sql .= " '".$this->db->escape($this->fk_user_c)."'"; + $sql .= " ".($this->fk_user_c > 0 ? ((int) $this->fk_user_c) : "null"); $sql .= ")"; dol_syslog(get_class($this)."::create", LOG_DEBUG); @@ -249,20 +248,19 @@ class EcmDirectory extends CommonObject // Clean parameters $this->label = trim($this->label); - $this->fk_parent = trim($this->fk_parent); $this->description = trim($this->description); - - // Check parameters - // Put here code to add control on parameters values + if ($this->fk_parent <= 0) { + $this->fk_parent = 0; + } $this->db->begin(); // Update request $sql = "UPDATE ".MAIN_DB_PREFIX."ecm_directories SET"; - $sql .= " label='".$this->db->escape($this->label)."',"; - $sql .= " fk_parent='".$this->db->escape($this->fk_parent)."',"; - $sql .= " description='".$this->db->escape($this->description)."'"; - $sql .= " WHERE rowid=".((int) $this->id); + $sql .= " label = '".$this->db->escape($this->label)."',"; + $sql .= " fk_parent = ".($this->fk_parent > 0 ? ((int) $this->fk_parent) : "null").","; + $sql .= " description = '".$this->db->escape($this->description)."'"; + $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); @@ -731,10 +729,10 @@ class EcmDirectory extends CommonObject // We count number of _ to have level (we use strlen that is faster than dol_strlen) $this->cats[$id_categ]['level'] = strlen(preg_replace('/([^_])/i', '', $this->cats[$id_categ]['fullpath'])); - // Traite ces enfants + // Process children $protection++; if ($protection > 20) { - return; // On ne traite pas plus de 20 niveaux + return; // We never go more than 20 levels } if (isset($this->cats[$id_categ]['id_children']) && is_array($this->cats[$id_categ]['id_children'])) { foreach ($this->cats[$id_categ]['id_children'] as $key => $val) { diff --git a/htdocs/ecm/class/htmlecm.form.class.php b/htdocs/ecm/class/htmlecm.form.class.php index 4b9d0a847f2..623d626935d 100644 --- a/htdocs/ecm/class/htmlecm.form.class.php +++ b/htdocs/ecm/class/htmlecm.form.class.php @@ -55,9 +55,10 @@ class FormEcm * @param int $selected Id of preselected section * @param string $select_name Name of HTML select component * @param string $module Module ('ecm', 'medias', ...) + * @param array $ids_to_ignore Array of id to ignore * @return string String with HTML select */ - public function selectAllSections($selected = 0, $select_name = '', $module = 'ecm') + public function selectAllSections($selected = 0, $select_name = '', $module = 'ecm', $ids_to_ignore = array()) { global $conf, $langs; $langs->load("ecm"); @@ -65,6 +66,9 @@ class FormEcm if ($select_name == '') { $select_name = "catParent"; } + if (!is_array($ids_to_ignore)) { + $ids_to_ignore = array($ids_to_ignore); + } $cate_arbo = null; if ($module == 'ecm') { @@ -83,13 +87,15 @@ class FormEcm } else { $output .= ''; foreach ($cate_arbo as $key => $value) { - $valueforoption = empty($cate_arbo[$key]['id']) ? $cate_arbo[$key]['relativename'] : $cate_arbo[$key]['id']; - if ($selected && $valueforoption == $selected) { - $add = 'selected '; - } else { - $add = ''; + if (!in_array($cate_arbo[$key]['id'], $ids_to_ignore)) { + $valueforoption = empty($cate_arbo[$key]['id']) ? $cate_arbo[$key]['relativename'] : $cate_arbo[$key]['id']; + if ($selected && $valueforoption == $selected) { + $add = 'selected '; + } else { + $add = ''; + } + $output .= ''; } - $output .= ''; } } } diff --git a/htdocs/ecm/dir_card.php b/htdocs/ecm/dir_card.php index fec8151728e..793e199f180 100644 --- a/htdocs/ecm/dir_card.php +++ b/htdocs/ecm/dir_card.php @@ -28,6 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/ecm.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once DOL_DOCUMENT_ROOT.'/ecm/class/htmlecm.form.class.php'; // Load translation files required by page $langs->loadLangs(array('ecm', 'companies', 'other')); @@ -204,6 +205,12 @@ if ($action == 'update' && !GETPOST('cancel', 'alpha') && $permtoadd) { // Fetch was already done $ecmdir->label = dol_sanitizeFileName(GETPOST("label")); + $fk_parent = GETPOST("catParent", 'int'); + if ($fk_parent == "-1") { + $ecmdir->fk_parent = "0"; + } else { + $ecmdir->fk_parent = $fk_parent; + } $ecmdir->description = GETPOST("description"); $ret = $extrafields->setOptionalsFromPost(null, $ecmdir); if ($ret < 0) { @@ -219,8 +226,10 @@ if ($action == 'update' && !GETPOST('cancel', 'alpha') && $permtoadd) { } $result = $ecmdir->update($user); if ($result > 0) { + $newdir = $ecmdir->getRelativePath(1); + $newdir = $conf->ecm->dir_output.'/'.$newdir; // Try to rename file if changed - if ($oldlabel != $ecmdir->label && file_exists($olddir)) { + if (($oldlabel != $ecmdir->label && file_exists($olddir)) || ($olddir != $newdir && file_exists($olddir))) { $newdir = $ecmdir->getRelativePath(1); // return "xxx/zzz/" from ecm directory $newdir = $conf->ecm->dir_output.'/'.$newdir; //print $olddir.'-'.$newdir; @@ -270,6 +279,7 @@ if ($action == 'update' && !GETPOST('cancel', 'alpha') && $permtoadd) { */ $form = new Form($db); +$formecm = new FormEcm($db); $object = new EcmDirectory($db); // Need to create a new one instance $extrafields = new ExtraFields($db); @@ -317,11 +327,7 @@ if ($module == 'ecm') { $tmpecmdir->fetch($ecmdir->id); while ($tmpecmdir && $result > 0) { $tmpecmdir->ref = $tmpecmdir->label; - if ($i == 0 && $action == 'edit') { - $s = ''; - } else { - $s = $tmpecmdir->getNomUrl(1).$s; - } + $s = $tmpecmdir->getNomUrl(1).$s; if ($tmpecmdir->fk_parent) { $s = ' -> '.$s; $result = $tmpecmdir->fetch($tmpecmdir->fk_parent); @@ -371,6 +377,16 @@ print img_picto('','object_dir').' '.$l print $s; print '';*/ if ($module == 'ecm') { + if ($action == 'edit') { + print ''.$langs->trans("ECMDirName").''; + print ''; + print ''; + print ''.$langs->trans("ECMParentDirectory").''; + print $formecm->selectAllSections($ecmdir->fk_parent, '', 'ecm', array($ecmdir->id)); + print ''; + print ''; + } + print ''.$langs->trans("Description").''; if ($action == 'edit') { print ''; - print ''; + // Add comments + print ''; + print ''; + print ''; - // Select VAT - print ''; - $defaultvat = -1; + // Select VAT + print ''; + $defaultvat = -1; if (!empty($conf->global->EXPENSEREPORT_NO_DEFAULT_VAT)) { $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS = 'none'; } - print $form->load_tva('vatrate', ($vatrate != '' ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1); - print ''; + print $form->load_tva('vatrate', ($vatrate != '' ? $vatrate : $defaultvat), $mysoc, '', 0, 0, '', false, 1); + print ''; - // Unit price net - print ''; - print ''; - print ''; + // Unit price net + print ''; + print ''; + print ''; - // Unit price with tax - print ''; - print ''; - print ''; + // Unit price with tax + print ''; + print ''; + print ''; - // Quantity - print ''; - print ''; // We must be able to enter decimal qty - print ''; + // Quantity + print ''; + print ''; // We must be able to enter decimal qty + print ''; - // Picture - print ''; + // Picture + print ''; if ($action != 'editline') { print ''; print ''; } - print ''; - print $form->buttonsSaveCancel("Add", '', '', 1); - print ''; + print ''; + print $form->buttonsSaveCancel("Add", '', '', 1); + print ''; - print ''; + print ''; } // Fin si c'est payé/validé print ''; @@ -2526,7 +2586,7 @@ if ($action == 'create') { print '
    '; -if ($action != 'create' && $action != 'edit') { +if ($action != 'create' && $action != 'edit' && $action != 'editline') { $object = new ExpenseReport($db); $object->fetch($id, $ref); @@ -2548,11 +2608,11 @@ if ($action != 'create' && $action != 'edit') { if ($user->rights->expensereport->creer && $object->status == ExpenseReport::STATUS_DRAFT) { if (in_array($object->fk_user_author, $user->getAllChildIds(1)) || !empty($user->rights->expensereport->writeall_advance)) { // Modify - print ''; + print ''; // Validate if (count($object->lines) > 0) { - print ''; + print ''; } } } @@ -2565,12 +2625,12 @@ if ($action != 'create' && $action != 'edit') { if ($user->rights->expensereport->creer && $object->status == ExpenseReport::STATUS_REFUSED) { if ($user->id == $object->fk_user_author || $user->id == $object->fk_user_valid) { // Modify - print ''; + print ''; // setdraft (le statut refusée est identique à brouillon) //print ''.$langs->trans('ReOpen').''; // Enregistrer depuis le statut "Refusée" - print ''; + print ''; } } @@ -2704,13 +2764,13 @@ if ($action != 'presend') { } */ - print '
    '; + print '
    '; // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'expensereport', null); - print '
    '; + print ''; } // Presend form diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 6dfe761195e..877a7c79ade 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -80,8 +80,6 @@ class ExpenseReport extends CommonObject */ public $fk_statut; - public $vat_src_code; - public $fk_c_paiement; public $paid; @@ -124,6 +122,9 @@ class ExpenseReport extends CommonObject // Paiement public $user_paid_infos; + public $localtax1; // for backward compatibility (real field should be total_localtax1 defined into CommonObject) + public $localtax2; // for backward compatibility (real field should be total_localtax2 defined into CommonObject) + /** * Draft status @@ -213,6 +214,10 @@ class ExpenseReport extends CommonObject $this->total_ht = 0; $this->total_ttc = 0; $this->total_tva = 0; + $this->total_localtax1 = 0; + $this->total_localtax2 = 0; + $this->localtax1 = 0; // For backward compatibility + $this->localtax2 = 0; // For backward compatibility $this->modepaymentid = 0; // List of language codes for status @@ -314,12 +319,18 @@ class ExpenseReport extends CommonObject $newndfline->fk_project = $line->fk_project; $newndfline->vatrate = $line->vatrate; $newndfline->vat_src_code = $line->vat_src_code; + $newndfline->localtax1_tx = $line->localtax1_tx; + $newndfline->localtax2_tx = $line->localtax2_tx; + $newndfline->localtax1_type = $line->localtax1_type; + $newndfline->localtax2_type = $line->localtax2_type; $newndfline->comments = $line->comments; $newndfline->qty = $line->qty; $newndfline->value_unit = $line->value_unit; $newndfline->total_ht = $line->total_ht; $newndfline->total_ttc = $line->total_ttc; $newndfline->total_tva = $line->total_tva; + $newndfline->total_localtax1 = $line->total_localtax1; + $newndfline->total_localtax2 = $line->total_localtax2; $newndfline->date = $line->date; $newndfline->rule_warning_message = $line->rule_warning_message; $newndfline->fk_c_exp_tax_cat = $line->fk_c_exp_tax_cat; @@ -539,7 +550,8 @@ class ExpenseReport extends CommonObject $sql = "SELECT d.rowid, d.entity, d.ref, d.note_public, d.note_private,"; // DEFAULT $sql .= " d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,"; // ACTIONS $sql .= " d.date_refuse, d.date_cancel,"; // ACTIONS - $sql .= " d.total_ht, d.total_ttc, d.total_tva,"; // TOTAUX (int) + $sql .= " d.total_ht, d.total_ttc, d.total_tva,"; + $sql .= " d.localtax1 as total_localtax1, d.localtax2 as total_localtax2,"; $sql .= " d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,"; // DATES (datetime) $sql .= " d.fk_user_creat, d.fk_user_author, d.fk_user_modif, d.fk_user_validator,"; $sql .= " d.fk_user_valid, d.fk_user_approve,"; @@ -565,6 +577,11 @@ class ExpenseReport extends CommonObject $this->total_ht = $obj->total_ht; $this->total_tva = $obj->total_tva; $this->total_ttc = $obj->total_ttc; + $this->localtax1 = $obj->total_localtax1; // For backward compatibility + $this->localtax2 = $obj->total_localtax2; // For backward compatibility + $this->total_localtax1 = $obj->total_localtax1; + $this->total_localtax2 = $obj->total_localtax2; + $this->note_public = $obj->note_public; $this->note_private = $obj->note_private; $this->detail_refuse = $obj->detail_refuse; @@ -962,54 +979,6 @@ class ExpenseReport extends CommonObject } } - /** - * recalculer - * TODO Replace this with call to update_price if not already done - * - * @param int $id Id of expense report - * @return int <0 if KO, >0 if OK - */ - public function recalculer($id) - { - $sql = 'SELECT tt.total_ht, tt.total_ttc, tt.total_tva'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as tt'; - $sql .= " WHERE tt.".$this->fk_element.' = '.((int) $id); - - $total_ht = 0; $total_tva = 0; $total_ttc = 0; - - $result = $this->db->query($sql); - if ($result) { - $num = $this->db->num_rows($result); - $i = 0; - while ($i < $num) { - $objp = $this->db->fetch_object($result); - $total_ht += $objp->total_ht; - $total_tva += $objp->total_tva; - $i++; - } - - $total_ttc = $total_ht + $total_tva; - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; - $sql .= " total_ht = ".((float) price2num($total_ht, 'MT')); - $sql .= " , total_ttc = ".((float) price2num($total_ttc, 'MT')); - $sql .= " , total_tva = ".((float) price2num($total_tva, 'MT')); - $sql .= " WHERE rowid = ".((int) $id); - $result = $this->db->query($sql); - if ($result) : - $this->db->free($result); - return 1; - else : - $this->error = $this->db->lasterror(); - dol_syslog(get_class($this)."::recalculer: Error ".$this->error, LOG_ERR); - return -3; - endif; - } else { - $this->error = $this->db->lasterror(); - dol_syslog(get_class($this)."::recalculer: Error ".$this->error, LOG_ERR); - return -3; - } - } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * fetch_lines @@ -1024,8 +993,12 @@ class ExpenseReport extends CommonObject $this->lines = array(); $sql = ' SELECT de.rowid, de.comments, de.qty, de.value_unit, de.date, de.rang,'; - $sql .= " de.".$this->fk_element.", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project, de.tva_tx, de.fk_ecm_files,"; + $sql .= " de.".$this->fk_element.", de.fk_c_type_fees, de.fk_c_exp_tax_cat, de.fk_projet as fk_project,"; + $sql .= ' de.tva_tx, de.vat_src_code,'; + $sql .= ' de.localtax1_tx, de.localtax2_tx, de.localtax1_type, de.localtax2_type,'; + $sql .= ' de.fk_ecm_files,'; $sql .= ' de.total_ht, de.total_tva, de.total_ttc,'; + $sql .= ' de.total_localtax1, de.total_localtax2, de.rule_warning_message,'; $sql .= ' ctf.code as code_type_fees, ctf.label as libelle_type_fees,'; $sql .= ' p.ref as ref_projet, p.title as title_projet'; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as de'; @@ -1065,14 +1038,25 @@ class ExpenseReport extends CommonObject $deplig->total_ht = $objp->total_ht; $deplig->total_tva = $objp->total_tva; $deplig->total_ttc = $objp->total_ttc; + $deplig->total_localtax1 = $objp->total_localtax1; + $deplig->total_localtax2 = $objp->total_localtax2; $deplig->type_fees_code = empty($objp->code_type_fees) ? 'TF_OTHER' : $objp->code_type_fees; $deplig->type_fees_libelle = $objp->libelle_type_fees; - $deplig->tva_tx = $objp->tva_tx; + + $deplig->tva_tx = $objp->tva_tx; $deplig->vatrate = $objp->tva_tx; + $deplig->vat_src_code = $objp->vat_src_code; + $deplig->localtax1_tx = $objp->localtax1_tx; + $deplig->localtax2_tx = $objp->localtax2_tx; + $deplig->localtax1_type = $objp->localtax1_type; + $deplig->localtax2_type = $objp->localtax2_type; + $deplig->projet_ref = $objp->ref_projet; $deplig->projet_title = $objp->title_projet; + $deplig->rule_warning_message = $objp->rule_warning_message; + $deplig->rang = $objp->rang; $this->lines[$i] = $deplig; @@ -1749,49 +1733,19 @@ class ExpenseReport extends CommonObject $sql .= " WHERE rowid = ".((int) $this->id); $result = $this->db->query($sql); - if ($result) : + if ($result) { return 1; - else : + } else { $this->error = $this->db->error(); return -1; - endif; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Update total of an expense report when you delete a line. - * - * @param string $ligne_total_ht Amount without taxes - * @param string $ligne_total_tva Amount of all taxes - * @return void - */ - public function update_totaux_del($ligne_total_ht, $ligne_total_tva) - { - // phpcs:enable - $this->total_ht = $this->total_ht - $ligne_total_ht; - $this->total_tva = $this->total_tva - $ligne_total_tva; - $this->total_ttc = $this->total_ht + $this->total_tva; - - $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; - $sql .= " total_ht = ".$this->total_ht; - $sql .= " , total_ttc = ".$this->total_ttc; - $sql .= " , total_tva = ".$this->total_tva; - $sql .= " WHERE rowid = ".((int) $this->id); - - $result = $this->db->query($sql); - if ($result) : - return 1; - else : - $this->error = $this->db->error(); - return -1; - endif; + } } /** - * addline + * Add expense report line * * @param float $qty Qty - * @param double $up Value init + * @param double $up Unit price (price with tax) * @param int $fk_c_type_fees Type payment * @param string $vatrate Vat rate (Can be '10' or '10 (ABC)') * @param string $date Date @@ -1838,7 +1792,14 @@ class ExpenseReport extends CommonObject $this->line = new ExpenseReportLine($this->db); - $localtaxes_type = getLocalTaxesFromRate($vatrate, 0, $mysoc, $this->thirdparty); + // We don't know seller and buyer for expense reports + $seller = $mysoc; // We use same than current company (expense report are often done in same country) + $seller->tva_assuj = 1; // Most seller uses vat + $seller->localtax1_assuj = $mysoc->localtax1_assuj; // We don't know, we reuse the state of company + $seller->localtax2_assuj = $mysoc->localtax1_assuj; // We don't know, we reuse the state of company + $buyer = new Societe($this->db); + + $localtaxes_type = getLocalTaxesFromRate($vatrate, 0, $buyer, $seller); $vat_src_code = ''; $reg = array(); @@ -1848,16 +1809,22 @@ class ExpenseReport extends CommonObject } $vatrate = preg_replace('/\*/', '', $vatrate); - $seller = ''; // seller is unknown - - $tmp = calcul_price_total($qty, $up, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller, $localtaxes_type); + $tmp = calcul_price_total($qty, $up, 0, $vatrate, -1, -1, 0, 'TTC', 0, $type, $seller, $localtaxes_type); $this->line->value_unit = $up; + $this->line->vat_src_code = $vat_src_code; $this->line->vatrate = price2num($vatrate); + $this->line->localtax1_tx = $localtaxes_type[1]; + $this->line->localtax2_tx = $localtaxes_type[3]; + $this->line->localtax1_type = $localtaxes_type[0]; + $this->line->localtax2_type = $localtaxes_type[2]; + $this->line->total_ttc = $tmp[2]; $this->line->total_ht = $tmp[0]; $this->line->total_tva = $tmp[1]; + $this->line->total_localtax1 = $tmp[9]; + $this->line->total_localtax2 = $tmp[10]; $this->line->fk_expensereport = $this->id; $this->line->qty = $qty; @@ -1899,21 +1866,27 @@ class ExpenseReport extends CommonObject /** * Check constraint of rules and update price if needed * - * @param int $type type of line - * @param string $seller seller, but actually he is unknown - * @return true or false + * @param int $type Type of line + * @param string $seller Seller, but actually he is unknown + * @return true or false */ public function checkRules($type = 0, $seller = '') { - global $user, $conf, $db, $langs; + global $user, $conf, $db, $langs, $mysoc; $langs->load('trips'); - if (empty($conf->global->MAIN_USE_EXPENSE_RULE)) { - return true; // if don't use rules + // We don't know seller and buyer for expense reports + if (!is_object($seller)) { + $seller = $mysoc; // We use same than current company (expense report are often done in same country) + $seller->tva_assuj = 1; // Most seller uses vat + $seller->localtax1_assuj = $mysoc->localtax1_assuj; // We don't know, we reuse the state of company + $seller->localtax2_assuj = $mysoc->localtax1_assuj; // We don't know, we reuse the state of company } + //$buyer = new Societe($this->db); - $rulestocheck = ExpenseReportRule::getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author); + $expensereportrule = new ExpenseReportRule($db); + $rulestocheck = $expensereportrule->getAllRule($this->line->fk_c_type_fees, $this->line->date, $this->fk_user_author); $violation = 0; $rule_warning_message_tab = array(); @@ -1939,12 +1912,12 @@ class ExpenseReport extends CommonObject $this->errors[] = $this->error; $new_current_total_ttc -= $amount_to_test - $rule->amount; // ex, entered 16€, limit 12€, subtracts 4€; - $rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationError', $rule->id, price($amount_to_test, 0, $langs, 1, -1, -1, $conf->currency), price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency), $langs->trans('by'.$rule->code_expense_rules_type, price($new_current_total_ttc, 0, $langs, 1, -1, -1, $conf->currency))); + $rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationError', $rule->id, price($amount_to_test, 0, $langs, 1, -1, -1, $conf->currency), price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency)); } else { $this->error = 'ExpenseReportConstraintViolationWarning'; $this->errors[] = $this->error; - $rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationWarning', $rule->id, price($amount_to_test, 0, $langs, 1, -1, -1, $conf->currency), price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency), $langs->trans('nolimitby'.$rule->code_expense_rules_type)); + $rule_warning_message_tab[] = $langs->trans('ExpenseReportConstraintViolationWarning', $rule->id, price($amount_to_test, 0, $langs, 1, -1, -1, $conf->currency), price($rule->amount, 0, $langs, 1, -1, -1, $conf->currency)); } // No break, we sould test if another rule is violated @@ -1960,6 +1933,8 @@ class ExpenseReport extends CommonObject $this->line->total_ttc = $tmp[2]; $this->line->total_ht = $tmp[0]; $this->line->total_tva = $tmp[1]; + $this->line->total_localtax1 = $tmp[9]; + $this->line->total_localtax2 = $tmp[10]; return false; } else { @@ -1970,11 +1945,13 @@ class ExpenseReport extends CommonObject /** * Method to apply the offset if needed * - * @return boolean true=applied, false=not applied + * @param int $type Type of line + * @param string $seller Seller, but actually he is unknown + * @return boolean True=applied, False=not applied */ - public function applyOffset() + public function applyOffset($type = 0, $seller = '') { - global $conf; + global $conf, $mysoc; if (empty($conf->global->MAIN_USE_EXPENSE_IK)) { return false; @@ -1987,7 +1964,17 @@ class ExpenseReport extends CommonObject return false; } - $range = ExpenseReportIk::getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat); + // We don't know seller and buyer for expense reports + if (!is_object($seller)) { + $seller = $mysoc; // We use same than current company (expense report are often done in same country) + $seller->tva_assuj = 1; // Most seller uses vat + $seller->localtax1_assuj = $mysoc->localtax1_assuj; // We don't know, we reuse the state of company + $seller->localtax2_assuj = $mysoc->localtax1_assuj; // We don't know, we reuse the state of company + } + //$buyer = new Societe($this->db); + + $expenseik = new ExpenseReportIk($this->db); + $range = $expenseik->getRangeByUser($userauthor, $this->line->fk_c_exp_tax_cat); if (empty($range)) { $this->error = 'ErrorNoRangeAvailable'; @@ -2010,6 +1997,8 @@ class ExpenseReport extends CommonObject $this->line->total_ttc = $tmp[2]; $this->line->total_ht = $tmp[0]; $this->line->total_tva = $tmp[1]; + $this->line->total_localtax1 = $tmp[9]; + $this->line->total_localtax2 = $tmp[10]; return true; } @@ -2033,7 +2022,7 @@ class ExpenseReport extends CommonObject $sql .= ' AND d.rowid <> '.((int) $this->line->id); } - dol_syslog(get_class($this)."::offsetAlreadyGiven sql=".$sql); + dol_syslog(get_class($this)."::offsetAlreadyGiven"); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -2056,7 +2045,7 @@ class ExpenseReport extends CommonObject * @param double $vatrate Vat rate. Can be '8.5' or '8.5* (8.5NPROM...)' * @param string $comments Description * @param float $qty Qty - * @param double $value_unit Value init + * @param double $value_unit Unit price (with taxes) * @param int $date Date * @param int $expensereport_id Expense report id * @param int $fk_c_exp_tax_cat Id of category of car @@ -2073,7 +2062,10 @@ class ExpenseReport extends CommonObject $type = 0; // TODO What if type is service ? // We don't know seller and buyer for expense reports - $seller = $mysoc; + $seller = $mysoc; // We use same than current company (expense report are often done in same country) + $seller->tva_assuj = 1; // Most seller uses vat + $seller->localtax1_assuj = $mysoc->localtax1_assuj; // We don't know, we reuse the state of company + $seller->localtax2_assuj = $mysoc->localtax1_assuj; // We don't know, we reuse the state of company $buyer = new Societe($this->db); $localtaxes_type = getLocalTaxesFromRate($vatrate, 0, $buyer, $seller); @@ -2087,8 +2079,8 @@ class ExpenseReport extends CommonObject } $vatrate = preg_replace('/\*/', '', $vatrate); - $tmp = calcul_price_total($qty, $value_unit, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller, $localtaxes_type); - + $tmp = calcul_price_total($qty, $value_unit, 0, $vatrate, -1, -1, 0, 'TTC', 0, $type, $seller, $localtaxes_type); + //var_dump($vatrate);var_dump($localtaxes_type);var_dump($tmp);exit; // calcul total of line //$total_ttc = price2num($qty*$value_unit, 'MT'); @@ -2109,14 +2101,17 @@ class ExpenseReport extends CommonObject $this->line->vat_src_code = $vat_src_code; $this->line->vatrate = price2num($vatrate); - $this->line->total_ttc = $tmp[2]; - $this->line->total_ht = $tmp[0]; - $this->line->total_tva = $tmp[1]; $this->line->localtax1_tx = $localtaxes_type[1]; $this->line->localtax2_tx = $localtaxes_type[3]; $this->line->localtax1_type = $localtaxes_type[0]; $this->line->localtax2_type = $localtaxes_type[2]; + $this->line->total_ttc = $tmp[2]; + $this->line->total_ht = $tmp[0]; + $this->line->total_tva = $tmp[1]; + $this->line->total_localtax1 = $tmp[9]; + $this->line->total_localtax2 = $tmp[10]; + $this->line->fk_ecm_files = $fk_ecm_files; $this->line->id = ((int) $rowid); @@ -2184,6 +2179,8 @@ class ExpenseReport extends CommonObject return -1; } + $this->update_price(); + $this->db->commit(); return 1; @@ -2214,8 +2211,6 @@ class ExpenseReport extends CommonObject $date_d_form = $date_debut; $date_f_form = $date_fin; - $existe = false; - while ($i < $num_rows) { $objp = $this->db->fetch_object($result); @@ -2223,17 +2218,13 @@ class ExpenseReport extends CommonObject $date_f_req = $this->db->jdate($objp->date_fin); // 4 if (!($date_f_form < $date_d_req || $date_d_form > $date_f_req)) { - $existe = true; + return $objp->rowid; } $i++; } - if ($existe) { - return 1; - } else { - return 0; - } + return 0; } else { return 0; } @@ -2593,15 +2584,25 @@ class ExpenseReportLine public $projet_title; public $vatrate; + public $vat_src_code; + public $localtax1_tx; + public $localtax2_tx; + public $localtax1_type; + public $localtax2_type; + public $total_ht; public $total_tva; public $total_ttc; + public $total_localtax1; + public $total_localtax2; /** * @var int ID into llx_ecm_files table to link line to attached file */ public $fk_ecm_files; + public $rule_warning_message; + /** * Constructor @@ -2623,6 +2624,7 @@ class ExpenseReportLine { $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_c_exp_tax_cat, fde.fk_projet as fk_project, fde.date,'; $sql .= ' fde.tva_tx as vatrate, fde.vat_src_code, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc, fde.fk_ecm_files,'; + $sql .= ' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,'; $sql .= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql .= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; $sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_det as fde'; @@ -2652,13 +2654,24 @@ class ExpenseReportLine $this->type_fees_libelle = $objp->type_fees_libelle; $this->projet_ref = $objp->projet_ref; $this->projet_title = $objp->projet_title; + $this->vatrate = $objp->vatrate; $this->vat_src_code = $objp->vat_src_code; + $this->localtax1_tx = $objp->localtax1_tx; + $this->localtax2_tx = $objp->localtax2_tx; + $this->localtax1_type = $objp->localtax1_type; + $this->localtax2_type = $objp->localtax2_type; + $this->total_ht = $objp->total_ht; $this->total_tva = $objp->total_tva; $this->total_ttc = $objp->total_ttc; + $this->total_localtax1 = $objp->total_localtax1; + $this->total_localtax2 = $objp->total_localtax2; + $this->fk_ecm_files = $objp->fk_ecm_files; + $this->rule_warning_message = $objp->rule_warning_message; + $this->db->free($result); } else { dol_print_error($this->db); @@ -2695,18 +2708,29 @@ class ExpenseReportLine $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'expensereport_det'; $sql .= ' (fk_expensereport, fk_c_type_fees, fk_projet,'; - $sql .= ' tva_tx, vat_src_code, comments, qty, value_unit, total_ht, total_tva, total_ttc, date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)'; + $sql .= ' tva_tx, vat_src_code,'; + $sql .= ' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,'; + $sql .= ' comments, qty, value_unit,'; + $sql .= ' total_ht, total_tva, total_ttc,'; + $sql .= ' total_localtax1, total_localtax2,'; + $sql .= ' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)'; $sql .= " VALUES (".$this->db->escape($this->fk_expensereport).","; $sql .= " ".((int) $this->fk_c_type_fees).","; $sql .= " ".((int) (!empty($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : ((!empty($this->fk_projet) && $this->fk_projet > 0) ? $this->fk_projet : 'null')).","; $sql .= " ".((float) $this->vatrate).","; $sql .= " '".$this->db->escape(empty($this->vat_src_code) ? '' : $this->vat_src_code)."',"; + $sql .= " ".((float) price2num($this->localtax1_tx)).","; + $sql .= " ".((float) price2num($this->localtax2_tx)).","; + $sql .= " '".$this->db->escape($this->localtax1_type)."',"; + $sql .= " '".$this->db->escape($this->localtax2_type)."',"; $sql .= " '".$this->db->escape($this->comments)."',"; $sql .= " ".((float) $this->qty).","; $sql .= " ".((float) $this->value_unit).","; $sql .= " ".((float) price2num($this->total_ht)).","; $sql .= " ".((float) price2num($this->total_tva)).","; $sql .= " ".((float) price2num($this->total_ttc)).","; + $sql .= " ".((float) price2num($this->total_localtax1)).","; + $sql .= " ".((float) price2num($this->total_localtax2)).","; $sql .= " '".$this->db->idate($this->date)."',"; $sql .= " ".(empty($this->rule_warning_message) ? 'null' : "'".$this->db->escape($this->rule_warning_message)."'").","; $sql .= " ".((int) $this->fk_c_exp_tax_cat).","; @@ -2814,11 +2838,17 @@ class ExpenseReportLine $sql .= ", value_unit = ".((float) $this->value_unit); $sql .= ", qty=".((float) $this->qty); $sql .= ", date='".$this->db->idate($this->date)."'"; - $sql .= ", total_ht=".((float) price2num($this->total_ht, 'MT')).""; - $sql .= ", total_tva=".((float) price2num($this->total_tva, 'MT')).""; - $sql .= ", total_ttc=".((float) price2num($this->total_ttc, 'MT')).""; + $sql .= ", total_ht=".((float) price2num($this->total_ht, 'MT')); + $sql .= ", total_tva=".((float) price2num($this->total_tva, 'MT')); + $sql .= ", total_ttc=".((float) price2num($this->total_ttc, 'MT')); + $sql .= ", total_localtax1=".((float) price2num($this->total_localtax1, 'MT')); + $sql .= ", total_localtax2=".((float) price2num($this->total_localtax2, 'MT')); $sql .= ", tva_tx=".((float) $this->vatrate); $sql .= ", vat_src_code='".$this->db->escape($this->vat_src_code)."'"; + $sql .= ", localtax1_tx=".((float) $this->localtax1_tx); + $sql .= ", localtax2_tx=".((float) $this->localtax2_tx); + $sql .= ", localtax1_type='".$this->db->escape($this->localtax1_type)."'"; + $sql .= ", localtax2_type='".$this->db->escape($this->localtax2_type)."'"; $sql .= ", rule_warning_message='".$this->db->escape($this->rule_warning_message)."'"; $sql .= ", fk_c_exp_tax_cat=".$this->db->escape($this->fk_c_exp_tax_cat); $sql .= ", fk_ecm_files=".($this->fk_ecm_files > 0 ? ((int) $this->fk_ecm_files) : 'null'); diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php index 358a2fe06ca..53cf3695b12 100644 --- a/htdocs/expensereport/class/expensereport_ik.class.php +++ b/htdocs/expensereport/class/expensereport_ik.class.php @@ -87,8 +87,6 @@ class ExpenseReportIk extends CoreObject */ public function __construct(DoliDB &$db) { - global $conf; - parent::__construct($db); parent::init(); @@ -102,29 +100,28 @@ class ExpenseReportIk extends CoreObject * @param int $mode 1=only active; 2=only inactive; other value return all * @return array of category */ - public static function getTaxCategories($mode = 1) + public function getTaxCategories($mode = 1) { - global $db; - $categories = array(); $sql = 'SELECT rowid, label, entity, active'; $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat'; - $sql .= ' WHERE entity IN ('.getEntity('c_exp_tax_cat').')'; + $sql .= ' WHERE entity IN (0, '.getEntity($this->element).')'; if ($mode == 1) { $sql .= ' AND active = 1'; } elseif ($mode == 2) { $sql .= 'AND active = 0'; } - dol_syslog(get_called_class().'::getTaxCategories sql='.$sql, LOG_DEBUG); - $resql = $db->query($sql); + dol_syslog(get_called_class().'::getTaxCategories', LOG_DEBUG); + + $resql = $this->db->query($sql); if ($resql) { - while ($obj = $db->fetch_object($resql)) { + while ($obj = $this->db->fetch_object($resql)) { $categories[$obj->rowid] = $obj; } } else { - dol_print_error($db); + dol_print_error($this->db); } return $categories; @@ -137,10 +134,10 @@ class ExpenseReportIk extends CoreObject * @param int $fk_c_exp_tax_cat category * @return boolean|array */ - public static function getRangeByUser(User $userauthor, int $fk_c_exp_tax_cat) + public function getRangeByUser(User $userauthor, int $fk_c_exp_tax_cat) { $default_range = (int) $userauthor->default_range; // if not defined, then 0 - $ranges = self::getRangesByCategory($fk_c_exp_tax_cat); + $ranges = $this->getRangesByCategory($fk_c_exp_tax_cat); // substract 1 because array start from 0 if (empty($ranges) || !isset($ranges[$default_range - 1])) { @@ -157,10 +154,8 @@ class ExpenseReportIk extends CoreObject * @param int $active active * @return array */ - public static function getRangesByCategory(int $fk_c_exp_tax_cat, $active = 1) + public function getRangesByCategory(int $fk_c_exp_tax_cat, $active = 1) { - global $db; - $ranges = array(); dol_syslog(get_called_class().'::getRangesByCategory for fk_c_exp_tax_cat='.$fk_c_exp_tax_cat, LOG_DEBUG); @@ -170,24 +165,25 @@ class ExpenseReportIk extends CoreObject $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)'; } $sql .= ' WHERE r.fk_c_exp_tax_cat = '.((int) $fk_c_exp_tax_cat); + $sql .= " AND r.entity IN(0, ".getEntity($this->element).")"; if ($active) { $sql .= ' AND r.active = 1 AND c.active = 1'; } $sql .= ' ORDER BY r.range_ik'; - $resql = $db->query($sql); + $resql = $this->db->query($sql); if ($resql) { - $num = $db->num_rows($resql); + $num = $this->db->num_rows($resql); if ($num > 0) { - while ($obj = $db->fetch_object($resql)) { - $object = new ExpenseReportIk($db); + while ($obj = $this->db->fetch_object($resql)) { + $object = new ExpenseReportIk($this->db); $object->fetch($obj->rowid); $ranges[] = $object; } } } else { - dol_print_error($db); + dol_print_error($this->db); } return $ranges; @@ -198,24 +194,23 @@ class ExpenseReportIk extends CoreObject * * @return array */ - public static function getAllRanges() + public function getAllRanges() { - global $db; - $ranges = array(); $sql = ' SELECT r.rowid, r.fk_c_exp_tax_cat, r.range_ik, c.label, i.rowid as fk_expense_ik, r.active as range_active, c.active as cat_active'; $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; $sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'c_exp_tax_cat c ON (r.fk_c_exp_tax_cat = c.rowid)'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'expensereport_ik i ON (r.rowid = i.fk_range)'; - $sql .= ' WHERE r.entity IN (0, '.getEntity('').')'; + $sql .= ' WHERE r.entity IN (0, '.getEntity($this->element).')'; $sql .= ' ORDER BY r.fk_c_exp_tax_cat, r.range_ik'; - dol_syslog(get_called_class().'::getAllRanges sql='.$sql, LOG_DEBUG); - $resql = $db->query($sql); + dol_syslog(get_called_class().'::getAllRanges', LOG_DEBUG); + + $resql = $this->db->query($sql); if ($resql) { - while ($obj = $db->fetch_object($resql)) { - $ik = new ExpenseReportIk($db); + while ($obj = $this->db->fetch_object($resql)) { + $ik = new ExpenseReportIk($this->db); if ($obj->fk_expense_ik > 0) { $ik->fetch($obj->fk_expense_ik); } @@ -227,7 +222,7 @@ class ExpenseReportIk extends CoreObject $ranges[$obj->fk_c_exp_tax_cat]['ranges'][] = $obj; } } else { - dol_print_error($db); + dol_print_error($this->db); } return $ranges; @@ -236,30 +231,28 @@ class ExpenseReportIk extends CoreObject /** * Return the max number of range by a category * - * @param int $default_c_exp_tax_cat id - * @return int + * @param int $default_c_exp_tax_cat id Default c_exp_tax_cat + * @return int Max nb */ - public static function getMaxRangeNumber($default_c_exp_tax_cat = 0) + public function getMaxRangeNumber($default_c_exp_tax_cat = 0) { - global $db, $conf; - $sql = 'SELECT MAX(counted) as nbRange FROM ('; $sql .= ' SELECT COUNT(*) as counted'; $sql .= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_range r'; - $sql .= ' WHERE r.entity IN (0, '.$conf->entity.')'; + $sql .= ' WHERE r.entity IN (0, '.getEntity($this->element).')'; if ($default_c_exp_tax_cat > 0) { $sql .= ' AND r.fk_c_exp_tax_cat = '.((int) $default_c_exp_tax_cat); } $sql .= ' GROUP BY r.fk_c_exp_tax_cat'; $sql .= ') as counts'; - dol_syslog(get_called_class().'::getMaxRangeNumber sql='.$sql, LOG_DEBUG); - $resql = $db->query($sql); + dol_syslog(get_called_class().'::getMaxRangeNumber', LOG_DEBUG); + $resql = $this->db->query($sql); if ($resql) { - $obj = $db->fetch_object($resql); + $obj = $this->db->fetch_object($resql); return $obj->nbRange; } else { - dol_print_error($db); + dol_print_error($this->db); } return 0; diff --git a/htdocs/expensereport/class/expensereport_rule.class.php b/htdocs/expensereport/class/expensereport_rule.class.php index 6299dd7c5bd..ae89b4b0f51 100644 --- a/htdocs/expensereport/class/expensereport_rule.class.php +++ b/htdocs/expensereport/class/expensereport_rule.class.php @@ -148,20 +148,19 @@ class ExpenseReportRule extends CoreObject * @param int $fk_user user of expense * @return array Array with ExpenseReportRule */ - public static function getAllRule($fk_c_type_fees = '', $date = '', $fk_user = '') + public function getAllRule($fk_c_type_fees = '', $date = '', $fk_user = '') { - global $db; - $rules = array(); + $sql = 'SELECT er.rowid'; $sql .= ' FROM '.MAIN_DB_PREFIX.'expensereport_rules er'; - $sql .= ' WHERE er.entity IN (0,'.getEntity('').')'; + $sql .= ' WHERE er.entity IN (0,'.getEntity($this->element).')'; if (!empty($fk_c_type_fees)) { $sql .= ' AND er.fk_c_type_fees IN (-1, '.((int) $fk_c_type_fees).')'; } if (!empty($date)) { - $sql .= " AND er.dates <= '".dol_print_date($date, '%Y-%m-%d')."'"; - $sql .= " AND er.datee >= '".dol_print_date($date, '%Y-%m-%d')."'"; + $sql .= " AND er.dates <= '".$this->db->idate($date)."'"; + $sql .= " AND er.datee >= '".$this->db->idate($date)."'"; } if ($fk_user > 0) { $sql .= ' AND (er.is_for_all = 1'; @@ -172,18 +171,18 @@ class ExpenseReportRule extends CoreObject dol_syslog("ExpenseReportRule::getAllRule"); - $resql = $db->query($sql); + $resql = $this->db->query($sql); if ($resql) { - while ($obj = $db->fetch_object($resql)) { - $rule = new ExpenseReportRule($db); + while ($obj = $this->db->fetch_object($resql)) { + $rule = new ExpenseReportRule($this->db); if ($rule->fetch($obj->rowid) > 0) { $rules[$rule->id] = $rule; } else { - dol_print_error($db); + dol_print_error($this->db); } } } else { - dol_print_error($db); + dol_print_error($this->db); } return $rules; @@ -201,7 +200,7 @@ class ExpenseReportRule extends CoreObject if ($this->fk_usergroup > 0) { $group = new UserGroup($this->db); if ($group->fetch($this->fk_usergroup) > 0) { - return $group->nom; + return $group->name; } else { $this->error = $group->error; $this->errors[] = $this->error; diff --git a/htdocs/expensereport/document.php b/htdocs/expensereport/document.php index d7ecea8fcc9..8c3b5f56549 100644 --- a/htdocs/expensereport/document.php +++ b/htdocs/expensereport/document.php @@ -44,13 +44,6 @@ $confirm = GETPOST('confirm', 'alpha'); $childids = $user->getAllChildIds(1); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'expensereport', $id, 'expensereport'); - - // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); @@ -81,6 +74,12 @@ $modulepart = 'trip'; // 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 +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'expensereport', $id, 'expensereport'); + if ($object->id > 0) { // Check current user can read this expense report $canread = 0; @@ -95,6 +94,8 @@ if ($object->id > 0) { } } +$permissiontoadd = $user->rights->expensereport->creer; // Used by the include of actions_dellink.inc.php + /* * Actions diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index c87cc08fb40..d731c4c8c82 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -185,7 +185,7 @@ print ''; // Right area -print '
    '; +print '
    '; $max = 10; @@ -265,7 +265,7 @@ if ($result) { dol_print_error($db); } -print '
    '; +print ''; $parameters = array('user' => $user); $reshook = $hookmanager->executeHooks('dashboardExpenseReport', $parameters, $object); // Note that $action and $object may have been modified by hook diff --git a/htdocs/expensereport/payment/card.php b/htdocs/expensereport/payment/card.php index 7b86f295b5b..847c059a9c6 100644 --- a/htdocs/expensereport/payment/card.php +++ b/htdocs/expensereport/payment/card.php @@ -240,7 +240,7 @@ print '
    '; if ($action == '') { if ($user->rights->expensereport->supprimer) { if (!$disable_delete) { - print ''.$langs->trans('Delete').''; + print ''.$langs->trans('Delete').''; } else { print ''.$langs->trans('Delete').''; } diff --git a/htdocs/expensereport/stats/index.php b/htdocs/expensereport/stats/index.php index 5f8a9f628b5..500fe874747 100644 --- a/htdocs/expensereport/stats/index.php +++ b/htdocs/expensereport/stats/index.php @@ -146,7 +146,7 @@ if (!$mesg) { $data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filename_avg = $dir.'/ordersaverage-'.$user->id.'-'.$year.'.png'; if ($mode == 'customer') { $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=orderstats&file=ordersaverage-'.$user->id.'-'.$year.'.png'; @@ -292,7 +292,7 @@ foreach ($data as $val) { print ''; print '
    '; -print '
    '; +print '
    '; // Show graphs @@ -309,7 +309,7 @@ if ($mesg) { print ''; -print '
    '; +print ''; print '
    '; diff --git a/htdocs/expensereport/tpl/expensereport_addfile.tpl.php b/htdocs/expensereport/tpl/expensereport_addfile.tpl.php index c27136ebd38..d74b68e6738 100644 --- a/htdocs/expensereport/tpl/expensereport_addfile.tpl.php +++ b/htdocs/expensereport/tpl/expensereport_addfile.tpl.php @@ -2,7 +2,14 @@ // Add line to upload new file print ''."\n"; print 'global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ' style="display: none"' : '').'>'; -print ''; + +// Num line +if ($action == 'editline') { + print ''; +} + +// Upload section +print ''; $modulepart = 'expensereport'; $permission = $user->rights->expensereport->creer; diff --git a/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php b/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php index 9264400a71f..33cfc0976fe 100644 --- a/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php +++ b/htdocs/expensereport/tpl/expensereport_linktofile.tpl.php @@ -13,7 +13,14 @@ if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) { if ($nbFiles > 0) { print 'global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ' style="display: none"' : '').'>'; - print ''; + + // Num line + if ($action == 'editline') { + print ''; + } + + // Select image section + print ''; //print ''.$langs->trans("AttachTheNewLineToTheDocument").'
    '; $modulepart = 'expensereport'; $maxheightmini = 48; $relativepath = (!empty($object->ref) ?dol_sanitizeFileName($object->ref) : '').'/'; @@ -112,8 +119,8 @@ if (empty($conf->global->EXPENSEREPORT_DISABLE_ATTACHMENT_ON_LINES)) { if (!empty($filenamelinked) && $filenamelinked == $file['relativename']) { $checked = ' checked'; } - print '
    '; - print ''; + print '
    '; + print ''; print '
    '; print '
    '; diff --git a/htdocs/expensereport/tpl/linkedobjectblock.tpl.php b/htdocs/expensereport/tpl/linkedobjectblock.tpl.php index 31c5526903b..6a36b62f924 100644 --- a/htdocs/expensereport/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expensereport/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; @@ -47,7 +47,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { echo price($objectlink->total_ht); } ?> getLibStatut(3); ?> - ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> + ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> array_export_code[$i] = $module->export_code[$r]; // Define a key for sort - $this->array_export_code_for_sort[$i] = $module->module_position.'_'.$module->export_code[$r]; // Add a key into the module + $this->array_export_code_for_sort[$i] = $module->module_position.'_'.$module->export_code[$r]; // Add a key into the module // Libelle du dataset export $this->array_export_label[$i] = $module->getExportDatasetLabel($r); // Tableau des champ a exporter (cle=champ, valeur=libelle) @@ -379,13 +379,13 @@ class Export */ public function conditionDate($Field, $Value, $Sens) { - // TODO date_format is forbidden, not performant and not portable. Use instead BETWEEN + // TODO date_format is forbidden, not performant and not portable. Use instead $Value to forge the range date. if (strlen($Value) == 4) { - $Condition = " date_format(".$Field.",'%Y') ".$Sens." '".$Value."'"; + $Condition = " date_format(".$Field.",'%Y') ".$Sens." '".$this->db->escape($Value)."'"; } elseif (strlen($Value) == 6) { - $Condition = " date_format(".$Field.",'%Y%m') ".$Sens." '".$Value."'"; + $Condition = " date_format(".$Field.",'%Y%m') ".$Sens." '".$this->db->escape($Value)."'"; } else { - $Condition = " date_format(".$Field.",'%Y%m%d') ".$Sens." ".$Value; + $Condition = " date_format(".$Field.",'%Y%m%d') ".$Sens." '".$this->db->escape($Value)."'"; } return $Condition; } @@ -416,7 +416,7 @@ class Export case 'Duree': case 'Numeric': case 'Number': - // Must be a string text to allow to use comparison strings like "<= 999" + // Must be a string text to allow to use comparison strings like "<= 99.9" $szFilterField = ''; break; case 'Status': diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index c0a48b97222..93e20b06afe 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -151,7 +151,6 @@ $sqlusedforexport = ''; $head = array(); $upload_dir = $conf->export->dir_temp.'/'.$user->id; -//$usefilters=($conf->global->MAIN_FEATURES_LEVEL > 1); $usefilters = 1; // Security check diff --git a/htdocs/fichinter/card-rec.php b/htdocs/fichinter/card-rec.php index 72a3fdd654b..0c84552c795 100644 --- a/htdocs/fichinter/card-rec.php +++ b/htdocs/fichinter/card-rec.php @@ -490,7 +490,7 @@ if ($action == 'create') { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->ficheinter->creer) { if ($action != 'classify') { - $morehtmlref .= ''; + $morehtmlref .= ''; $morehtmlref .= img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { @@ -507,10 +507,10 @@ if ($action == 'create') { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= 'trans('ShowProject').'">'; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -573,7 +573,6 @@ if ($action == 'create') { print ''; print '
    '; - print '
    '; print '
    '; $title = $langs->trans("Recurrence"); @@ -587,7 +586,7 @@ if ($action == 'create') { print $langs->trans('Frequency'); print ''; if ($action != 'editfrequency' && $user->rights->ficheinter->creer) { - print ''; + print ''; print img_edit($langs->trans('Edit'), 1).''; } print ''; @@ -674,7 +673,6 @@ if ($action == 'create') { print '
    '; } - print '
    '; print '
    '; print ''; @@ -761,7 +759,7 @@ if ($action == 'create') { $sql .= " FROM ".MAIN_DB_PREFIX."fichinter_rec as f"; $sql .= " , ".MAIN_DB_PREFIX."societe as s "; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " , ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; @@ -769,7 +767,7 @@ if ($action == 'create') { if ($socid) { $sql .= " AND s.rowid = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($search_ref) { diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index c1037b15556..44a4efd18df 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -66,17 +66,13 @@ $originid = (GETPOST('originid', 'int') ?GETPOST('originid', 'int') : GETPOST('o $note_public = GETPOST('note_public', 'restricthtml'); $lineid = GETPOST('line_id', 'int'); +$error = 0; + //PDF $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0)); $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'ficheinter', $id, 'fichinter'); - // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('interventioncard', 'globalcard')); @@ -96,11 +92,15 @@ if ($id > 0 || !empty($ref)) { } } +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'ficheinter', $id, 'fichinter'); + $permissionnote = $user->rights->ficheinter->creer; // Used by the include of actions_setnotes.inc.php $permissiondellink = $user->rights->ficheinter->creer; // Used by the include of actions_dellink.inc.php -$error = 0; - /* * Actions @@ -945,7 +945,7 @@ if ($action == 'create') { $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, 'edit'); + print $object->showOptionals($extrafields, 'create'); } // Show link to origin object @@ -1138,7 +1138,7 @@ if ($action == 'create') { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->ficheinter->creer) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -1146,7 +1146,7 @@ if ($action == 'create') { $morehtmlref .= ''; $morehtmlref .= ''; $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; + $morehtmlref .= ''; $morehtmlref .= ''; } else { $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1); @@ -1155,9 +1155,10 @@ if ($action == 'create') { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -1246,7 +1247,6 @@ if ($action == 'create') { print ''; print '
    '; - print '
    '; print '
    '; print ''; @@ -1260,7 +1260,6 @@ if ($action == 'create') { print "
    "; - print '
    '; print '
    '; print ''; @@ -1350,21 +1349,21 @@ if ($action == 'create') { // Icon to edit and delete if ($object->statut == 0 && $user->rights->ficheinter->creer) { print ''; - print 'rowid.'#'.$objp->rowid.'">'; + print 'rowid.'#'.$objp->rowid.'">'; print img_edit(); print ''; - print 'rowid.'">'; + print 'rowid.'">'; print img_delete(); print ''; print ''; if ($num > 1) { if ($i > 0) { - print 'rowid.'">'; + print 'rowid.'">'; print img_up(); print ''; } if ($i < $num - 1) { - print 'rowid.'">'; + print 'rowid.'">'; print img_down(); print ''; } @@ -1573,7 +1572,7 @@ if ($action == 'create') { // Reopen if ($object->statut >= Fichinter::STATUS_CLOSED) { if ($user->rights->ficheinter->creer) { - print ''; + print ''; } else { print ''; } @@ -1583,7 +1582,7 @@ if ($action == 'create') { if (empty($user->socid)) { if ($object->statut > Fichinter::STATUS_DRAFT) { if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || $user->rights->ficheinter->ficheinter_advance->send) { - print ''; + print ''; } else { print ''; } @@ -1622,26 +1621,26 @@ if ($action == 'create') { if (!empty($conf->global->FICHINTER_CLASSIFY_BILLED)) { // Option deprecated. In a future, billed must be managed with a dedicated field to 0 or 1 if ($object->statut != Fichinter::STATUS_BILLED) { - print ''; + print ''; } else { - print ''; + print ''; } } } // Done if (empty($conf->global->FICHINTER_CLASSIFY_BILLED) && $object->statut > Fichinter::STATUS_DRAFT && $object->statut < Fichinter::STATUS_CLOSED) { - print ''; + print ''; } // Clone if ($user->rights->ficheinter->creer) { - print ''; + print ''; } // Delete if (($object->statut == Fichinter::STATUS_DRAFT && $user->rights->ficheinter->creer) || $user->rights->ficheinter->supprimer) { - print ''; } } @@ -1668,14 +1667,14 @@ if ($action == 'create') { $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; + print '
    '; // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'fichinter', $socid, 1); - print '
    '; + print ''; } diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 9bd3f17da25..297e03fa379 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -204,7 +204,7 @@ class Fichinter extends CommonObject $sql = "SELECT count(fi.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as fi"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON fi.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/fichinter/class/fichinterstats.class.php b/htdocs/fichinter/class/fichinterstats.class.php index 297aeca7760..f6fbdb8d305 100644 --- a/htdocs/fichinter/class/fichinterstats.class.php +++ b/htdocs/fichinter/class/fichinterstats.class.php @@ -72,7 +72,7 @@ class FichinterStats extends Stats $this->field_line = '0'; //$this->where.= " AND c.fk_statut > 0"; // Not draft and not cancelled } - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $this->where .= " AND c.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $this->where .= ($this->where ? ' AND ' : '')."c.entity IN (".getEntity('fichinter').')'; @@ -98,7 +98,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%m') as dm, COUNT(*) as nb"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -122,7 +122,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%Y') as dm, COUNT(*) as nb, 0"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE ".$this->where; @@ -145,7 +145,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%m') as dm, 0"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -169,7 +169,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%m') as dm, 0"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year))."' AND '".$this->db->idate(dol_get_last_day($year))."'"; @@ -191,7 +191,7 @@ class FichinterStats extends Stats $sql = "SELECT date_format(c.date_valid,'%Y') as year, COUNT(*) as nb, 0 as total, 0 as avg"; $sql .= " FROM ".$this->from; - if (!$user->rights->societe->client->voir && !$this->socid) { + if (empty($user->rights->societe->client->voir) && !$this->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE ".$this->where; @@ -214,7 +214,7 @@ class FichinterStats extends Stats $sql = "SELECT product.ref, COUNT(product.ref) as nb, 0 as total, 0 as avg"; $sql .= " FROM ".$this->from.", ".$this->from_line.", ".MAIN_DB_PREFIX."product as product"; - //if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + //if (empty($user->rights->societe->client->voir) && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql .= " WHERE ".$this->where; $sql .= " AND c.rowid = tl.fk_fichinter AND tl.fk_product = product.rowid"; $sql .= " AND c.date_valid BETWEEN '".$this->db->idate(dol_get_first_day($year, 1, false))."' AND '".$this->db->idate(dol_get_last_day($year, 12, false))."'"; diff --git a/htdocs/fichinter/contact.php b/htdocs/fichinter/contact.php index 7957479e611..f2f50963287 100644 --- a/htdocs/fichinter/contact.php +++ b/htdocs/fichinter/contact.php @@ -128,7 +128,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->ficheinter->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -146,9 +146,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fichinter/document.php b/htdocs/fichinter/document.php index 71f52212978..7fdcaa151a0 100644 --- a/htdocs/fichinter/document.php +++ b/htdocs/fichinter/document.php @@ -78,6 +78,8 @@ $object->fetch($id, $ref); $upload_dir = $conf->ficheinter->dir_output.'/'.dol_sanitizeFileName($object->ref); $modulepart = 'fichinter'; +$permissiontoadd = $user->rights->ficheinter->creer; // Used by the include of actions_setnotes.inc.php + /* * Actions @@ -126,7 +128,7 @@ if ($object->id) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->commande->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -144,9 +146,10 @@ if ($object->id) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fichinter/index.php b/htdocs/fichinter/index.php index 8eca043ef40..0f0fc0acc99 100644 --- a/htdocs/fichinter/index.php +++ b/htdocs/fichinter/index.php @@ -74,7 +74,7 @@ print '
    '; $sql = "SELECT count(f.rowid), f.fk_statut"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."fichinter as f"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.entity IN (".getEntity('intervention').")"; @@ -82,7 +82,7 @@ $sql .= " AND f.fk_soc = s.rowid"; if ($user->socid) { $sql .= ' AND f.fk_soc = '.((int) $user->socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY f.fk_statut"; @@ -192,7 +192,7 @@ if (!empty($conf->ficheinter->enabled)) { $sql = "SELECT f.rowid, f.ref, s.nom as name, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.entity IN (".getEntity('intervention').")"; @@ -201,7 +201,7 @@ if (!empty($conf->ficheinter->enabled)) { if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -229,7 +229,7 @@ if (!empty($conf->ficheinter->enabled)) { } -print '
    '; +print '
    '; $max = 5; @@ -242,7 +242,7 @@ $sql = "SELECT f.rowid, f.ref, f.fk_statut, f.date_valid as datec, f.tms as date $sql .= " s.nom as name, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.entity IN (".getEntity('intervention').")"; @@ -251,7 +251,7 @@ $sql .= " AND f.fk_soc = s.rowid"; if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY f.tms DESC"; @@ -315,7 +315,7 @@ if (!empty($conf->ficheinter->enabled)) { $sql = "SELECT f.rowid, f.ref, f.fk_statut, s.nom as name, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."fichinter as f"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.entity IN (".getEntity('intervention').")"; @@ -324,7 +324,7 @@ if (!empty($conf->ficheinter->enabled)) { if ($socid) { $sql .= " AND f.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY f.rowid DESC"; @@ -381,7 +381,7 @@ if (!empty($conf->ficheinter->enabled)) { } } -print '
    '; +print ''; $parameters = array('user' => $user); $reshook = $hookmanager->executeHooks('dashboardInterventions', $parameters, $object); // Note that $action and $object may have been modified by hook diff --git a/htdocs/fichinter/info.php b/htdocs/fichinter/info.php index 39ac695f84e..e5eea9f846c 100644 --- a/htdocs/fichinter/info.php +++ b/htdocs/fichinter/info.php @@ -83,7 +83,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->commande->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -101,9 +101,10 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 6f4dccd878d..d710d7cd6cc 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -257,7 +257,7 @@ $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; -if (!$user->rights->societe->client->voir && empty($socid)) { +if (empty($user->rights->societe->client->voir) && empty($socid)) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= ", ".MAIN_DB_PREFIX."societe as s"; @@ -285,7 +285,7 @@ if ($search_desc) { if ($search_status != '' && $search_status >= 0) { $sql .= ' AND f.fk_statut = '.urlencode($search_status); } -if (!$user->rights->societe->client->voir && empty($socid)) { +if (empty($user->rights->societe->client->voir) && empty($socid)) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { diff --git a/htdocs/fichinter/note.php b/htdocs/fichinter/note.php index 01a8d82cf5a..579760cf55f 100644 --- a/htdocs/fichinter/note.php +++ b/htdocs/fichinter/note.php @@ -93,7 +93,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->commande->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -111,9 +111,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fichinter/stats/index.php b/htdocs/fichinter/stats/index.php index 7a7adb639b3..f1247adb457 100644 --- a/htdocs/fichinter/stats/index.php +++ b/htdocs/fichinter/stats/index.php @@ -79,7 +79,7 @@ $data = $stats->getNbByMonthWithPrevYear($endyear, $startyear); // $data = array(array('Lib',val1,val2,val3),...) -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filenamenb = $dir.'/interventionsnbinyear-'.$user->id.'-'.$year.'.png'; $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsnbinyear-'.$user->id.'-'.$year.'.png'; } else { @@ -114,7 +114,7 @@ if (!$mesg) { $data = $stats->getAmountByMonthWithPrevYear($endyear, $startyear); // $data = array(array('Lib',val1,val2,val3),...) -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filenameamount = $dir.'/interventionsamountinyear-'.$user->id.'-'.$year.'.png'; $fileurlamount = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsamountinyear-'.$user->id.'-'.$year.'.png'; } else { @@ -148,7 +148,7 @@ if (!$mesg) { $data = $stats->getAverageByMonthWithPrevYear($endyear, $startyear); -if (!$user->rights->societe->client->voir || $user->socid) { +if (empty($user->rights->societe->client->voir) || $user->socid) { $filename_avg = $dir.'/interventionsaverage-'.$user->id.'-'.$year.'.png'; $fileurl_avg = DOL_URL_ROOT.'/viewimage.php?modulepart=interventionstats&file=interventionsaverage-'.$user->id.'-'.$year.'.png'; } else { @@ -300,7 +300,7 @@ print ''; print ''; -print '
    '; +print '
    '; // Show graphs @@ -317,7 +317,7 @@ if ($mesg) { print ''; -print '
    '; +print ''; print '
    '; print dol_get_fiche_end(); diff --git a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php index ba754ec3321..e5903ee5863 100644 --- a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php @@ -22,7 +22,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; @@ -50,7 +50,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { datev, 'day'); ?> getLibStatut(3); ?> - ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> + ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> id > 0) { print showValueWithClipboardCPButton(dol_escape_htmltag($object->code_fournisseur)); $tmpcheck = $object->check_codefournisseur(); if ($tmpcheck != 0 && $tmpcheck != -5) { - print ' ('.$langs->trans("WrongSupplierCode").')'; + print ' ('.$langs->trans("WrongSupplierCode").')'; } print ''; print ''; @@ -261,7 +261,7 @@ if ($object->id > 0) { print $langs->trans('PaymentConditions'); print ''; if (($action != 'editconditions') && $user->rights->societe->creer) { - print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; } print ''; print ''; @@ -279,7 +279,7 @@ if ($object->id > 0) { print $langs->trans('PaymentMode'); print ''; if (($action != 'editmode') && $user->rights->societe->creer) { - print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; } print ''; print ''; @@ -371,7 +371,7 @@ if ($object->id > 0) { print ''; - print '
    '; + print '
    '; $boxstat = ''; @@ -813,7 +813,7 @@ if ($object->id > 0) { } } - print '
    '; + print ''; print '
    '; print dol_get_fiche_end(); diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index df1bf36b723..51cd2673b0b 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -201,6 +201,10 @@ class SupplierInvoices extends DolibarrApi /** * Create supplier invoice object * + * Note: soc_id = dolibarr_order_id + * + * Example: {'ref': 'auto', 'ref_supplier': '7985630', 'socid': 1, 'note': 'Inserted with Python', 'order_supplier': 1, 'date': '2021-07-28'} + * * @param array $request_data Request datas * * @return int ID of supplier invoice @@ -525,6 +529,10 @@ class SupplierInvoices extends DolibarrApi /** * Add a line to given supplier invoice * + * Note: socid = dolibarr_order_id, pu_ht = net price, remise = discount + * + * Example: {'socid': 1, 'qty': 1, 'pu_ht': 21.0, 'tva_tx': 25.0, 'fk_product': '1189', 'product_type': 0, 'remise_percent': 1.0, 'vat_src_code': None} + * * @param int $id Id of supplier invoice to update * @param array $request_data supplier invoice line data * diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index d4eedcd0fd9..f221035a2ab 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -224,7 +224,7 @@ class SupplierOrders extends DolibarrApi */ public function post($request_data = null) { - if (!DolibarrApiAccess::$user->rights->fournisseur->commande->creer || !DolibarrApiAccess::$user->rights->supplier_order->creer) { + if (empty(DolibarrApiAccess::$user->rights->fournisseur->commande->creer) && empty(DolibarrApiAccess::$user->rights->supplier_order->creer)) { throw new RestException(401, "Insuffisant rights"); } // Check mandatory fields @@ -260,7 +260,7 @@ class SupplierOrders extends DolibarrApi */ public function put($id, $request_data = null) { - if (!DolibarrApiAccess::$user->rights->fournisseur->commande->creer || !DolibarrApiAccess::$user->rights->supplier_order->creer) { + if (empty(DolibarrApiAccess::$user->rights->fournisseur->commande->creer) && empty(DolibarrApiAccess::$user->rights->supplier_order->creer)) { throw new RestException(401); } @@ -340,7 +340,7 @@ class SupplierOrders extends DolibarrApi */ public function validate($id, $idwarehouse = 0, $notrigger = 0) { - if (!DolibarrApiAccess::$user->rights->fournisseur->commande->creer || !DolibarrApiAccess::$user->rights->supplier_order->creer) { + if (empty(DolibarrApiAccess::$user->rights->fournisseur->commande->creer) && empty(DolibarrApiAccess::$user->rights->supplier_order->creer)) { throw new RestException(401); } $result = $this->order->fetch($id); diff --git a/htdocs/fourn/class/fournisseur.class.php b/htdocs/fourn/class/fournisseur.class.php index 805ed7c1ba6..b47cfa263c0 100644 --- a/htdocs/fourn/class/fournisseur.class.php +++ b/htdocs/fourn/class/fournisseur.class.php @@ -113,7 +113,7 @@ class Fournisseur extends Societe $sql = "SELECT count(s.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; @@ -178,12 +178,12 @@ class Fournisseur extends Societe $sql = "SELECT s.rowid, s.nom as name"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.fournisseur = 1"; $sql .= " AND s.entity IN (".getEntity('societe').")"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 09a43fb95ab..f5064699eb2 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -112,6 +112,7 @@ class CommandeFournisseur extends CommonOrder public $socid; public $fourn_id; public $date; + public $date_creation; public $date_valid; public $date_approve; public $date_approve2; // Used when SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED is set @@ -375,11 +376,16 @@ class CommandeFournisseur extends CommonOrder $this->total_localtax1 = $obj->localtax1; $this->total_localtax2 = $obj->localtax2; $this->total_ttc = $obj->total_ttc; - $this->date = $this->db->jdate($obj->date_creation); + $this->date_creation = $this->db->jdate($obj->date_creation); $this->date_valid = $this->db->jdate($obj->date_valid); $this->date_approve = $this->db->jdate($obj->date_approve); $this->date_approve2 = $this->db->jdate($obj->date_approve2); $this->date_commande = $this->db->jdate($obj->date_commande); // date we make the order to supplier + if (isset($obj->date_commande)) { + $this->date = $this->date_commande; + } else { + $this->date = $this->date_creation; + } $this->date_livraison = $this->db->jdate($obj->delivery_date); // deprecated $this->delivery_date = $this->db->jdate($obj->delivery_date); $this->remise_percent = $obj->remise_percent; @@ -1002,7 +1008,7 @@ class CommandeFournisseur extends CommonOrder if (empty($secondlevel)) { // standard or first level approval $sql .= " date_approve='".$this->db->idate($now)."',"; $sql .= " fk_user_approve = ".$user->id; - if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $conf->global->MAIN_FEATURES_LEVEL > 0 && $this->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) { + if (!empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) && $this->total_ht >= $conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED) { if (empty($this->user_approve_id2)) { $movetoapprovestatus = false; // second level approval not done $comment = ' (first level)'; @@ -2087,7 +2093,7 @@ class CommandeFournisseur extends CommonOrder // Test we can delete $this->fetchObjectLinked(null, 'order_supplier'); - if (!empty($this->linkedObjects)) { + if (!empty($this->linkedObjects) && array_key_exists('reception', $this->linkedObjects)) { foreach ($this->linkedObjects['reception'] as $element) { if ($element->statut >= 0) { $this->errors[] = $langs->trans('ReceptionExist'); @@ -2930,11 +2936,11 @@ class CommandeFournisseur extends CommonOrder $this->user_approve_id2 = $obj->fk_user_approve2; } - $this->date_creation = $this->db->idate($obj->datec); - $this->date_modification = $this->db->idate($obj->datem); - $this->date_approve = $this->db->idate($obj->datea); - $this->date_approve2 = $this->db->idate($obj->datea2); - $this->date_validation = $this->db->idate($obj->date_validation); + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = $this->db->jdate($obj->datem); + $this->date_approve = $this->db->jdate($obj->datea); + $this->date_approve2 = $this->db->jdate($obj->datea2); + $this->date_validation = $this->db->jdate($obj->date_validation); } $this->db->free($result); } else { @@ -2959,7 +2965,7 @@ class CommandeFournisseur extends CommonOrder $sql = "SELECT count(co.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as co"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON co.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; @@ -2997,7 +3003,7 @@ class CommandeFournisseur extends CommonOrder $sql = "SELECT c.rowid, c.date_creation as datec, c.date_commande, c.fk_statut, c.date_livraison as delivery_date"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON c.fk_soc = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = " AND"; @@ -3295,7 +3301,6 @@ class CommandeFournisseur extends CommonOrder $keysinwishednotindelivered = array_diff(array_keys($qtywished), array_keys($qtydelivered)); // To check we also have same number of keys $keysindeliverednotinwished = array_diff(array_keys($qtydelivered), array_keys($qtywished)); // To check we also have same number of keys /*var_dump(array_keys($qtydelivered)); - var_dump(array_keys($qtywished)); var_dump($diff_array); var_dump($keysinwishednotindelivered); diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index a83795996e4..7037cd94262 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -103,6 +103,7 @@ class CommandeFournisseurDispatch extends CommonObjectLine public $batch; public $eatby = ''; public $sellby = ''; + public $cost_price = 0; @@ -189,7 +190,8 @@ class CommandeFournisseurDispatch extends CommonObjectLine $sql .= "batch,"; $sql .= "eatby,"; $sql .= "sellby,"; - $sql .= "fk_reception"; + $sql .= "fk_reception,"; + $sql .= "cost_price"; $sql .= ") VALUES ("; @@ -205,7 +207,8 @@ class CommandeFournisseurDispatch extends CommonObjectLine $sql .= " ".(!isset($this->batch) ? 'NULL' : "'".$this->db->escape($this->batch)."'").","; $sql .= " ".(!isset($this->eatby) || dol_strlen($this->eatby) == 0 ? 'NULL' : "'".$this->db->idate($this->eatby)."'").","; $sql .= " ".(!isset($this->sellby) || dol_strlen($this->sellby) == 0 ? 'NULL' : "'".$this->db->idate($this->sellby)."'").","; - $sql .= " ".(!isset($this->fk_reception) ? 'NULL' : "'".$this->db->escape($this->fk_reception)."'").""; + $sql .= " ".(!isset($this->fk_reception) ? 'NULL' : "'".$this->db->escape($this->fk_reception)."'").","; + $sql .= " ".(!isset($this->cost_price) ? '0' : "'".$this->db->escape($this->cost_price)."'").""; $sql .= ")"; $this->db->begin(); @@ -283,7 +286,7 @@ class CommandeFournisseurDispatch extends CommonObjectLine $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; if ($ref) { - $sql .= " WHERE t.ref = '".$ref."'"; + $sql .= " WHERE t.ref = '".$this->db->escape($ref)."'"; } else { $sql .= " WHERE t.rowid = ".((int) $id); } @@ -371,7 +374,6 @@ class CommandeFournisseurDispatch extends CommonObjectLine // Update request $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; - $sql .= " fk_commande=".(isset($this->fk_commande) ? $this->fk_commande : "null").","; $sql .= " fk_product=".(isset($this->fk_product) ? $this->fk_product : "null").","; $sql .= " fk_commandefourndet=".(isset($this->fk_commandefourndet) ? $this->fk_commandefourndet : "null").","; @@ -385,8 +387,6 @@ class CommandeFournisseurDispatch extends CommonObjectLine $sql .= " batch=".(isset($this->batch) ? "'".$this->db->escape($this->batch)."'" : "null").","; $sql .= " eatby=".(dol_strlen($this->eatby) != 0 ? "'".$this->db->idate($this->eatby)."'" : 'null').","; $sql .= " sellby=".(dol_strlen($this->sellby) != 0 ? "'".$this->db->idate($this->sellby)."'" : 'null').""; - - $sql .= " WHERE rowid=".((int) $this->id); $this->db->begin(); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 9980e084789..6419d233d43 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -415,6 +415,7 @@ class FactureFournisseur extends CommonInvoice $sql = "INSERT INTO ".MAIN_DB_PREFIX."facture_fourn ("; $sql .= "ref"; $sql .= ", ref_supplier"; + $sql .= ", ref_ext"; $sql .= ", entity"; $sql .= ", type"; $sql .= ", libelle"; @@ -438,6 +439,7 @@ class FactureFournisseur extends CommonInvoice $sql .= " VALUES ("; $sql .= "'(PROV)'"; $sql .= ", '".$this->db->escape($this->ref_supplier)."'"; + $sql .= ", '".$this->db->escape($this->ref_ext)."'"; $sql .= ", ".((int) $conf->entity); $sql .= ", '".$this->db->escape($this->type)."'"; $sql .= ", '".$this->db->escape(isset($this->label) ? $this->label : (isset($this->libelle) ? $this->libelle : ''))."'"; @@ -647,6 +649,7 @@ class FactureFournisseur extends CommonInvoice $sql .= " t.rowid,"; $sql .= " t.ref,"; $sql .= " t.ref_supplier,"; + $sql .= " t.ref_ext,"; $sql .= " t.entity,"; $sql .= " t.type,"; $sql .= " t.fk_soc,"; @@ -708,6 +711,7 @@ class FactureFournisseur extends CommonInvoice $this->ref = $obj->ref ? $obj->ref : $obj->rowid; // We take rowid if ref is empty for backward compatibility $this->ref_supplier = $obj->ref_supplier; + $this->ref_ext = $obj->ref_ext; $this->entity = $obj->entity; $this->type = empty($obj->type) ? self::TYPE_STANDARD : $obj->type; $this->fk_soc = $obj->fk_soc; @@ -924,6 +928,9 @@ class FactureFournisseur extends CommonInvoice if (isset($this->ref_supplier)) { $this->ref_supplier = trim($this->ref_supplier); } + if (isset($this->ref_ext)) { + $this->ref_ext = trim($this->ref_ext); + } if (isset($this->entity)) { $this->entity = trim($this->entity); } @@ -1013,6 +1020,7 @@ class FactureFournisseur extends CommonInvoice $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn SET"; $sql .= " ref=".(isset($this->ref) ? "'".$this->db->escape($this->ref)."'" : "null").","; $sql .= " ref_supplier=".(isset($this->ref_supplier) ? "'".$this->db->escape($this->ref_supplier)."'" : "null").","; + $sql .= " ref_ext=".(isset($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null").","; $sql .= " entity=".(isset($this->entity) ? $this->entity : "null").","; $sql .= " type=".(isset($this->type) ? $this->type : "null").","; $sql .= " fk_soc=".(isset($this->fk_soc) ? $this->fk_soc : "null").","; @@ -1949,8 +1957,8 @@ class FactureFournisseur extends CommonInvoice $this->line->desc = $desc; $this->line->ref_supplier = $ref_supplier; - $this->line->qty = ($this->type == self::TYPE_CREDIT_NOTE ?abs($qty) : $qty); // For credit note, quantity is always positive and unit price negative - $this->line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ?-abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise + $this->line->qty = ($this->type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty); // For credit note, quantity is always positive and unit price negative + $this->line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise $this->line->vat_src_code = $vat_src_code; $this->line->tva_tx = $txtva; @@ -1959,11 +1967,11 @@ class FactureFournisseur extends CommonInvoice $this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; $this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; - $this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative - $this->line->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_tva) : $total_tva); - $this->line->total_localtax1 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_localtax1) : $total_localtax1); - $this->line->total_localtax2 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_localtax2) : $total_localtax2); - $this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ttc) : $total_ttc); + $this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative + $this->line->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva); // For credit note and if qty is negative, total is negative + $this->line->total_localtax1 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax1) : $total_localtax1); // For credit note and if qty is negative, total is negative + $this->line->total_localtax2 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax2) : $total_localtax2); // For credit note and if qty is negative, total is negative + $this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc); // For credit note and if qty is negative, total is negative $this->line->fk_product = $fk_product; $this->line->product_type = $type; @@ -1984,10 +1992,11 @@ class FactureFournisseur extends CommonInvoice // Multicurrency $this->line->fk_multicurrency = $this->fk_multicurrency; $this->line->multicurrency_code = $this->multicurrency_code; - $this->line->multicurrency_subprice = $pu_ht_devise; - $this->line->multicurrency_total_ht = $multicurrency_total_ht; - $this->line->multicurrency_total_tva = $multicurrency_total_tva; - $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; + $this->line->multicurrency_subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise); // For credit note, unit price always negative, always positive otherwise + + $this->line->multicurrency_total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht); // For credit note and if qty is negative, total is negative + $this->line->multicurrency_total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva); // For credit note and if qty is negative, total is negative + $this->line->multicurrency_total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc); // For credit note and if qty is negative, total is negative if (is_array($array_options) && count($array_options) > 0) { $this->line->array_options = $array_options; @@ -2404,7 +2413,7 @@ class FactureFournisseur extends CommonInvoice $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut'; $sql .= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as ff'; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= ' WHERE ff.paye=0'; @@ -2413,7 +2422,7 @@ class FactureFournisseur extends CommonInvoice if ($user->socid) { $sql .= ' AND ff.fk_soc = '.((int) $user->socid); } - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " AND ff.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -2440,7 +2449,7 @@ class FactureFournisseur extends CommonInvoice if ($facturestatic->hasDelay()) { $response->nbtodolate++; - $response->url_late = DOL_URL_ROOT.'/fourn/facture/list.php?option=late&mainmenu=billing&leftmenu=suppliers_bills'; + $response->url_late = DOL_URL_ROOT.'/fourn/facture/list.php?search_option=late&mainmenu=billing&leftmenu=suppliers_bills'; } } $this->db->free($resql); @@ -2759,7 +2768,7 @@ class FactureFournisseur extends CommonInvoice $sql = "SELECT count(f.rowid) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$user->socid) { + if (empty($user->rights->societe->client->voir) && !$user->socid) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc"; $sql .= " WHERE sc.fk_user = ".((int) $user->id); $clause = "AND"; diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index b08d9237c63..5b523d8d7e8 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -846,7 +846,7 @@ class ProductFournisseur extends Product $this->fourn_qty = $record["quantity"]; $this->fourn_remise_percent = $record["remise_percent"]; $this->fourn_remise = $record["remise"]; - $this->fourn_unitprice = $record["unitprice"]; + $this->fourn_unitprice = $fourn_unitprice; $this->fourn_charges = $record["charges"]; // deprecated $this->fourn_tva_tx = $record["tva_tx"]; $this->fourn_id = $record["fourn_id"]; @@ -1183,7 +1183,7 @@ class ProductFournisseur extends Product $label .= $this->displayPriceProductFournisseurLog($logPrices); } - $url = dol_buildpath('/product/fournisseurs.php', 1).'?id='.$this->id.'&action=add_price&socid='.$this->fourn_id.'&rowid='.$this->product_fourn_price_id; + $url = dol_buildpath('/product/fournisseurs.php', 1).'?id='.$this->id.'&action=add_price&token='.newToken().'&socid='.$this->fourn_id.'&rowid='.$this->product_fourn_price_id; if ($option != 'nolink') { // Add param to save lastsearch_values or not diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index d5110f4dc69..8f6ed82160e 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -144,6 +144,12 @@ $permissiondellink = $usercancreate; // Used by the include of actions_dellink.i $permissiontoedit = $usercancreate; // Used by the include of actions_lineupdown.inc.php $permissiontoadd = $usercancreate; // Used by the include of actions_addupdatedelete.inc.php +// Project permission +$caneditproject = false; +if (!empty($conf->projet->enabled)) { + $caneditproject = empty($conf->global->SUPPLIER_ORDER_FORBID_EDIT_PROJECT) || ($object->statut == CommandeFournisseur::STATUS_DRAFT && preg_match('/^[\(]?PROV/i', $object->ref)); +} + /* * Actions @@ -239,7 +245,7 @@ if (empty($reshook)) { } // Set project - if ($action == 'classin' && $usercancreate) { + if ($action == 'classin' && $usercancreate && $caneditproject) { $result = $object->setProject($projectid); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); @@ -1780,7 +1786,7 @@ if ($action == 'create') { print $hookmanager->resPrint; if (empty($reshook)) { - print $object->showOptionals($extrafields, 'edit'); + print $object->showOptionals($extrafields, 'create'); } // Bouton "Create Draft" @@ -1975,7 +1981,7 @@ if ($action == 'create') { } if (empty($conf->global->MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER) || $action != 'edit_thirdparty') { if (!empty($conf->global->MAIN_CAN_EDIT_SUPPLIER_ON_SUPPLIER_ORDER) && $object->statut == CommandeFournisseur::STATUS_DRAFT) { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetThirdParty')).''; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetThirdParty')).''; } $morehtmlref .= ' : '.$object->thirdparty->getNomUrl(1, 'supplier'); if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) { @@ -1988,8 +1994,8 @@ if ($action == 'create') { $langs->load("projects"); $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($usercancreate) { - if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + if ($action != 'classify' && $caneditproject) { + $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); @@ -2006,9 +2012,10 @@ if ($action == 'create') { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -2075,7 +2082,7 @@ if ($action == 'create') { print $langs->trans('PaymentConditions'); print ''; if ($action != 'editconditions') { - print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; } print ''; print ''; @@ -2094,7 +2101,7 @@ if ($action == 'create') { print $langs->trans('PaymentMode'); print ''; if ($action != 'editmode') { - print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; } print ''; print ''; @@ -2114,7 +2121,7 @@ if ($action == 'create') { print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0); print ''; if ($action != 'editmulticurrencycode' && $object->statut == $object::STATUS_DRAFT) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -2134,7 +2141,7 @@ if ($action == 'create') { print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0); print ''; if ($action != 'editmulticurrencyrate' && $object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -2162,7 +2169,7 @@ if ($action == 'create') { print $langs->trans('BankAccount'); print ''; if ($action != 'editbankaccount' && $usercancreate) { - print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; } print ''; print ''; @@ -2187,7 +2194,7 @@ if ($action == 'create') { print $langs->trans('DateDeliveryPlanned'); print ''; if ($action != 'editdate_livraison') { - print 'id.'">'.img_edit($langs->trans('SetDeliveryDate'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetDeliveryDate'), 1).''; } print ''; print ''; @@ -2221,7 +2228,7 @@ if ($action == 'create') { print $langs->trans('IncotermLabel'); print ''; if ($usercancreate) { - print ''.img_edit().''; + print ''.img_edit().''; } else { print ' '; } @@ -2243,7 +2250,6 @@ if ($action == 'create') { print ''; print '
    '; - print '
    '; print '
    '; print ''; @@ -2302,7 +2308,6 @@ if ($action == 'create') { }*/ - print ''; print ''; print ''; @@ -2410,7 +2415,7 @@ if ($action == 'create') { // Modify if ($object->statut == CommandeFournisseur::STATUS_VALIDATED) { if ($usercanorder) { - print ''.$langs->trans("Modify").''; + print ''.$langs->trans("Modify").''; } } @@ -2466,20 +2471,20 @@ if ($action == 'create') { if (!$buttonshown && $usercanapprove) { if (empty($conf->global->SUPPLIER_ORDER_REOPEN_BY_APPROVER_ONLY) || (!empty($conf->global->SUPPLIER_ORDER_REOPEN_BY_APPROVER_ONLY) && $user->id == $object->user_approve_id)) { - print ''.$langs->trans("Disapprove").''; + print ''.$langs->trans("Disapprove").''; $buttonshown++; } } if (!$buttonshown && $usercanapprovesecond && !empty($conf->global->SUPPLIER_ORDER_3_STEPS_TO_BE_APPROVED)) { if (empty($conf->global->SUPPLIER_ORDER_REOPEN_BY_APPROVER2_ONLY) || (!empty($conf->global->SUPPLIER_ORDER_REOPEN_BY_APPROVER2_ONLY) && $user->id == $object->user_approve_id2)) { - print ''.$langs->trans("Disapprove").''; + print ''.$langs->trans("Disapprove").''; } } } if (in_array($object->statut, array(3, 4, 5, 6, 7, 9))) { if ($usercanorder) { - print ''.$langs->trans("ReOpen").''; + print ''.$langs->trans("ReOpen").''; } } @@ -2519,7 +2524,7 @@ if ($action == 'create') { // Classify received (this does not record reception) if ($object->statut == CommandeFournisseur::STATUS_ORDERSENT || $object->statut == CommandeFournisseur::STATUS_RECEIVED_PARTIALLY) { if ($usercanreceived) { - print ''; + print ''; } } @@ -2536,11 +2541,11 @@ if ($action == 'create') { // Classify billed manually (need one invoice if module invoice is on, no condition on invoice if not) if ($usercancreate && $object->statut >= 2 && $object->statut != 7 && $object->billed != 1) { // statut 2 means approved if (empty($conf->facture->enabled)) { - print ''.$langs->trans("ClassifyBilled").''; + print ''.$langs->trans("ClassifyBilled").''; } else { if (!empty($object->linkedObjectsIds['invoice_supplier'])) { if ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer) { - print ''.$langs->trans("ClassifyBilled").''; + print ''.$langs->trans("ClassifyBilled").''; } } else { print ''.$langs->trans("ClassifyBilled").''; @@ -2550,7 +2555,7 @@ if ($action == 'create') { // Create a remote order using WebService only if module is activated if (!empty($conf->syncsupplierwebservices->enabled) && $object->statut >= 2) { // 2 means accepted - print ''.$langs->trans('CreateRemoteOrder').''; + print ''.$langs->trans('CreateRemoteOrder').''; } // Clone @@ -2570,7 +2575,7 @@ if ($action == 'create') { if ($hasreception) { print ''.$langs->trans("Delete").''; } else { - print ''.$langs->trans("Delete").''; + print ''.$langs->trans("Delete").''; } } } @@ -2625,15 +2630,16 @@ if ($action == 'create') { $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; $genallowed = $usercanread; $delallowed = $usercancreate; + $modelpdf = (!empty($object->model_pdf) ? $object->model_pdf : (empty($conf->global->COMMANDE_SUPPLIER_ADDON_PDF) ? '' : $conf->global->COMMANDE_SUPPLIER_ADDON_PDF)); - print $formfile->showdocuments('commande_fournisseur', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 0, 0, '', '', '', $object->thirdparty->default_lang); + print $formfile->showdocuments('commande_fournisseur', $objref, $filedir, $urlsource, $genallowed, $delallowed, $modelpdf, 1, 0, 0, 0, 0, '', '', '', $object->thirdparty->default_lang); $somethingshown = $formfile->numoffiles; // Show links to link elements $linktoelem = $form->showLinkToObjectBlock($object, null, array('supplier_order', 'order_supplier')); $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; + print '
    '; if ($action == 'classifyreception') { if ($usercanreceived && ($object->statut == CommandeFournisseur::STATUS_ORDERSENT || $object->statut == CommandeFournisseur::STATUS_RECEIVED_PARTIALLY)) { @@ -2679,7 +2685,7 @@ if ($action == 'create') { $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'order_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : '')); - print '
    '; + print ''; } /* diff --git a/htdocs/fourn/commande/contact.php b/htdocs/fourn/commande/contact.php index f53fba883c0..e521caf1080 100644 --- a/htdocs/fourn/commande/contact.php +++ b/htdocs/fourn/commande/contact.php @@ -140,7 +140,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -158,9 +158,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index ead05251920..170785c0118 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -547,7 +547,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -565,9 +565,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -1219,7 +1220,7 @@ if ($id > 0 || !empty($ref)) { // Qty print ''; print ''; diff --git a/htdocs/fourn/commande/document.php b/htdocs/fourn/commande/document.php index c38751fc138..c7e3f609164 100644 --- a/htdocs/fourn/commande/document.php +++ b/htdocs/fourn/commande/document.php @@ -46,12 +46,6 @@ $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); - // Get parameters $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); @@ -81,6 +75,15 @@ if ($object->fetch($id, $ref) < 0) { $upload_dir = $conf->fournisseur->commande->dir_output.'/'.dol_sanitizeFileName($object->ref); $object->fetch_thirdparty(); +// Security check +$socid = 0; +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); + +$permissiontoadd = ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer); // Used by the include of actions_setnotes.inc.php + /* * Actions @@ -133,7 +136,7 @@ if ($object->id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -151,9 +154,10 @@ if ($object->id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php index b4956ea706f..7d6b3b6936a 100644 --- a/htdocs/fourn/commande/index.php +++ b/htdocs/fourn/commande/index.php @@ -67,7 +67,7 @@ print '
    '; $sql = "SELECT count(cf.rowid) as nb, fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."commande_fournisseur as cf"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE cf.fk_soc = s.rowid"; @@ -75,7 +75,7 @@ $sql .= " AND cf.entity IN (".getEntity('supplier_order').")"; if ($user->socid) { $sql .= ' AND cf.fk_soc = '.((int) $user->socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " GROUP BY cf.fk_statut"; @@ -176,7 +176,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU $sql = "SELECT c.rowid, c.ref, s.nom as name, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -185,7 +185,7 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU if (!empty($socid)) { $sql .= " AND c.fk_soc = ".((int) $socid); } - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } @@ -272,7 +272,7 @@ if ($resql) { } -print '
    '; +print '
    '; /* @@ -283,7 +283,7 @@ $max = 5; $sql = "SELECT c.rowid, c.ref, c.fk_statut as status, c.tms, c.billed, s.nom as name, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE c.fk_soc = s.rowid"; @@ -292,7 +292,7 @@ $sql .= " AND c.entity IN (".getEntity('supplier_order').")"; if (!empty($socid)) { $sql .= " AND c.fk_soc = ".((int) $socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " ORDER BY c.tms DESC"; @@ -355,12 +355,12 @@ if ($resql) { $sql = "SELECT c.rowid, c.ref, c.fk_statut, s.nom as name, s.rowid as socid"; $sql.=" FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; $sql.= ", ".MAIN_DB_PREFIX."societe as s"; -if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +if (empty($user->rights->societe->client->voir) && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE c.fk_soc = s.rowid"; $sql.= " AND c.entity IN (".getEntity("supplier_order").")"; $sql.= " AND c.fk_statut = 1"; if ($socid) $sql.= " AND c.fk_soc = ".((int) $socid); -if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .((int) $user->id); +if (empty($user->rights->societe->client->voir) && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .((int) $user->id); $sql.= " ORDER BY c.rowid DESC"; $resql=$db->query($sql); @@ -417,7 +417,7 @@ print "
    '; if ($action == 'editline' && $lineid == $objp->dispatchlineid) { - print ''; + print ''; } else { print $objp->qty; } @@ -1294,13 +1295,13 @@ if ($id > 0 || !empty($ref)) { if ($action != 'editline' || $lineid != $objp->dispatchlineid) { if (empty($reception->id) || ($reception->statut == Reception::STATUS_DRAFT)) { // only allow edit on draft reception print ''; - print 'dispatchlineid.'#line_'.$objp->dispatchlineid.'">'; + print 'dispatchlineid.'#line_'.$objp->dispatchlineid.'">'; print img_edit(); print ''; print ''; - print 'dispatchlineid.'#dispatch_received_products">'; + print 'dispatchlineid.'#dispatch_received_products">'; print img_delete(); print ''; print '

    "; } */ -print '
    '; +print ''; $parameters = array('user' => $user); $reshook = $hookmanager->executeHooks('dashboardOrdersSuppliers', $parameters, $object); // Note that $action and $object may have been modified by hook diff --git a/htdocs/fourn/commande/info.php b/htdocs/fourn/commande/info.php index 9de144f1f90..09bf1ab08e6 100644 --- a/htdocs/fourn/commande/info.php +++ b/htdocs/fourn/commande/info.php @@ -74,7 +74,7 @@ if ($user->socid) { } $result = restrictedArea($user, 'fournisseur', $id, 'commande_fournisseur', 'commande'); -if (!$user->rights->fournisseur->commande->lire) { +if (empty($user->rights->fournisseur->commande->lire)) { accessforbidden(); } @@ -144,7 +144,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -162,9 +162,10 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 4ceea8fde2c..419e75b55aa 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -70,6 +70,23 @@ $search_date_delivery_endyear = GETPOST('search_date_delivery_endyear', 'int'); $search_date_delivery_start = dol_mktime(0, 0, 0, $search_date_delivery_startmonth, $search_date_delivery_startday, $search_date_delivery_startyear); // Use tzserver $search_date_delivery_end = dol_mktime(23, 59, 59, $search_date_delivery_endmonth, $search_date_delivery_endday, $search_date_delivery_endyear); +$search_date_valid_startday = GETPOST('search_date_valid_startday', 'int'); +$search_date_valid_startmonth = GETPOST('search_date_valid_startmonth', 'int'); +$search_date_valid_startyear = GETPOST('search_date_valid_startyear', 'int'); +$search_date_valid_endday = GETPOST('search_date_valid_endday', 'int'); +$search_date_valid_endmonth = GETPOST('search_date_valid_endmonth', 'int'); +$search_date_valid_endyear = GETPOST('search_date_valid_endyear', 'int'); +$search_date_valid_start = dol_mktime(0, 0, 0, $search_date_valid_startmonth, $search_date_valid_startday, $search_date_valid_startyear); // Use tzserver +$search_date_valid_end = dol_mktime(23, 59, 59, $search_date_valid_endmonth, $search_date_valid_endday, $search_date_valid_endyear); +$search_date_approve_startday = GETPOST('search_date_approve_startday', 'int'); +$search_date_approve_startmonth = GETPOST('search_date_approve_startmonth', 'int'); +$search_date_approve_startyear = GETPOST('search_date_approve_startyear', 'int'); +$search_date_approve_endday = GETPOST('search_date_approve_endday', 'int'); +$search_date_approve_endmonth = GETPOST('search_date_approve_endmonth', 'int'); +$search_date_approve_endyear = GETPOST('search_date_approve_endyear', 'int'); +$search_date_approve_start = dol_mktime(0, 0, 0, $search_date_approve_startmonth, $search_date_approve_startday, $search_date_approve_startyear); // Use tzserver +$search_date_approve_end = dol_mktime(23, 59, 59, $search_date_approve_endmonth, $search_date_approve_endday, $search_date_approve_endyear); + $sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); $search_product_category = GETPOST('search_product_category', 'int'); @@ -134,10 +151,6 @@ if (!$sortorder) { $sortorder = 'DESC'; } -if ($search_status == '') { - $search_status = -1; -} - // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new CommandeFournisseur($db); $hookmanager->initHooks(array('supplierorderlist')); @@ -188,7 +201,9 @@ $arrayfields = array( 'cf.datec'=>array('label'=>"DateCreation", 'checked'=>0, 'position'=>500), 'cf.tms'=>array('label'=>"DateModificationShort", 'checked'=>0, 'position'=>500), 'cf.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), - 'cf.billed'=>array('label'=>"Billed", 'checked'=>1, 'position'=>1000, 'enabled'=>1) + 'cf.billed'=>array('label'=>"Billed", 'checked'=>1, 'position'=>1000, 'enabled'=>1), + 'cf.date_valid' =>array('label' => 'DateValidation', 'checked' => 0), + 'cf.date_approve' =>array('label' => 'DateApprove', 'checked' => 0) ); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; @@ -245,7 +260,7 @@ if (empty($reshook)) { $search_multicurrency_montant_tva = ''; $search_multicurrency_montant_ttc = ''; $search_project_ref = ''; - $search_status = -1; + $search_status = ''; $search_date_order_startday = ''; $search_date_order_startmonth = ''; $search_date_order_startyear = ''; @@ -262,6 +277,22 @@ if (empty($reshook)) { $search_date_delivery_endyear = ''; $search_date_delivery_start = ''; $search_date_delivery_end = ''; + $search_date_valid_startday = ''; + $search_date_valid_startmonth = ''; + $search_date_valid_startyear = ''; + $search_date_valid_endday = ''; + $search_date_valid_endmonth = ''; + $search_date_valid_endyear = ''; + $search_date_valid_start = ''; + $search_date_valid_end = ''; + $search_date_approve_startday = ''; + $search_date_approve_startmonth = ''; + $search_date_approve_startyear = ''; + $search_date_approve_endday = ''; + $search_date_approve_endmonth = ''; + $search_date_approve_endyear = ''; + $search_date_approve_start = ''; + $search_date_approve_end = ''; $billed = ''; $search_billed = ''; $toselect = ''; @@ -277,9 +308,42 @@ if (empty($reshook)) { $objectlabel = 'SupplierOrders'; $permissiontoread = $user->rights->fournisseur->commande->lire; $permissiontodelete = $user->rights->fournisseur->commande->supprimer; + $permissiontovalidate = $user->rights->fournisseur->commande->creer; $uploaddir = $conf->fournisseur->commande->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + if ($action == 'validate' && $permissiontovalidate) { + if (GETPOST('confirm') == 'yes') { + $objecttmp = new CommandeFournisseur($db); + $db->begin(); + $error = 0; + + foreach ($toselect as $checked) { + if ($objecttmp->fetch($checked)) { + if ($objecttmp->statut == 0) { + $objecttmp->date_commande = dol_now(); + $result = $objecttmp->valid($user); + if ($result >= 0) { + // If we have permission, and if we don't need to provide the idwarehouse, we go directly on approved step + if (empty($conf->global->SUPPLIER_ORDER_NO_DIRECT_APPROVE) && $user->rights->fournisseur->commande->approuver && !(!empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_VALIDATE_ORDER) && $objecttmp->hasProductsOrServices(1))) { + $result = $objecttmp->approve($user); + setEventMessages($langs->trans("SupplierOrderValidatedAndApproved"), array($objecttmp->ref)); + } else { + setEventMessages($langs->trans("SupplierOrderValidated"), array($objecttmp->ref)); + } + } else { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + } + } + } + } + + if (!$error) $db->commit(); + else $db->rollback(); + } + } + // Mass action to generate vendor bills if ($massaction == 'confirm_createsupplierbills') { $orders = GETPOST('toselect', 'array'); @@ -551,6 +615,42 @@ if (empty($reshook)) { if ($search_date_delivery_endyear) { $param .= '&search_date_delivery_endyear='.urlencode($search_date_delivery_endyear); } + if ($search_date_valid_startday) { + $param .= '&search_date_valid_startday='.urlencode($search_date_valid_startday); + } + if ($search_date_valid_startmonth) { + $param .= '&search_date_valid_startmonth='.urlencode($search_date_valid_startmonth); + } + if ($search_date_valid_startyear) { + $param .= '&search_date_valid_startyear='.urlencode($search_date_valid_startyear); + } + if ($search_date_valid_endday) { + $param .= '&search_date_valid_endday='.urlencode($search_date_valid_endday); + } + if ($search_date_valid_endmonth) { + $param .= '&search_date_valid_endmonth='.urlencode($search_date_valid_endmonth); + } + if ($search_date_valid_endyear) { + $param .= '&search_date_valid_endyear='.urlencode($search_date_valid_endyear); + } + if ($search_date_approve_startday) { + $param .= '&search_date_approve_startday='.urlencode($search_date_approve_startday); + } + if ($search_date_approve_startmonth) { + $param .= '&search_date_approve_startmonth='.urlencode($search_date_approve_startmonth); + } + if ($search_date_approve_startyear) { + $param .= '&search_date_approve_startyear='.urlencode($search_date_approve_startyear); + } + if ($search_date_approve_endday) { + $param .= '&search_date_approve_endday='.urlencode($search_date_approve_endday); + } + if ($search_date_approve_endmonth) { + $param .= '&search_date_approve_endmonth='.urlencode($search_date_approve_endmonth); + } + if ($search_date_approve_endyear) { + $param .= '&search_date_approve_endyear='.urlencode($search_date_approve_endyear); + } if ($search_ref) { $param .= '&search_ref='.urlencode($search_ref); } @@ -644,7 +744,7 @@ if ($sall || $search_product_category > 0 || $search_user > 0) { $sql .= ' s.rowid as socid, s.nom as name, s.town, s.zip, s.fk_pays, s.client, s.code_client, s.email,'; $sql .= " typent.code as typent_code,"; $sql .= " state.code_departement as state_code, state.nom as state_name,"; -$sql .= " cf.rowid, cf.ref, cf.ref_supplier, cf.fk_statut, cf.billed, cf.total_ht, cf.total_tva, cf.total_ttc, cf.fk_user_author, cf.date_commande as date_commande, cf.date_livraison as date_livraison,"; +$sql .= " cf.rowid, cf.ref, cf.ref_supplier, cf.fk_statut, cf.billed, cf.total_ht, cf.total_tva, cf.total_ttc, cf.fk_user_author, cf.date_commande as date_commande, cf.date_livraison as date_livraison,cf.date_valid, cf.date_approve,"; $sql .= ' cf.fk_multicurrency, cf.multicurrency_code, cf.multicurrency_tx, cf.multicurrency_total_ht, cf.multicurrency_total_tva, cf.multicurrency_total_ttc,'; $sql .= ' cf.date_creation as date_creation, cf.tms as date_update,'; $sql .= ' cf.note_public, cf.note_private,'; @@ -677,7 +777,7 @@ if ($search_product_category > 0) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON cf.fk_user_author = u.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = cf.fk_projet"; // We'll need this table joined to the select in order to filter by sale -if ($search_sale > 0 || (!$user->rights->societe->client->voir && !$socid)) { +if ($search_sale > 0 || (empty($user->rights->societe->client->voir) && !$socid)) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } if ($search_user > 0) { @@ -692,7 +792,7 @@ $sql .= ' AND cf.entity IN ('.getEntity('supplier_order').')'; if ($socid > 0) { $sql .= " AND s.rowid = ".((int) $socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($search_ref) { @@ -735,6 +835,18 @@ if ($search_date_delivery_start) { if ($search_date_delivery_end) { $sql .= " AND cf.date_livraison <= '".$db->idate($search_date_delivery_end)."'"; } +if ($search_date_valid_start) { + $sql .= " AND cf.date_commande >= '".$db->idate($search_date_valid_start)."'"; +} +if ($search_date_valid_end) { + $sql .= " AND cf.date_commande <= '".$db->idate($search_date_valid_end)."'"; +} +if ($search_date_approve_start) { + $sql .= " AND cf.date_livraison >= '".$db->idate($search_date_approve_start)."'"; +} +if ($search_date_approve_end) { + $sql .= " AND cf.date_livraison <= '".$db->idate($search_date_approve_end)."'"; +} if ($search_town) { $sql .= natural_search('s.town', $search_town); } @@ -876,6 +988,42 @@ if ($resql) { if ($search_date_delivery_endyear) { $param .= '&search_date_delivery_endyear='.urlencode($search_date_delivery_endyear); } + if ($search_date_valid_startday) { + $param .= '&search_date_valid_startday='.urlencode($search_date_valid_startday); + } + if ($search_date_valid_startmonth) { + $param .= '&search_date_valid_startmonth='.urlencode($search_date_valid_startmonth); + } + if ($search_date_valid_startyear) { + $param .= '&search_date_valid_startyear='.urlencode($search_date_valid_startyear); + } + if ($search_date_valid_endday) { + $param .= '&search_date_valid_endday='.urlencode($search_date_valid_endday); + } + if ($search_date_valid_endmonth) { + $param .= '&search_date_valid_endmonth='.urlencode($search_date_valid_endmonth); + } + if ($search_date_valid_endyear) { + $param .= '&search_date_valid_endyear='.urlencode($search_date_valid_endyear); + } + if ($search_date_approve_startday) { + $param .= '&search_date_approve_startday='.urlencode($search_date_approve_startday); + } + if ($search_date_approve_startmonth) { + $param .= '&search_date_approve_startmonth='.urlencode($search_date_approve_startmonth); + } + if ($search_date_approve_startyear) { + $param .= '&search_date_approve_startyear='.urlencode($search_date_approve_startyear); + } + if ($search_date_approve_endday) { + $param .= '&search_date_approve_endday='.urlencode($search_date_approve_endday); + } + if ($search_date_approve_endmonth) { + $param .= '&search_date_approve_endmonth='.urlencode($search_date_approve_endmonth); + } + if ($search_date_approve_endyear) { + $param .= '&search_date_approve_endyear='.urlencode($search_date_approve_endyear); + } if ($search_ref) { $param .= '&search_ref='.urlencode($search_ref); } @@ -947,6 +1095,15 @@ if ($resql) { 'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), 'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), ); + + if ($permissiontovalidate) { + if ($user->rights->fournisseur->commande->approuver && empty($conf->global->SUPPLIER_ORDER_NO_DIRECT_APPROVE)) { + $arrayofmassactions['prevalidate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ValidateAndApprove"); + } else { + $arrayofmassactions['prevalidate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"); + } + } + if ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer) { $arrayofmassactions['createbills'] = img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("CreateInvoiceForThisSupplier"); } @@ -986,6 +1143,10 @@ if ($resql) { $trackid = 'sord'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + if ($massaction == 'prevalidate') { + print $form->formconfirm($_SERVER["PHP_SELF"].$fieldstosearchall, $langs->trans("ConfirmMassValidation"), $langs->trans("ConfirmMassValidationQuestion"), "validate", null, '', 0, 200, 500, 1); + } + if ($massaction == 'createbills') { //var_dump($_REQUEST); print ''; @@ -1237,6 +1398,28 @@ if ($resql) { print $form->selectyesno('search_billed', $search_billed, 1, 0, 1, 1); print ''; } + // Date valid + if (!empty($arrayfields['cf.date_valid']['checked'])) { + print ''; + print '
    '; + print $form->selectDate($search_date_valid_start ? $search_date_valid_start : -1, 'search_date_valid_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search_date_valid_end ? $search_date_valid_end : -1, 'search_date_valid_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + print ''; + } + // Date approve + if (!empty($arrayfields['cf.date_approve']['checked'])) { + print ''; + print '
    '; + print $form->selectDate($search_date_approve_start ? $search_date_approve_start : -1, 'search_date_approve_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); + print '
    '; + print '
    '; + print $form->selectDate($search_date_approve_end ? $search_date_approve_end : -1, 'search_date_approve_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('to')); + print '
    '; + print ''; + } // Action column print ''; $searchpicto = $form->showFilterButtons(); @@ -1328,6 +1511,12 @@ if ($resql) { if (!empty($arrayfields['cf.billed']['checked'])) { print_liste_field_titre($arrayfields['cf.billed']['label'], $_SERVER["PHP_SELF"], 'cf.billed', '', $param, '', $sortfield, $sortorder, 'center '); } + if (!empty($arrayfields['cf.date_valid']['checked'])) { + print_liste_field_titre($arrayfields['cf.date_valid']['label'], $_SERVER["PHP_SELF"], "cf.date_valid", "", $param, '', $sortfield, $sortorder, 'center '); + } + if (!empty($arrayfields['cf.date_approve']['checked'])) { + print_liste_field_titre($arrayfields['cf.date_approve']['label'], $_SERVER["PHP_SELF"], 'cf.date_approve', '', $param, '', $sortfield, $sortorder, 'center '); + } print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'center maxwidthsearch '); print "\n"; @@ -1626,6 +1815,25 @@ if ($resql) { } } + // valid date + if (!empty($arrayfields['cf.date_valid']['checked'])) { + print ''; + print dol_print_date($db->jdate($obj->date_valid), 'day'); + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // approve date + if (!empty($arrayfields['cf.date_approve']['checked'])) { + print ''; + print dol_print_date($db->jdate($obj->date_approve), 'day'); + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Action column print ''; if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined diff --git a/htdocs/fourn/commande/note.php b/htdocs/fourn/commande/note.php index b3e7d33e5d9..1c67c03d727 100644 --- a/htdocs/fourn/commande/note.php +++ b/htdocs/fourn/commande/note.php @@ -111,7 +111,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -129,9 +129,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php index a152ca26ff1..1efd78df372 100644 --- a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; @@ -55,7 +55,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { echo price($objectlink->total_ht); } ?> getLibStatut(3); ?> - ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> + ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> liste_limit; */ $sql = "SELECT s.rowid as socid, s.nom as name, st.libelle as stcomm, p.rowid as cidp, p.lastname, p.firstname, p.email, p.phone"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user "; } $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."socpeople as p, ".MAIN_DB_PREFIX."c_stcomm as st"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.fk_stcomm = st.id"; $sql .= " AND s.fournisseur = 1"; $sql .= " AND s.rowid = p.fk_soc"; $sql .= " AND s.entity IN (".getEntity('societe').")"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php old mode 100644 new mode 100755 index d2c7ce613d4..7ad7d434f46 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -423,9 +423,9 @@ if (empty($reshook)) { dol_print_error($db); } } elseif ($action == 'setdatef' && $usercancreate) { - $newdate = dol_mktime(0, 0, 0, $_POST['datefmonth'], $_POST['datefday'], $_POST['datefyear']); - if ($newdate > (dol_now() + (empty($conf->global->INVOICE_MAX_OFFSET_IN_FUTURE) ? 0 : $conf->global->INVOICE_MAX_OFFSET_IN_FUTURE))) { - if (empty($conf->global->INVOICE_MAX_OFFSET_IN_FUTURE)) { + $newdate = dol_mktime(0, 0, 0, GETPOST('datefmonth', 'int'), GETPOST('datefday', 'int'), GETPOST('datefyear', 'int'), 'tzserver'); + if ($newdate > (dol_now('tzuserrel') + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + if (empty($conf->global->INVOICE_MAX_FUTURE_DELAY)) { setEventMessages($langs->trans("WarningInvoiceDateInFuture"), null, 'warnings'); } else { setEventMessages($langs->trans("WarningInvoiceDateTooFarInFuture"), null, 'warnings'); @@ -449,7 +449,7 @@ if (empty($reshook)) { } } elseif ($action == 'setdate_lim_reglement' && $usercancreate) { $object->fetch($id); - $object->date_echeance = dol_mktime(12, 0, 0, $_POST['date_lim_reglementmonth'], $_POST['date_lim_reglementday'], $_POST['date_lim_reglementyear']); + $object->date_echeance = dol_mktime(12, 0, 0, GETPOST('date_lim_reglementmonth', 'int'), GETPOST('date_lim_reglementday', 'int'), GETPOST('date_lim_reglementyear', 'int')); if (!empty($object->date_echeance) && $object->date_echeance < $object->date) { $object->date_echeance = $object->date; setEventMessages($langs->trans("DatePaymentTermCantBeLowerThanObjectDate"), null, 'warnings'); @@ -695,6 +695,7 @@ if (empty($reshook)) { if ($socid > 0) { $object->socid = GETPOST('socid', 'int'); } + $selectedLines = GETPOST('toselect', 'array'); $db->begin(); @@ -706,8 +707,12 @@ if (empty($reshook)) { $error++; } - $dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); - $datedue = dol_mktime(12, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int')); + $dateinvoice = dol_mktime(0, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'), 'tzserver'); // If we enter the 02 january, we need to save the 02 january for server + $datedue = dol_mktime(0, 0, 0, GETPOST('echmonth', 'int'), GETPOST('echday', 'int'), GETPOST('echyear', 'int'), 'tzserver'); + /*var_dump($dateinvoice.' '.dol_print_date($dateinvoice, 'dayhour')); + var_dump(dol_now('tzuserrel').' '.dol_get_last_hour(dol_now('tzuserrel')).' '.dol_print_date(dol_now('tzuserrel'),'dayhour').' '.dol_print_date(dol_get_last_hour(dol_now('tzuserrel')), 'dayhour')); + var_dump($db->idate($dateinvoice)); + exit;*/ // Replacement invoice if (GETPOST('type') == FactureFournisseur::TYPE_REPLACEMENT) { @@ -716,7 +721,7 @@ if (empty($reshook)) { $action = 'create'; $_GET['socid'] = $_POST['socid']; $error++; - } elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors'); $action = 'create'; @@ -780,7 +785,7 @@ if (empty($reshook)) { $action = 'create'; $_GET['socid'] = $_POST['socid']; $error++; - } elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors'); $action = 'create'; @@ -889,7 +894,7 @@ if (empty($reshook)) { $action = 'create'; $_GET['socid'] = $_POST['socid']; $error++; - } elseif ($dateinvoice > (dol_get_last_hour(dol_now()) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { + } elseif ($dateinvoice > (dol_get_last_hour(dol_now('tzuserrel')) + (empty($conf->global->INVOICE_MAX_FUTURE_DELAY) ? 0 : $conf->global->INVOICE_MAX_FUTURE_DELAY))) { $error++; setEventMessages($langs->trans("ErrorDateIsInFuture"), null, 'errors'); $action = 'create'; @@ -1127,6 +1132,10 @@ if (empty($reshook)) { $num = count($lines); for ($i = 0; $i < $num; $i++) { // TODO handle subprice < 0 + if (!in_array($lines[$i]->id, $selectedLines)) { + continue; // Skip unselected lines + } + $desc = ($lines[$i]->desc ? $lines[$i]->desc : $lines[$i]->libelle); $product_type = ($lines[$i]->product_type ? $lines[$i]->product_type : 0); @@ -2276,7 +2285,7 @@ if ($action == 'create') { } if (empty($reshook)) { - print $object->showOptionals($extrafields, 'edit'); + print $object->showOptionals($extrafields, 'create'); } // Public note @@ -2359,9 +2368,6 @@ if ($action == 'create') { print $form->buttonsSaveCancel("CreateDraft"); - print "\n"; - - // Show origin lines if (is_object($objectsrc)) { print '
    '; @@ -2371,10 +2377,12 @@ if ($action == 'create') { print ''; - $objectsrc->printOriginLinesList(); + $objectsrc->printOriginLinesList('', $selectedLines); print '
    '; } + + print "\n"; } else { if ($id > 0 || !empty($ref)) { // @@ -2409,6 +2417,15 @@ if ($action == 'create') { // $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + // Multicurrency + if (!empty($conf->multicurrency->enabled)) { + $multicurrency_totalpaye = $object->getSommePaiement(1); + $multicurrency_totalcreditnotes = $object->getSumCreditNotesUsed(1); + $multicurrency_totaldeposits = $object->getSumDepositsUsed(1); + $multicurrency_resteapayer = price2num($object->multicurrency_total_ttc - $multicurrency_totalpaye - $multicurrency_totalcreditnotes - $multicurrency_totaldeposits, 'MT'); + $resteapayer = price2num($multicurrency_resteapayer / $object->multicurrency_tx, 'MT'); + } + if ($object->paye) { $resteapayer = 0; } @@ -2546,11 +2563,11 @@ if ($action == 'create') { } // Confirmation set paid - if ($action == 'paid' && $resteapayer <= 0) { + if ($action == 'paid' && ($resteapayer <= 0 || (!empty($conf->global->SUPPLIER_INVOICE_CAN_ADD_PAYMENT_EVEN_IF_ALREADY_PAID) && $resteapayer == $object->total_ttc))) { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ClassifyPaid'), $langs->trans('ConfirmClassifyPaidBill', $object->ref), 'confirm_paid', '', 0, 1); } - if ($action == 'paid' && $resteapayer > 0) { + if ($action == 'paid' && $resteapayer > 0 && (empty($conf->global->SUPPLIER_INVOICE_CAN_ADD_PAYMENT_EVEN_IF_ALREADY_PAID) || $resteapayer != $object->total_ttc)) { $close = array(); // Code $i = 0; @@ -2654,7 +2671,7 @@ if ($action == 'create') { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($usercancreate) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -2671,9 +2688,10 @@ if ($action == 'create') { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -2703,8 +2721,12 @@ if ($action == 'create') { } if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) { $facusing = new FactureFournisseur($db); - $facusing->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).')'; + if ($object->fk_facture_source > 0) { + $facusing->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).')'; + } else { + print ' ('.$langs->transnoentities("CorrectedInvoiceNotFound").')'; + } } $facidavoir = $object->getListIdAvoirFromInvoice(); @@ -2771,7 +2793,7 @@ if ($action == 'create') { print $langs->trans('PaymentConditions'); print ''; if ($action != 'editconditions' && $form_permission) { - print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetConditions'), 1).''; } print ''; print ''; @@ -2800,7 +2822,7 @@ if ($action == 'create') { print $langs->trans('PaymentMode'); print ''; if ($action != 'editmode' && $form_permission2) { - print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetMode'), 1).''; } print ''; print ''; @@ -2820,7 +2842,7 @@ if ($action == 'create') { print $form->editfieldkey('Currency', 'multicurrency_code', '', $object, 0); print ''; if ($action != 'editmulticurrencycode' && $object->statut == $object::STATUS_DRAFT) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -2839,7 +2861,7 @@ if ($action == 'create') { print $form->editfieldkey('CurrencyRate', 'multicurrency_tx', '', $object, 0); print ''; if ($action != 'editmulticurrencyrate' && $object->statut == $object::STATUS_DRAFT && $object->multicurrency_code && $object->multicurrency_code != $conf->currency) { - print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; + print 'id.'">'.img_edit($langs->transnoentitiesnoconv('SetMultiCurrencyCode'), 1).''; } print ''; print ''; @@ -2867,7 +2889,7 @@ if ($action == 'create') { print $langs->trans('BankAccount'); print ''; if ($action != 'editbankaccount' && $usercancreate) { - print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; + print 'id.'">'.img_edit($langs->trans('SetBankAccount'), 1).''; } print ''; print ''; @@ -2887,7 +2909,7 @@ if ($action == 'create') { print $langs->trans('IncotermLabel'); print ''; if ($usercancreate) { - print ''.img_edit().''; + print ''.img_edit().''; } else { print ' '; } @@ -2910,7 +2932,7 @@ if ($action == 'create') { print $langs->trans('IntracommReportTransportMode'); print ''; if ($action != 'editmode' && ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer)) { - print 'id.'">'.img_edit().''; + print 'id.'">'.img_edit().''; } print ''; print ''; @@ -2931,7 +2953,6 @@ if ($action == 'create') { print ''; print '
    '; - print '
    '; print '
    '; print ''; @@ -3308,7 +3329,6 @@ if ($action == 'create') { print '
    '; print '
    '; - print '
    '; print ''; print ''; @@ -3398,7 +3418,7 @@ if ($action == 'create') { $ventilExportCompta = $object->getVentilExportCompta(); // Should be 0 since the sum of payments are zero. But we keep the protection. if ($ventilExportCompta == 0) { - print ''.$langs->trans('Modify').''; + print ''.$langs->trans('Modify').''; } else { print ''.$langs->trans('Modify').''; } @@ -3413,7 +3433,7 @@ if ($action == 'create') { || ($object->type == FactureFournisseur::TYPE_DEPOSIT && empty($discount->id))) && ($object->statut == FactureFournisseur::STATUS_CLOSED || $object->statut == FactureFournisseur::STATUS_ABANDONED)) { // A paid invoice (partially or completely) if (!$facidnext && $object->close_code != 'replaced' && $usercancreate) { // Not replaced by another invoice - print ''.$langs->trans('ReOpen').''; + print ''.$langs->trans('ReOpen').''; } else { if ($usercancreate) { print ''.$langs->trans('ReOpen').''; @@ -3480,14 +3500,17 @@ if ($action == 'create') { } // Classify paid - if (($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && (($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->type != FactureFournisseur::TYPE_DEPOSIT && $resteapayer <= 0) || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $resteapayer >= 0))) - || ($object->type == FactureFournisseur::TYPE_DEPOSIT && $object->paye == 0 && $object->total_ttc > 0 && $resteapayer == 0 && empty($discount->id)) + if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && ( + ($object->type != FactureFournisseur::TYPE_CREDIT_NOTE && $object->type != FactureFournisseur::TYPE_DEPOSIT && ($resteapayer <= 0 || (!empty($conf->global->SUPPLIER_INVOICE_CAN_ADD_PAYMENT_EVEN_IF_ALREADY_PAID) && $object->total_ttc == $resteapayer))) || + ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $resteapayer >= 0) || + ($object->type == FactureFournisseur::TYPE_DEPOSIT && $object->total_ttc > 0 && ($resteapayer == 0 || (!empty($conf->global->SUPPLIER_INVOICE_CAN_ADD_PAYMENT_EVEN_IF_ALREADY_PAID) && $object->total_ttc == $resteapayer))) + ) ) { print ''.$langs->trans('ClassifyPaid').''; } // Classify 'closed not completely paid' (possible if validated and not yet filed paid) - if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && $resteapayer > 0) { + if ($object->statut == FactureFournisseur::STATUS_VALIDATED && $object->paye == 0 && $resteapayer > 0 && (empty($conf->global->SUPPLIER_INVOICE_CAN_ADD_PAYMENT_EVEN_IF_ALREADY_PAID) || $object->total_ttc != $resteapayer)) { if ($totalpaye > 0 || $totalcreditnotes > 0) { // If one payment or one credit note was linked to this invoice print ''.$langs->trans('ClassifyPaidPartially').''; @@ -3531,7 +3554,7 @@ if ($action == 'create') { } elseif ($isErasable <= 0) { // Any other cases print ''.$langs->trans('Delete').''; } else { - print ''.$langs->trans('Delete').''; + print ''.$langs->trans('Delete').''; } } print ''; @@ -3557,17 +3580,14 @@ if ($action == 'create') { $linktoelem = $form->showLinkToObjectBlock($object, null, array('invoice_supplier')); $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; - //print ''; - //print '
    '; + print '
    '; // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'invoice_supplier', $socid, 1, 'listaction'.($genallowed ? 'largetitle' : '')); - print '
    '; - //print ''; + print ''; } } } diff --git a/htdocs/fourn/facture/contact.php b/htdocs/fourn/facture/contact.php index 22892823f05..927cc5f36b9 100644 --- a/htdocs/fourn/facture/contact.php +++ b/htdocs/fourn/facture/contact.php @@ -142,7 +142,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->facture->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -160,9 +160,10 @@ if ($id > 0 || !empty($ref)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fourn/facture/document.php b/htdocs/fourn/facture/document.php index d7c11045f03..d94eacdbc8d 100644 --- a/htdocs/fourn/facture/document.php +++ b/htdocs/fourn/facture/document.php @@ -77,6 +77,8 @@ if ($object->fetch($id, $ref)) { $upload_dir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id, 2, 0, 0, $object, 'invoice_supplier').$ref; } +$permissiontoadd = ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer); // Used by the include of actions_setnotes.inc.php + /* * Actions @@ -118,7 +120,7 @@ if ($object->id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->facture->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -136,9 +138,10 @@ if ($object->id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fourn/facture/index.php b/htdocs/fourn/facture/index.php index 5479ad22462..21d3e4cfa58 100644 --- a/htdocs/fourn/facture/index.php +++ b/htdocs/fourn/facture/index.php @@ -73,7 +73,6 @@ if ($tmp) { print ''; print '
    '; -print '
    '; $tmp = getPurchaseInvoiceLatestEditTable($maxLatestEditCount, $socid); if ($tmp) { @@ -87,7 +86,6 @@ if ($tmp) { print '
    '; } -print '
    '; print '
    '; print ''; diff --git a/htdocs/fourn/facture/info.php b/htdocs/fourn/facture/info.php index efe91880a56..f17d3c3e127 100644 --- a/htdocs/fourn/facture/info.php +++ b/htdocs/fourn/facture/info.php @@ -86,7 +86,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->facture->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -104,9 +104,10 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 358b1c59c1b..7dbead5536b 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -119,7 +119,7 @@ $search_btn = GETPOST('button_search', 'alpha'); $search_remove_btn = GETPOST('button_removefilter', 'alpha'); $search_categ_sup = trim(GETPOST("search_categ_sup", 'int')); -$option = GETPOST('option'); +$option = GETPOST('search_option'); if ($option == 'late') { $search_status = '1'; } @@ -418,7 +418,7 @@ $sql .= " typent.code as typent_code,"; $sql .= " state.code_departement as state_code, state.nom as state_name,"; $sql .= " country.code as country_code,"; $sql .= " p.rowid as project_id, p.ref as project_ref, p.title as project_label,"; -$sql .= " u.login"; +$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'; if ($search_categ_sup && $search_categ_sup != '-1') { $sql .= ", cs.fk_categorie, cs.fk_soc"; } @@ -441,7 +441,7 @@ $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s'; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as country on (country.rowid = s.fk_pays)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_typent as typent on (typent.id = s.fk_typent)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as state on (state.rowid = s.fk_departement)"; -if (!empty($search_categ_sup)) { +if (!empty($search_categ_sup) && $search_categ_supplier != '-1') { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_fournisseur as cs ON s.rowid = cs.fk_soc"; } @@ -461,7 +461,7 @@ if ($search_product_category > 0) { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'user AS u ON f.fk_user_author = u.rowid'; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = f.fk_projet"; // We'll need this table joined to the select in order to filter by sale -if ($search_sale > 0 || (!$user->rights->societe->client->voir && !$socid)) { +if ($search_sale > 0 || (empty($user->rights->societe->client->voir) && !$socid)) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } if ($search_user > 0) { @@ -474,7 +474,7 @@ $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object $sql .= $hookmanager->resPrint; $sql .= ' WHERE f.fk_soc = s.rowid'; $sql .= ' AND f.entity IN ('.getEntity('facture_fourn').')'; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($search_product_category > 0) { @@ -634,7 +634,7 @@ if (!$search_all) { $sql .= " state.code_departement, state.nom,"; $sql .= ' country.code,'; $sql .= " p.rowid, p.ref, p.title,"; - $sql .= " u.login"; + $sql .= " u.login, u.lastname, u.firstname, u.email, u.statut, u.entity, u.photo, u.office_phone, u.office_fax, u.user_mobile, u.job, u.gender"; if ($search_categ_sup && $search_categ_sup != '-1') { $sql .= ", cs.fk_categorie, cs.fk_soc"; } @@ -803,7 +803,7 @@ if ($resql) { $param .= '&show_files='.urlencode($show_files); } if ($option) { - $param .= "&option=".urlencode($option); + $param .= "&search_option=".urlencode($option); } if ($optioncss != '') { $param .= '&optioncss='.urlencode($optioncss); @@ -975,13 +975,13 @@ if ($resql) { // Ref if (!empty($arrayfields['f.ref']['checked'])) { print ''; - print ''; + print ''; print ''; } // Ref supplier if (!empty($arrayfields['f.ref_supplier']['checked'])) { print ''; - print ''; + print ''; print ''; } // Type @@ -1006,7 +1006,7 @@ if ($resql) { // Label if (!empty($arrayfields['f.label']['checked'])) { print ''; - print ''; + print ''; print ''; } // Date invoice @@ -1037,11 +1037,11 @@ if ($resql) { } // Project if (!empty($arrayfields['p.ref']['checked'])) { - print ''; + print ''; } // Thirpdarty if (!empty($arrayfields['s.nom']['checked'])) { - print ''; + print ''; } // Town if (!empty($arrayfields['s.town']['checked'])) { @@ -1096,13 +1096,13 @@ if ($resql) { if (!empty($arrayfields['f.total_localtax1']['checked'])) { // Amount tax 1 print ''; - print ''; + print ''; print ''; } if (!empty($arrayfields['f.total_localtax2']['checked'])) { // Amount tax 2 print ''; - print ''; + print ''; print ''; } if (!empty($arrayfields['f.total_ttc']['checked'])) { @@ -1428,9 +1428,9 @@ if ($resql) { // Date limit if (!empty($arrayfields['f.date_lim_reglement']['checked'])) { - print ''.dol_print_date($datelimit, 'day'); + print ''.dol_print_date($datelimit, 'day'); if ($facturestatic->hasDelay()) { - print img_warning($langs->trans('Late')); + print img_warning($langs->trans('Alert').' - '.$langs->trans('Late')); } print ''; if (!$i) { @@ -1585,13 +1585,25 @@ if ($resql) { $totalarray['val']['f.total_ttc'] += $obj->total_ttc; } + $userstatic->id = $obj->fk_user_author; + $userstatic->login = $obj->login; + $userstatic->lastname = $obj->lastname; + $userstatic->firstname = $obj->firstname; + $userstatic->email = $obj->user_email; + $userstatic->statut = $obj->user_statut; + $userstatic->entity = $obj->entity; + $userstatic->photo = $obj->photo; + $userstatic->office_phone = $obj->office_phone; + $userstatic->office_fax = $obj->office_fax; + $userstatic->user_mobile = $obj->user_mobile; + $userstatic->job = $obj->job; + $userstatic->gender = $obj->gender; + // Author if (!empty($arrayfields['u.login']['checked'])) { - $userstatic->id = $obj->fk_user_author; - $userstatic->login = $obj->login; - print ''; + print ''; if ($userstatic->id) { - print $userstatic->getLoginUrl(1); + print $userstatic->getLoginUrl(-1); } else { print ' '; } diff --git a/htdocs/fourn/facture/note.php b/htdocs/fourn/facture/note.php index c5ea5feac68..d59aefe7831 100644 --- a/htdocs/fourn/facture/note.php +++ b/htdocs/fourn/facture/note.php @@ -115,7 +115,7 @@ if ($object->id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->fournisseur->commande->creer || $user->rights->supplier_order->creer) { if ($action != 'classify') { - // $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + // $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -133,9 +133,10 @@ if ($object->id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index fcbfdcf7b45..71a15023343 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -360,16 +360,16 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie $sql = 'SELECT s.nom as name, s.rowid as socid,'; $sql .= ' f.rowid, f.ref, f.ref_supplier, f.total_ttc as total, f.fk_mode_reglement, f.fk_account'; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user "; } $sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s, '.MAIN_DB_PREFIX.'facture_fourn as f'; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= ' WHERE f.fk_soc = s.rowid'; $sql .= ' AND f.rowid = '.((int) $facid); - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $resql = $db->query($sql); @@ -641,13 +641,19 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print ''; if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) { - print price($objp->multicurrency_am); + print price($sign * $multicurrency_payment); + if ($multicurrency_creditnotes) { + print '+'.price($multicurrency_creditnotes); + } + if ($multicurrency_deposits) { + print '+'.price($multicurrency_deposits); + } } print ''; print ''; if ($objp->multicurrency_code && $objp->multicurrency_code != $conf->currency) { - print price($objp->multicurrency_total_ttc - $objp->multicurrency_am); + print price($sign * $multicurrency_remaintopay); } print ''; } @@ -676,10 +682,10 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie print img_picto("Auto fill", 'rightarrow', "class='AutoFillAmout' data-rowname='".$namef."' data-value='".($sign * $remaintopay)."'"); } print ''; - print ''; // class is requied to be used by javascript callForResult(); + print ''; // class is requied to be used by javascript callForResult(); } else { print ''; - print ''; // class is requied to be used by javascript callForResult(); + print ''; // class is requied to be used by javascript callForResult(); } print ""; diff --git a/htdocs/fourn/facture/rapport.php b/htdocs/fourn/facture/rapport.php index fe2bb78008d..59b92f349c0 100644 --- a/htdocs/fourn/facture/rapport.php +++ b/htdocs/fourn/facture/rapport.php @@ -46,7 +46,7 @@ if ($user->socid > 0) { } $dir = $conf->fournisseur->facture->dir_output.'/payments'; -if (!$user->rights->societe->client->voir || $socid) { +if (empty($user->rights->societe->client->voir) || $socid) { $dir .= '/private/'.$user->id; // If user has no permission to see all, output dir is specific to user } diff --git a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php index ae600ec4080..3f728d99567 100644 --- a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php @@ -25,7 +25,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; @@ -71,7 +71,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { echo $objectlink->getLibStatut(3); } ?> - ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> + ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?>
    '; $sql = "SELECT count(cf.rowid), cf.fk_statut"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as cf,"; $sql .= " ".MAIN_DB_PREFIX."societe as s"; -if (!$user->rights->societe->client->voir && !$socid) { +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 cf.fk_soc = s.rowid "; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND sc.fk_user = ".((int) $user->id); } $sql .= " AND cf.entity = ".$conf->entity; @@ -106,11 +106,11 @@ if ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SU $sql .= " s.nom as name, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as cf"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + 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 cf.fk_soc = s.rowid"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND sc.fk_user = ".((int) $user->id); } $sql .= " AND cf.entity = ".$conf->entity; @@ -162,11 +162,11 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S $sql .= ", s.nom as name, s.rowid as socid"; $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as ff"; $sql .= ", ".MAIN_DB_PREFIX."societe as s"; - if (!$user->rights->societe->client->voir && !$socid) { + 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 s.rowid = ff.fk_soc"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND sc.fk_user = ".((int) $user->id); } $sql .= " AND ff.entity = ".$conf->entity; @@ -221,25 +221,32 @@ if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_S } -//print ''; -print '
    '; +print '
    '; /* * List last modified supliers */ $max = 10; -$sql = "SELECT s.rowid as socid, s.nom as name, s.town, s.datec, s.tms, s.prefix_comm, s.code_fournisseur, s.code_compta_fournisseur"; +$sql = "SELECT s.rowid as socid, s.nom as name, s.town, s.datec, s.tms, s.prefix_comm, s.code_fournisseur"; +if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { + $sql .= ", spe.accountancy_code_supplier as code_compta_fournisseur"; +} else { + $sql .= ", s.code_compta_fournisseur"; +} $sql .= ", st.libelle as stcomm"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; +if (!empty($conf->global->MAIN_COMPANY_PERENTITY_SHARED)) { + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity); +} $sql .= ", ".MAIN_DB_PREFIX."c_stcomm as st"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE s.fk_stcomm = st.id"; $sql .= " AND s.fournisseur = 1"; $sql .= " AND s.entity IN (".getEntity('societe').")"; -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -310,8 +317,7 @@ if (count($companystatic->SupplierCategories)) { } -//print "\n"; -print '
    '; +print ''; // End of page llxFooter(); diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 708fa266f0a..f8f484f0cc9 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -135,6 +135,13 @@ $upload_dir = $conf->fournisseur->payment->dir_output; $permissiontoadd = true; include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; +// Actions to send emails +$triggersendname = 'PAYMENTRECEIPT_SENTBYMAIL'; +$paramname = 'id'; +$autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO'; +$trackid = 'pre'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + /* * View @@ -334,6 +341,18 @@ if ($result > 0) { */ print '
    '; + + // Send by mail + if ($user->socid == 0 && $action == '') { + $usercansend = (empty($conf->global->MAIN_USE_ADVANCED_PERMS)); + if ($usercansend) { + print ''.$langs->trans('SendMail').''; + } else { + print ''.$langs->trans('SendMail').''; + } + } + + // Payment validation if (!empty($conf->global->BILL_ADD_PAYMENT_VALIDATION)) { if ($user->socid == 0 && $object->statut == 0 && $action == '') { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && (!empty($user->rights->fournisseur->facture->creer) || !empty($user->rights->supplier_invoice->creer))) @@ -342,10 +361,12 @@ if ($result > 0) { } } } + + // Delete payment if ($user->socid == 0 && $action == '') { if ($user->rights->fournisseur->facture->supprimer) { if ($allow_delete) { - print ''.$langs->trans('Delete').''; + print ''.$langs->trans('Delete').''; } else { print ''.$langs->trans('Delete').''; } @@ -371,7 +392,7 @@ if ($result > 0) { $somethingshown = $formfile->numoffiles; } - print '
    '; + print '
    '; //print '
    '; // List of actions on element @@ -380,7 +401,16 @@ if ($result > 0) { $somethingshown = $formactions->showactions($object,'supplier_payment',$socid,1,'listaction'.($genallowed?'largetitle':'')); */ - print '
    '; + print ''; + + // Presend form + $modelmail = ''; //TODO: Add new 'payment receipt' model in email models + $defaulttopic = 'SendPaymentReceipt'; + $diroutput = $conf->fournisseur->payment->dir_output; + $autocopy = 'MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO'; + $trackid = 'pre'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } else { $langs->load("errors"); print $langs->trans("ErrorRecordNotFound"); diff --git a/htdocs/fourn/paiement/document.php b/htdocs/fourn/paiement/document.php new file mode 100644 index 00000000000..a29e9b0713c --- /dev/null +++ b/htdocs/fourn/paiement/document.php @@ -0,0 +1,180 @@ + + * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2005 Marc Barilley / Ocebo + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2012 Marcos García + * Copyright (C) 2013 Cédric Salvador + * Copyright (C) 2017 Ferran Marcet + * Copyright (C) 2021 Jesus Jerez + * + * 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/fourn/paiement/document.php + * \ingroup facture, fournisseur + * \brief Management page of attached documents to a payment + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; +if (!empty($conf->projet->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +} + +// Load translation files required by the page +$langs->loadLangs(array('bills', 'banks', 'companies', 'suppliers', 'other')); + +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); + +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, $object->element, $object->id, 'paiementfourn', ''); + +// Get parameters +$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 (!$sortorder) { + $sortorder = "ASC"; +} +if (!$sortfield) { + $sortfield = "name"; +} + +// Load object +$object = new PaiementFourn($db); +if ($object->fetch($id, $ref)) { + $object->fetch_thirdparty(); + $ref = dol_sanitizeFileName($object->ref); + $upload_dir = $conf->fournisseur->payment->dir_output.'/'.dol_sanitizeFileName($object->ref); +} + +$permissiontoadd = ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer); // Used by the include of actions_setnotes.inc.php + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans('Payment')." - ".$langs->trans('Documents'); +llxHeader('', $title); + +if ($object->id > 0) { + $head = payment_supplier_prepare_head($object); + print dol_get_fiche_head($head, 'documents', $langs->trans("SupplierPayment"), -1, 'payment'); + + // Supplier order card + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + + // Date of payment + $morehtmlref .= $form->editfieldkey("Date", 'datep', $object->date, $object, $object->statut == 0 && ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer), 'datehourpicker', '', null, 3).': '; + $morehtmlref .= $form->editfieldval("Date", 'datep', $object->date, $object, $object->statut == 0 && ($user->rights->fournisseur->facture->creer || $user->rights->supplier_invoice->creer), 'datehourpicker', '', null, $langs->trans('PaymentDateUpdateSucceeded')); + + // Payment mode + $morehtmlref .= '
    '.$langs->trans('PaymentMode').' : '; + $morehtmlref .= $langs->trans("PaymentType".$object->type_code) != ("PaymentType".$object->type_code) ? $langs->trans("PaymentType".$object->type_code) : $object->type_label; + $morehtmlref .= $object->num_payment ? ' - '.$object->num_payment : ''; + + // Thirdparty + $morehtmlref .= '
    '.$langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1); + + // Amount + $morehtmlref .= '
    '.$langs->trans('Amount').' : '. price($object->amount, '', $langs, 0, 0, -1, $conf->currency); + + $allow_delete = 1; + // Bank account + if (!empty($conf->banque->enabled)) { + if ($object->fk_account) { + $bankline = new AccountLine($db); + $bankline->fetch($object->bank_line); + if ($bankline->rappro) { + $allow_delete = 0; + $title_button = dol_escape_htmltag($langs->transnoentitiesnoconv("CantRemoveConciliatedPayment")); + } + + $morehtmlref .= '
    '.$langs->trans('BankAccount').' : '; + $accountstatic = new Account($db); + $accountstatic->fetch($bankline->fk_account); + $morehtmlref .= $accountstatic->getNomUrl(1); + + $morehtmlref .= '
    '.$langs->trans('BankTransactionLine').' : '; + $morehtmlref .= $bankline->getNomUrl(1, 0, 'showconciliated'); + } + } + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + // 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']; + } + + 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 = 'supplier_payment'; + // TODO: get the appropriate permission + $permissiontoadd = true; + $permtoedit = true; + $param = '&id='.$object->id; + include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; +} else { + header('Location: index.php'); + exit; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/fourn/paiement/list.php b/htdocs/fourn/paiement/list.php index 8534ad8bac1..c4e18d50f90 100644 --- a/htdocs/fourn/paiement/list.php +++ b/htdocs/fourn/paiement/list.php @@ -48,6 +48,9 @@ $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 've $socid = GETPOST('socid', 'int'); +// Security check +if ($user->socid) $socid = $user->socid; + $search_ref = GETPOST('search_ref', 'alpha'); $search_date_startday = GETPOST('search_date_startday', 'int'); $search_date_startmonth = GETPOST('search_date_startmonth', 'int'); @@ -174,7 +177,7 @@ $sql = 'SELECT p.rowid, p.ref, p.datep, p.amount as pamount, p.num_paiement'; $sql .= ', s.rowid as socid, s.nom as name, s.email'; $sql .= ', c.code as paiement_type, c.libelle as paiement_libelle'; $sql .= ', ba.rowid as bid, ba.label'; -if (!$user->rights->societe->client->voir) { +if (empty($user->rights->societe->client->voir)) { $sql .= ', sc.fk_soc, sc.fk_user'; } $sql .= ', SUM(pf.amount)'; @@ -186,12 +189,12 @@ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement AS c ON p.fk_paiement = c.id'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe AS s ON s.rowid = f.fk_soc'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; -if (!$user->rights->societe->client->voir) { +if (empty($user->rights->societe->client->voir)) { $sql .= ', '.MAIN_DB_PREFIX.'societe_commerciaux as sc'; } $sql .= ' WHERE f.entity = '.$conf->entity; -if (!$user->rights->societe->client->voir) { +if (empty($user->rights->societe->client->voir)) { $sql .= ' AND s.rowid = sc.fk_soc AND sc.fk_user = '.((int) $user->id); } if ($socid > 0) { @@ -230,7 +233,7 @@ if ($search_all) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; $sql .= ' GROUP BY p.rowid, p.ref, p.datep, p.amount, p.num_paiement, s.rowid, s.nom, s.email, c.code, c.libelle, ba.rowid, ba.label'; -if (!$user->rights->societe->client->voir) { +if (empty($user->rights->societe->client->voir)) { $sql .= ', sc.fk_soc, sc.fk_user'; } diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index ac38a130bfa..e84fb79c7e3 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -338,25 +338,25 @@ if (empty($reshook)) { // If no start date if (empty($_POST['date_debut_'])) { - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=nodatedebut'); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'&error=nodatedebut'); exit; } // If no end date if (empty($_POST['date_fin_'])) { - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=nodatefin'); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'&error=nodatefin'); exit; } // If start date after end date if ($date_debut > $date_fin) { - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=datefin'); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'&error=datefin'); exit; } // If no validator designated if ($approverid < 1) { - header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&error=Valideur'); + header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'&error=Valideur'); exit; } @@ -567,9 +567,10 @@ if (empty($reshook)) { $nbopenedday = num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday); $soldeActuel = $object->getCpforUser($object->fk_user, $object->fk_type); $newSolde = ($soldeActuel - $nbopenedday); + $label = $langs->transnoentitiesnoconv("Holidays").' - '.$object->ref; // The modification is added to the LOG - $result = $object->addLogCP($user->id, $object->fk_user, $langs->transnoentitiesnoconv("Holidays"), $newSolde, $object->fk_type); + $result = $object->addLogCP($user->id, $object->fk_user, $label, $newSolde, $object->fk_type); if ($result < 0) { $error++; setEventMessages(null, $object->errors, 'errors'); @@ -881,7 +882,7 @@ $object = new Holiday($db); $listhalfday = array('morning'=>$langs->trans("Morning"), "afternoon"=>$langs->trans("Afternoon")); -$title = $langs->trans('CPTitreMenu'); +$title = $langs->trans('Leave'); $help_url = 'EN:Module_Holiday'; llxHeader('', $title, $help_url); @@ -1087,7 +1088,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { print ''; print ''.$langs->trans("DescCP").''; print ''; - $doleditor = new DolEditor('description', GETPOST('description', 'restricthtml'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + $doleditor = new DolEditor('description', GETPOST('description', 'restricthtml'), '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, ROWS_3, '90%'); print $doleditor->Create(1); print ''; @@ -1157,7 +1158,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { setEventMessages($errors, null, 'errors'); } - // On vérifie si l'utilisateur à le droit de lire cette demande + // check if the user has the right to read this request if ($canread) { $head = holiday_prepare_head($object); @@ -1288,7 +1289,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { print ''; print ''.$langs->trans('DescCP').''; print ''; - $doleditor = new DolEditor('description', $object->description, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); + $doleditor = new DolEditor('description', $object->description, '', 80, 'dolibarr_notes', 'In', 0, false, empty($conf->fckeditor->enabled) ? false : $conf->fckeditor->enabled, ROWS_3, '90%'); print $doleditor->Create(1); print ''; } @@ -1301,7 +1302,6 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { print '
    '; print '
    '; - print '
    '; print '
    '; @@ -1338,7 +1338,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { } $include_users = $object->fetch_users_approver_holiday(); if (is_array($include_users) && in_array($user->id, $include_users) && $object->statut == Holiday::STATUS_VALIDATED) { - print ''.img_edit($langs->trans("Edit")).''; + print ''.img_edit($langs->trans("Edit")).''; } print ''; print ''; @@ -1390,7 +1390,6 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { print ''; print ''; - print '
    '; print '
    '; print ''; @@ -1434,11 +1433,9 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { if (($action == 'edit' && $object->statut == Holiday::STATUS_DRAFT) || ($action == 'editvalidator')) { if ($action == 'edit' && $object->statut == Holiday::STATUS_DRAFT) { - print '
    '; if ($cancreate && $object->statut == Holiday::STATUS_DRAFT) { - print ''; + print $form->buttonsSaveCancel(); } - print '
    '; } print ''; @@ -1450,11 +1447,11 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { print '
    '; if ($cancreate && $object->statut == Holiday::STATUS_DRAFT) { - print ''.$langs->trans("EditCP").''; + print ''.$langs->trans("EditCP").''; } if ($cancreate && $object->statut == Holiday::STATUS_DRAFT) { // If draft - print ''.$langs->trans("Validate").''; + print ''.$langs->trans("Validate").''; } if ($object->statut == Holiday::STATUS_VALIDATED) { // If validated @@ -1522,7 +1519,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { $action = 'presend'; } - if ($action != 'presend') { + if ($action != 'presend' && $action != 'edit') { print '
    '; print ''; // ancre @@ -1544,20 +1541,16 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { //$somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; + print '
    '; $MAXEVENT = 10; - /*$morehtmlright = ''; - $morehtmlright .= $langs->trans("SeeAll"); - $morehtmlright .= '';*/ - // 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, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); - print '
    '; + print '
    '; } } } diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 81e1a5394f3..89760c4d1ac 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -701,6 +701,7 @@ class Holiday extends CommonObject public function validate($user = null, $notrigger = 0) { global $conf, $langs; + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $error = 0; // Define new ref @@ -740,6 +741,44 @@ class Holiday extends CommonObject } } + if (!$error) { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { + // Now we rename also files into index + $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filename = CONCAT('" . $this->db->escape($this->newref) . "', SUBSTR(filename, " . (strlen($this->ref) + 1) . ")), filepath = 'holiday/" . $this->db->escape($this->newref) . "'"; + $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'holiday/" . $this->db->escape($this->ref) . "' and entity = " . ((int) $conf->entity); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->error = $this->db->lasterror(); + } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->holiday->multidir_output[$this->entity] . '/' . $oldref; + $dirdest = $conf->holiday->multidir_output[$this->entity] . '/' . $newref; + if (!$error && file_exists($dirsource)) { + dol_syslog(get_class($this) . "::validate rename dir " . $dirsource . " into " . $dirdest); + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($dirdest, 'files', 1, '^' . preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource); + $dirsource = $fileentry['path'] . '/' . $dirsource; + $dirdest = $fileentry['path'] . '/' . $dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Commit or rollback if ($error) { foreach ($this->errors as $errmsg) { @@ -1266,16 +1305,16 @@ class Holiday extends CommonObject if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("mymodule"); - $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('DraftCP'); - $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('ToReviewCP'); - $this->labelStatus[self::STATUS_APPROVED] = $langs->trans('ApprovedCP'); - $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('CancelCP'); - $this->labelStatus[self::STATUS_REFUSED] = $langs->trans('RefuseCP'); - $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('DraftCP'); - $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('ToReviewCP'); - $this->labelStatusShort[self::STATUS_APPROVED] = $langs->trans('ApprovedCP'); - $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('CancelCP'); - $this->labelStatusShort[self::STATUS_REFUSED] = $langs->trans('RefuseCP'); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP'); + $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP'); + $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('DraftCP'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('ToReviewCP'); + $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('ApprovedCP'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('CancelCP'); + $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('RefuseCP'); } $params = array(); @@ -1447,7 +1486,7 @@ class Holiday extends CommonObject // Update each user counter foreach ($users as $userCounter) { - $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newByMonth']) ? $typeleaves[$userCounter['type']]['newByMonth'] : 0); + $nbDaysToAdd = (isset($typeleaves[$userCounter['type']]['newbymonth']) ? $typeleaves[$userCounter['type']]['newbymonth'] : 0); if (empty($nbDaysToAdd)) { continue; } @@ -1936,7 +1975,7 @@ class Holiday extends CommonObject * * @param int $fk_user_action Id user creation * @param int $fk_user_update Id user update - * @param string $label Label + * @param string $label Label (Example: 'Leave', 'Manual update', 'Leave request cancelation'...) * @param int $new_solde New value * @param int $fk_type Type of vacation * @return int Id of record added, 0 if nothing done, < 0 if KO @@ -2081,7 +2120,7 @@ class Holiday extends CommonObject { global $mysoc; - $sql = "SELECT rowid, code, label, affect, delay, newByMonth"; + $sql = "SELECT rowid, code, label, affect, delay, newbymonth"; $sql .= " FROM ".MAIN_DB_PREFIX."c_holiday_types"; $sql .= " WHERE (fk_country IS NULL OR fk_country = ".((int) $mysoc->country_id).')'; if ($active >= 0) { @@ -2096,7 +2135,7 @@ class Holiday extends CommonObject $num = $this->db->num_rows($result); if ($num) { while ($obj = $this->db->fetch_object($result)) { - $types[$obj->rowid] = array('rowid'=> $obj->rowid, 'code'=> $obj->code, 'label'=>$obj->label, 'affect'=>$obj->affect, 'delay'=>$obj->delay, 'newByMonth'=>$obj->newByMonth); + $types[$obj->rowid] = array('rowid'=> $obj->rowid, 'code'=> $obj->code, 'label'=>$obj->label, 'affect'=>$obj->affect, 'delay'=>$obj->delay, 'newbymonth'=>$obj->newbymonth); } return $types; diff --git a/htdocs/holiday/define_holiday.php b/htdocs/holiday/define_holiday.php index fdcdb5f88e6..621443fb408 100644 --- a/htdocs/holiday/define_holiday.php +++ b/htdocs/holiday/define_holiday.php @@ -358,7 +358,7 @@ if (count($typeleaves) == 0) { //var_dump($users['rowid'].' - '.$val['rowid']); print ''; if ($canedit) { - print ''; + print ''; } else { print $nbtoshow; } diff --git a/htdocs/holiday/document.php b/htdocs/holiday/document.php index c4e779efe52..b11b795723c 100644 --- a/htdocs/holiday/document.php +++ b/htdocs/holiday/document.php @@ -120,6 +120,7 @@ if ($user->socid) { } $result = restrictedArea($user, 'holiday', $object->id, 'holiday'); +$permissiontoadd = $user->rights->holiday->write; // Used by the include of actions_setnotes.inc.php /* @@ -136,8 +137,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; $form = new Form($db); $listhalfday = array('morning'=>$langs->trans("Morning"), "afternoon"=>$langs->trans("Afternoon")); - -$title = $langs->trans('InterventionCard'); +$title = $langs->trans("Leave").' - '.$langs->trans("Files"); llxHeader('', $title); @@ -283,7 +283,6 @@ if ($object->id) { /* print ''; print '
    '; - print '
    '; print '
    '; @@ -340,7 +339,6 @@ if ($object->id) { print ''; print ''; - print '
    '; print '
    '; */ print ''; @@ -348,12 +346,12 @@ if ($object->id) { print dol_get_fiche_end(); - - - $modulepart = 'holiday'; $permissiontoadd = $user->rights->holiday->write; $permtoedit = $user->rights->holiday->write; $param = '&id='.$object->id; + $relativepathwithnofile = dol_sanitizeFileName($object->ref).'/'; + $savingdocmask = dol_sanitizeFileName($object->ref).'-__file__'; + include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; } else { print $langs->trans("ErrorUnknown"); diff --git a/htdocs/holiday/info.php b/htdocs/holiday/info.php index 3ec95e61a52..5df3a5069de 100644 --- a/htdocs/holiday/info.php +++ b/htdocs/holiday/info.php @@ -78,7 +78,7 @@ $result = restrictedArea($user, 'holiday', $object->id, 'holiday'); $form = new Form($db); -$title = $langs->trans("Holiday")." - ".$langs->trans("Info"); +$title = $langs->trans("Leave")." - ".$langs->trans("Info"); $helpurl = ""; llxHeader("", $title, $helpurl); diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index 6aecff5eac0..953f5eabb2f 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -631,6 +631,12 @@ if ($resql) { print ''; } + // End date + if (!empty($arrayfields['cp.date_valid']['checked'])) { + print ''; + print ''; + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook @@ -691,6 +697,9 @@ if ($resql) { if (!empty($arrayfields['cp.date_fin']['checked'])) { print_liste_field_titre($arrayfields['cp.date_fin']['label'], $_SERVER["PHP_SELF"], "cp.date_fin", "", $param, '', $sortfield, $sortorder, 'center '); } + if (!empty($arrayfields['cp.date_valid']['checked'])) { + print_liste_field_titre($arrayfields['cp.date_valid']['label'], $_SERVER["PHP_SELF"], "cp.date_valid", "", $param, '', $sortfield, $sortorder, 'center '); + } // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields @@ -820,6 +829,18 @@ if ($resql) { $totalarray['nbfield']++; } } + if (!empty($arrayfields['cp.date_valid']['checked'])) { // date_valid is both date_valid but also date_approval + print ''; + print dol_print_date($db->jdate($obj->date_valid), 'day'); + print ''; + if (!$i) $totalarray['nbfield']++; + } + /*if (!empty($arrayfields['cp.date_approve']['checked'])) { + print ''; + print dol_print_date($db->jdate($obj->date_approve), 'day'); + print ''; + if (!$i) $totalarray['nbfield']++; + }*/ // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; diff --git a/htdocs/hrm/admin/admin_establishment.php b/htdocs/hrm/admin/admin_establishment.php index f5baeee4027..dd17a2be4b0 100644 --- a/htdocs/hrm/admin/admin_establishment.php +++ b/htdocs/hrm/admin/admin_establishment.php @@ -21,7 +21,7 @@ * \brief HRM Establishment module setup page */ require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/hrm.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm.lib.php'; require_once DOL_DOCUMENT_ROOT.'/hrm/class/establishment.class.php'; // Load translation files required by the page @@ -80,12 +80,12 @@ $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; // Subheader $linkback = ''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("HRMSetup"), $linkback); +print load_fiche_titre($langs->trans("HRMSetup"), $linkback, 'title_setup'); $newcardbutton = dolGetButtonTitle($langs->trans('NewEstablishment'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/hrm/establishment/card.php?action=create&backtopage='.urlencode($_SERVER['PHP_SELF']), '', $permissiontoadd); // Configuration header -$head = hrm_admin_prepare_head(); +$head = hrmAdminPrepareHead(); print dol_get_fiche_head($head, 'establishments', $langs->trans("HRM"), -1, "user", 0, $newcardbutton); $sql = "SELECT e.rowid, e.rowid as ref, e.label, e.address, e.zip, e.town, e.status"; diff --git a/htdocs/hrm/class/establishment.class.php b/htdocs/hrm/class/establishment.class.php index a9082a02b5e..88e93f1398f 100644 --- a/htdocs/hrm/class/establishment.class.php +++ b/htdocs/hrm/class/establishment.class.php @@ -369,10 +369,10 @@ class Establishment extends CommonObject if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("mymodule"); - $this->labelStatus[self::STATUS_OPEN] = $langs->trans('Open'); - $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('Closed'); - $this->labelStatusShort[self::STATUS_OPEN] = $langs->trans('Open'); - $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('Closed'); + $this->labelStatus[self::STATUS_OPEN] = $langs->transnoentitiesnoconv('Open'); + $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Closed'); + $this->labelStatusShort[self::STATUS_OPEN] = $langs->transnoentitiesnoconv('Open'); + $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Closed'); } $statusType = 'status'.$status; diff --git a/htdocs/hrm/class/evaluation.class.php b/htdocs/hrm/class/evaluation.class.php new file mode 100644 index 00000000000..75dc03cc6f2 --- /dev/null +++ b/htdocs/hrm/class/evaluation.class.php @@ -0,0 +1,1145 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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/evaluation.class.php + * \ingroup hrm + * \brief This file is a CRUD class file for Evaluation (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 . '/hrm/class/evaluationdet.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class for Evaluation + */ +class Evaluation extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'hrm'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'evaluation'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'hrm_evaluation'; + + /** + * @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; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for evaluation. Must be the part after the 'object_' into object_evaluation.png + */ + public $picto = 'label'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + const STATUS_CLOSED = 6; + + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', '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 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: '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. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // 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', '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'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'showoncombobox'=>'2',), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), + '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'=>5, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '6' => 'Closed'),), + 'date_eval' => array('type'=>'date', 'label'=>'DateEval', 'enabled'=>'1', 'position'=>502, 'notnull'=>1, 'visible'=>1,), + 'fk_user' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'User', 'enabled'=>'1', 'position'=>504, 'notnull'=>1, 'visible'=>1,), + 'fk_job' => array('type'=>'integer:Job:/hrm/class/job.class.php', 'label'=>'Job', 'enabled'=>'1', 'position'=>505, 'notnull'=>1, 'visible'=>1,), + ); + public $rowid; + public $ref; + public $label; + public $description; + public $note_public; + public $note_private; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $import_key; + public $status; + public $date_eval; + public $fk_user; + public $fk_job; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + /** + * @var string Name of subtable line + */ + public $table_element_line = 'hrm_evaluationdet'; + + /** + * @var string Field with ID of parent key if this object has a parent + */ + public $fk_element = 'fk_evaluation'; + + /** + * @var string Name of subtable class that manage subtable lines + */ + public $class_element_line = 'Evaluationline'; + + // /** + // * @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('@Evaluationline:hrm/class/evaluationdet.class.php:fk_evaluation'); + + /** + * @var Evaluationline[] Array of subtable lines + */ + public $lines = array(); + + + + /** + * 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; + } + + $this->date_eval = dol_now(); + + // 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); + + if ($resultcreate > 0) { + require_once DOL_DOCUMENT_ROOT . '/hrm/class/skillrank.class.php'; + $skillRank = new SkillRank($this->db); + $TRequiredRanks = $skillRank->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_object='.$this->fk_job." AND objecttype='job'")); + + if (is_array($TRequiredRanks) && !empty($TRequiredRanks)) { + $this->lines = array(); + foreach ($TRequiredRanks as $required) { + $line = new Evaluationline($this->db); + $line->fk_evaluation = $resultcreate; + $line->fk_skill = $required->fk_skill; + $line->required_rank = $required->rank; + $line->fk_rank = 0; + + $res = $line->create($user, $notrigger); + if ($res > 0) $this->lines[] = $line; + } + } + } + + 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(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * 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.'='.$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); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * 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; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $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(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " 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('EVALUATION_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + } + + if (!$error) { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'evaluation/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'evaluation/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; $this->error = $this->db->lasterror(); + } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->hrm->dir_output.'/evaluation/'.$oldref; + $dirdest = $conf->hrm->dir_output.'/evaluation/'.$newref; + if (!$error && file_exists($dirsource)) { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->hrm->dir_output.'/evaluation/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) { + $this->ref = $num; + $this->status = self::STATUS_VALIDATED; + } + + if (!$error) { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + + /** + * Get the last evaluation by date for the user assigned + * + * @param int $fk_user ID of user we need to get last eval + * @return Evaluation|null + */ + public function getLastEvaluationForUser($fk_user) + { + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."hrm_evaluation "; + $sql.= "WHERE fk_user=".((int) $fk_user)." "; + $sql.= "ORDER BY date_eval DESC "; + $sql.= "LIMIT 1 "; + + $res = $this->db->query($sql); + if (!$res) { dol_print_error($this->db);} + + $Tab = $this->db->fetch_object($res); + + if (empty($Tab)) return null; + else { + $evaluation = new Evaluation($this->db); + $evaluation->fetch($Tab->rowid); + + return $evaluation; + } + } + + + /** + * 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, 'EVALUATION_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, 'EVALUATION_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, 'EVALUATION_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("Evaluation").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + + $url = dol_buildpath('/hrm/evaluation_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("ShowEvaluation"); + $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('evaluationdao')); + $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 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("hrm"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated'); + $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Closed'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated'); + $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Closed'); + } + + $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(); + + $objectline = new Evaluationline($this->db); + $result = $objectline->fetchAll('ASC', '', 0, 0, array('customsql'=>'fk_evaluation = '.$this->id)); + + if (is_numeric($result)) { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("hrm"); + + if (empty($conf->global->HRMTEST_EVALUATION_ADDON)) { + $conf->global->HRMTEST_EVALUATION_ADDON = 'mod_evaluation_standard'; + } + + if (!empty($conf->global->HRMTEST_EVALUATION_ADDON)) { + $mybool = false; + + $file = $conf->global->HRMTEST_EVALUATION_ADDON.".php"; + $classname = $conf->global->HRMTEST_EVALUATION_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/hrm/"); + + // 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 = 0; + + $langs->load("hrm"); + + if (!dol_strlen($modele)) { + $modele = 'standard_evaluation'; + + if (!empty($this->model_pdf)) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->EVALUATION_ADDON_PDF)) { + $modele = $conf->global->EVALUATION_ADDON_PDF; + } + } + + $modelpath = "core/modules/hrm/doc/"; + + if ($includedocgeneration && !empty($modele)) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * 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; + } + + /** + * @param string $action + * @param int $selected + */ + // public function printObjectLines($action, $selected = 0) + // { + // global $conf, $hookmanager, $langs, $user, $extrafields, $object; + // // TODO We should not use global var for this + // global $inputalsopricewithtax, $usemargins, $disableedit, $disablemove, $disableremove, $outputalsopricetotalwithtax; + // + // // Define usemargins + //// $usemargins = 0; + //// if (!empty($conf->margin->enabled) && !empty($this->element) && in_array($this->element, array('facture', 'facturerec', 'propal', 'commande'))) { + //// $usemargins = 1; + //// } + // + // $num = count($this->lines); + // + // // Line extrafield + // if (!is_object($extrafields)) { + // require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + // $extrafields = new ExtraFields($this->db); + // } + // $extrafields->fetch_name_optionals_label($this->table_element_line); + // + // $parameters = array('num'=>$num, 'selected'=>$selected, 'table_element_line'=>$this->table_element_line); + // $reshook = $hookmanager->executeHooks('printObjectLineTitle', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + // if (empty($reshook)) { + // // Output template part (modules that overwrite templates must declare this into descriptor) + // // Note: This is deprecated. If you need to overwrite the tpl file, use instead the hook. + // include dol_buildpath('hrm/core/tpl/objectline_title.tpl.php'); + // } + // + // $i = 0; + // + // print "\n"; + // foreach ($this->lines as $line) { + // //Line extrafield + // $line->fetch_optionals(); + // + // //if (is_object($hookmanager) && (($line->product_type == 9 && ! empty($line->special_code)) || ! empty($line->fk_parent_line))) + // if (is_object($hookmanager)) { // Old code is commented on preceding line. + // if (empty($line->fk_parent_line)) { + // $parameters = array('line'=>$line, 'num'=>$num, 'i'=>$i, 'selected'=>$selected, 'table_element_line'=>$line->table_element); + // $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + // } else { + // $parameters = array('line'=>$line, 'num'=>$num, 'i'=>$i, 'selected'=>$selected, 'table_element_line'=>$line->table_element, 'fk_parent_line'=>$line->fk_parent_line); + // $reshook = $hookmanager->executeHooks('printObjectSubLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + // } + // } + // if (empty($reshook)) { + // $this->printObjectLine($action, $line); + // } + // + // $i++; + // } + // print "\n"; + // } + + // public function printObjectLine($action, $line) + // { + // global $conf, $langs, $user, $object, $hookmanager; + // global $form; + // global $object_rights, $disableedit, $disablemove, $disableremove; // TODO We should not use global var for this ! + // + // $object_rights = $this->getRights(); + // + // $element = $this->element; + // + // $text = ''; + // $description = ''; + // + // include dol_buildpath('hrm/tpl/objectline_view.tpl.php'); + // } +} diff --git a/htdocs/hrm/class/evaluationdet.class.php b/htdocs/hrm/class/evaluationdet.class.php new file mode 100644 index 00000000000..115571bb6ba --- /dev/null +++ b/htdocs/hrm/class/evaluationdet.class.php @@ -0,0 +1,1045 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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/evaluationdet.class.php + * \ingroup hrm + * \brief This file is a CRUD class file for Evaluationdet (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 . '/hrm/class/skillrank.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; +//require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + +/** + * Class for Evaluationline + */ +class Evaluationline extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'hrm'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'evaluationdet'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'hrm_evaluationdet'; + + /** + * @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; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for evaluationdet. Must be the part after the 'object_' into object_evaluationdet.png + */ + public $picto = 'evaluationdet@hrm'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', '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 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: '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. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // 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', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + '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,), + 'fk_skill' => array('type'=>'integer:Skill:hrm/class/skill.class.php:1', 'label'=>'Skill', 'enabled'=>'1', 'position'=>3, 'notnull'=>1, 'visible'=>1, 'index'=>1,), + 'fk_evaluation' => array('type'=>'integer:Evaluation:hrm/class/evaluation.class.php:1', 'label'=>'Evaluation', 'enabled'=>'1', 'position'=>3, 'notnull'=>1, 'visible'=>1, 'index'=>1,), + 'rankorder' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>'1', 'position'=>4, 'notnull'=>1, 'visible'=>1,), + 'required_rank' => array('type'=>'integer', 'label'=>'requiredRank', 'enabled'=>'1', 'position'=>5, 'notnull'=>1, 'visible'=>1,), + 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>'1', 'position'=>1000, 'notnull'=>-1, 'visible'=>-2,), + ); + public $rowid; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $fk_skill; + public $fk_evaluation; + public $fk_rank; + public $required_rank; + public $import_key; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + // /** + // * @var string Name of subtable line + // */ + // public $table_element_line = 'hrm_evaluationline'; + + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + // public $fk_element = 'fk_evaluationdet'; + + // /** + // * @var string Name of subtable class that manage subtable lines + // */ + // public $class_element_line = 'Evaluationline'; + + // /** + // * @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('hrm_evaluationdetdet'); + + // /** + // * @var EvaluationLine[] Array of subtable lines + // */ + // public $lines = array(); + + + + /** + * 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; + } + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->hrm->evaluationdet->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 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(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * 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.'='.$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) + { + if ($this->fk_rank) { + $skillRank = new SkillRank($this->db); + $skillRank->fetch($this->fk_rank); + $skillRank->delete($user, $notrigger); + } + return $this->deleteCommon($user, $notrigger); + //return $this->deleteCommon($user, $notrigger, 1); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * 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; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->evaluationdet->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->evaluationdet->evaluationdet_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " 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('EVALUATIONLINE_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + } + + if (!$error) { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'evaluationline/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'evaluationline/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; $this->error = $this->db->lasterror(); + } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->hrm->dir_output.'/evaluationline/'.$oldref; + $dirdest = $conf->hrm->dir_output.'/evaluationline/'.$newref; + if (!$error && file_exists($dirsource)) { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->hrm->dir_output.'/evaluationline/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) { + $this->ref = $num; + $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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'EVALUATIONLINE_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'EVALUATIONLINE_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'EVALUATIONLINE_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("Evaluationdet").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + + $url = dol_buildpath('/hrm/evaluationdet_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("ShowEvaluationdet"); + $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('evaluationlinedao')); + $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 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("hrm"); + $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(); + + $objectline = new EvaluationLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_evaluationdet = '.$this->id)); + + if (is_numeric($result)) { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("hrm"); + + if (empty($conf->global->hrm_EVALUATIONLINE_ADDON)) { + $conf->global->hrm_EVALUATIONLINE_ADDON = 'mod_evaluationdet_standard'; + } + + if (!empty($conf->global->hrm_EVALUATIONLINE_ADDON)) { + $mybool = false; + + $file = $conf->global->hrm_EVALUATIONLINE_ADDON.".php"; + $classname = $conf->global->hrm_EVALUATIONLINE_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/hrm/"); + + // 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 = 0; + + $langs->load("hrm"); + + if (!dol_strlen($modele)) { + $modele = 'standard_evaluationdet'; + + if (!empty($this->model_pdf)) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->EVALUATIONLINE_ADDON_PDF)) { + $modele = $conf->global->EVALUATIONLINE_ADDON_PDF; + } + } + + $modelpath = "core/modules/hrm/doc/"; + + if ($includedocgeneration && !empty($modele)) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * 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; + } +} + + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; diff --git a/htdocs/hrm/class/job.class.php b/htdocs/hrm/class/job.class.php new file mode 100644 index 00000000000..fc94f4ba6ae --- /dev/null +++ b/htdocs/hrm/class/job.class.php @@ -0,0 +1,1103 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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/job.class.php + * \ingroup hrm + * \brief This file is a CRUD class file for Job (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 Job + */ +class Job extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'hrm'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'job'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'hrm_job'; + + /** + * @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; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for job. Must be the part after the 'object_' into object_job.png + */ + public $picto = 'technic'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', '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 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: '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. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // 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', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'label' => array('type'=>'varchar(128)', 'label'=>'Label', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Label of object"), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>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,), + 'deplacement' => array('type'=>'select', 'required'=> 1,'label'=> 'deplacement', 'enabled'=> 1, 'position'=> 90, 'notnull'=> 1, 'visible'=> 1, 'arrayofkeyval'=> array(0 =>"No", 1=>"Yes"), 'default'=>0), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>70, 'notnull'=>0, 'visible'=>0,), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>71, 'notnull'=>0, 'visible'=>0,), + '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,), + ); + public $rowid; + public $ref; + public $description; + public $date_creation; + public $tms; + public $deplacement; + public $note_public; + public $note_private; + public $fk_user_creat; + public $fk_user_modif; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + // /** + // * @var string Name of subtable line + // */ + // public $table_element_line = 'hrm_jobline'; + + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + public $fk_element = 'fk_job'; + + // /** + // * @var string Name of subtable class that manage subtable lines + // */ + // public $class_element_line = 'Jobline'; + + // /** + // * @var array List of child tables. To test if we can delete object. + // */ + protected $childtables = array('hrm_evaluation', 'hrm_job_user'); + + // /** + // * @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("@SkillRank:hrm/class/skillrank.class.php:fk_object:objecttype='job'"); + + // /** + // * @var JobLine[] Array of subtable lines + // */ + // public $lines = array(); + + + + /** + * 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; + } + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->hrm->job->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 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); + + //$resultvalidate = $this->validate($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(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * 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.'='.$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); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * 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; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->job->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->job->job_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " 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('JOB_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + } + + if (!$error) { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'job/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'job/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; $this->error = $this->db->lasterror(); + } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->hrm->dir_output.'/job/'.$oldref; + $dirdest = $conf->hrm->dir_output.'/job/'.$newref; + if (!$error && file_exists($dirsource)) { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->hrm->dir_output.'/job/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) { + $this->ref = $num; + $this->status = self::STATUS_VALIDATED; + } + + if (!$error) { + $this->db->commit(); + return 1; + } else { + $this->db->rollback(); + return -1; + } + } + + /** + * Get last job for user + * + * @param int $fk_user id of user we need to get last job + * @return mixed|string|null + */ + public function getLastJobForUser($fk_user) + { + global $db; + + $j = new Job($db); + $Tab = $j->getForUser($fk_user); + + if (empty($Tab)) return ''; + + $job = array_shift($Tab); + + return $job; + } + + /** + * Get jobs for user + * + * @param int $userid id of user we need to get job list + * @return array of jobs + */ + public function getForUser($userid) + { + global $db; + + $TReturn = array(); + $position = new Position($db); + $TPosition = $position->getForUser($userid); + foreach ($TPosition as $UPosition) { + $TReturn[$UPosition->Job->rowid] = $UPosition->Job->ref; + } + return $TReturn; + } + + /** + * 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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'JOB_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'JOB_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'JOB_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("Job").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Label').': '.$this->label; + + $url = dol_buildpath('/hrm/job_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("ShowJob"); + $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->label); + $filearray = dol_dir_list($upload_dir, "files"); + $filename = $filearray[0]['name']; + if (!empty($filename)) { + $pospoint = strpos($filearray[0]['name'], '.'); + + $pathtophoto = $class.'/'.$this->label.'/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->label; + } + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('jobdao')); + $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 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("hrm"); + $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(); + + $objectline = new JobLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_job = '.$this->id)); + + if (is_numeric($result)) { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("hrm"); + + if (empty($conf->global->hrm_JOB_ADDON)) { + $conf->global->hrm_JOB_ADDON = 'mod_job_standard'; + } + + if (!empty($conf->global->hrm_JOB_ADDON)) { + $mybool = false; + + $file = $conf->global->hrm_JOB_ADDON.".php"; + $classname = $conf->global->hrm_JOB_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/hrm/"); + + // 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 = 0; + + $langs->load("hrm"); + + if (!dol_strlen($modele)) { + $modele = 'standard_job'; + + if (!empty($this->model_pdf)) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->JOB_ADDON_PDF)) { + $modele = $conf->global->JOB_ADDON_PDF; + } + } + + $modelpath = "core/modules/hrm/doc/"; + + if ($includedocgeneration && !empty($modele)) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * 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; + } +} + + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; + +/** + * Class JobLine. You can also remove this and generate a CRUD class for lines objects. + */ +class JobLine extends CommonObjectLine +{ + // To complete with content of an object JobLine + // We should have a field rowid, fk_job and position + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 0; + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } +} diff --git a/htdocs/hrm/class/position.class.php b/htdocs/hrm/class/position.class.php new file mode 100644 index 00000000000..26298c31aa7 --- /dev/null +++ b/htdocs/hrm/class/position.class.php @@ -0,0 +1,1091 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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/position.class.php + * \ingroup hrm + * \brief This file is a CRUD class file for Position (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 Position + */ +class Position extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'hrm'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'position'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'hrm_job_user'; + + /** + * @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; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for position. Must be the part after the 'object_' into object_position.png + */ + public $picto = 'user-cog'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', '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 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: '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. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // 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', 'position'=>1, 'notnull'=>1, 'visible'=>2, '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', 'comment'=>"Reference of object"), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), + '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_contrat' => array('type'=>'integer:Contrat:contrat/class/contrat.class.php', 'label'=>'fk_contrat', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>0,), + 'fk_user' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Employee', 'enabled'=>'1', 'position'=>55, 'notnull'=>1, 'visible'=>1,), + 'fk_job' => array('type'=>'integer:Job:/hrm/class/job.class.php', 'label'=>'Job', 'enabled'=>'1', 'position'=>56, 'notnull'=>1, 'visible'=>1,), + 'date_start' => array('type'=>'date', 'label'=>'DateStart', 'enabled'=>'1', 'position'=>51, 'notnull'=>1, 'visible'=>1,), + 'date_end' => array('type'=>'date', 'label'=>'DateEnd', 'enabled'=>'1', 'position'=>52, 'notnull'=>0, 'visible'=>1,), + 'abort_comment' => array('type'=>'varchar(255)', 'label'=>'AbandonmentComment', 'enabled'=>'1', 'position'=>502, 'notnull'=>0, 'visible'=>1,), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>70, 'notnull'=>0, 'visible'=>0,), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>71, 'notnull'=>0, 'visible'=>0,), + '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,), + ); + public $rowid; + public $ref; + public $description; + public $date_creation; + public $tms; + public $fk_contrat; + public $fk_user; + public $fk_job; + public $date_start; + public $date_end; + public $abort_comment; + public $note_public; + public $note_private; + public $fk_user_creat; + public $fk_user_modif; + + + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + // /** + // * @var string Name of subtable line + // */ + // public $table_element_line = 'hrm_job_userline'; + + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + // public $fk_element = 'fk_position'; + + // /** + // * @var string Name of subtable class that manage subtable lines + // */ + // public $class_element_line = 'Positionline'; + + // /** + // * @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('hrm_job_userdet'); + + // /** + // * @var PositionLine[] Array of subtable lines + // */ + // public $lines = array(); + + + /** + * 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; + } + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->hrm->position->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 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); + + //$resultvalidate = $this->validate($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(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * 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 . '=' . $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); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * 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; + + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) { + dol_syslog(get_class($this) . "::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->position->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->position->position_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " SET ref = '" . $this->db->escape($num) . "',"; + $sql .= " 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('POSITION_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + } + + if (!$error) { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { + // Now we rename also files into index + $sql = 'UPDATE ' . MAIN_DB_PREFIX . "ecm_files set filename = CONCAT('" . $this->db->escape($this->newref) . "', SUBSTR(filename, " . (strlen($this->ref) + 1) . ")), filepath = 'position/" . $this->db->escape($this->newref) . "'"; + $sql .= " WHERE filename LIKE '" . $this->db->escape($this->ref) . "%' AND filepath = 'position/" . $this->db->escape($this->ref) . "' and entity = " . $conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->error = $this->db->lasterror(); + } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->hrm->dir_output . '/position/' . $oldref; + $dirdest = $conf->hrm->dir_output . '/position/' . $newref; + if (!$error && file_exists($dirsource)) { + dol_syslog(get_class($this) . "::validate() rename dir " . $dirsource . " into " . $dirdest); + + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->hrm->dir_output . '/position/' . $newref, 'files', 1, '^' . preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^' . preg_quote($oldref, '/') . '/', $newref, $dirsource); + $dirsource = $fileentry['path'] . '/' . $dirsource; + $dirdest = $fileentry['path'] . '/' . $dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) { + $this->ref = $num; + $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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'POSITION_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'POSITION_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'POSITION_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("Position") . ''; + if (isset($this->status)) { + $label .= ' ' . $this->getLibStatut(5); + } + $label .= '
    '; + $label .= '' . $langs->trans('Ref') . ': ' . $this->ref; + + $url = dol_buildpath('/hrm/position_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("ShowPosition"); + $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('positiondao')); + $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 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("hrm"); + $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(); + + $objectline = new PositionLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql' => 'fk_position = ' . $this->id)); + + if (is_numeric($result)) { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("hrm"); + + if (empty($conf->global->hrm_POSITION_ADDON)) { + $conf->global->hrm_POSITION_ADDON = 'mod_position_standard'; + } + + if (!empty($conf->global->hrm_POSITION_ADDON)) { + $mybool = false; + + $file = $conf->global->hrm_POSITION_ADDON . ".php"; + $classname = $conf->global->hrm_POSITION_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir . "core/modules/hrm/"); + + // 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 ""; + } + } + + /** + * @param int $userid id of user we need to get position list + * @return array|int of positions of user with for each of them the job fetched into that array + */ + public function getForUser($userid) + { + $TPosition = array(); + + $TPosition = $this->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_user=' . $userid)); + + return $TPosition; + } + + /** + * 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 = 0; + + $langs->load("hrm"); + + if (!dol_strlen($modele)) { + $modele = 'standard_position'; + + if (!empty($this->model_pdf)) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->POSITION_ADDON_PDF)) { + $modele = $conf->global->POSITION_ADDON_PDF; + } + } + + $modelpath = "core/modules/hrm/doc/"; + + if ($includedocgeneration && !empty($modele)) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * 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; + } +} + + +require_once DOL_DOCUMENT_ROOT . '/core/class/commonobjectline.class.php'; + +/** + * Class PositionLine. You can also remove this and generate a CRUD class for lines objects. + */ +class PositionLine extends CommonObjectLine +{ + // To complete with content of an object PositionLine + // We should have a field rowid, fk_position and position + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 0; + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } +} diff --git a/htdocs/hrm/class/skill.class.php b/htdocs/hrm/class/skill.class.php new file mode 100644 index 00000000000..478b267ac1f --- /dev/null +++ b/htdocs/hrm/class/skill.class.php @@ -0,0 +1,1109 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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/skill.class.php + * \ingroup hrm + * \brief This file is a CRUD class file for Skill (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 Skill + */ +class Skill extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'hrm'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'skill'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'hrm_skill'; + + + /** + * @var string Name of subtable line + */ + public $table_element_line = 'skilldet'; + + /** + * @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; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for skill. Must be the part after the 'object_' into object_skill.png + */ + public $picto = 'shapes'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + const DEFAULT_MAX_RANK_PER_SKILL = 5; + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', '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 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: '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. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // 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', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'showoncombobox'=>'2',), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3,), + '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,), + 'required_level' => array('type'=>'integer', 'label'=>'requiredLevel', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>0,), + 'date_validite' => array('type'=>'integer', 'label'=>'date_validite', 'enabled'=>'1', 'position'=>52, 'notnull'=>1, 'visible'=>0,), + 'temps_theorique' => array('type'=>'double(24,8)', 'label'=>'temps_theorique', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>0,), + 'skill_type' => array('type'=>'integer', 'label'=>'SkillType', 'enabled'=>'1', 'position'=>55, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'knowHow', '1'=>'HowToBe', '9'=>'knowledge'), 'default'=>0), + 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>70, 'notnull'=>0, 'visible'=>0,), + 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>71, 'notnull'=>0, 'visible'=>0,), + ); + public $rowid; + public $label; + public $description; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $required_level; + public $date_validite; + public $temps_theorique; + public $skill_type; + public $note_public; + public $note_private; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + // /** + // * @var string Name of subtable line + // */ + // public $table_element_line = 'hrm_skillline'; + + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + public $fk_element = 'fk_skill'; + + // /** + // * @var string Name of subtable class that manage subtable lines + // */ + // public $class_element_line = 'Skillline'; + + // /** + // * @var array List of child tables. To test if we can delete object. + // */ + protected $childtables = array('hrm_skillrank', 'hrm_evaluationdet'); + + // /** + // * @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('hrm_skilldet'); + + // /** + // * @var SkillLine[] Array of subtable lines + // */ + // public $lines = array(); + + + + /** + * 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; + } + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->hrm->skill->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 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) + { + global $langs,$conf; + + $resultcreate = $this->createCommon($user, $notrigger); + + + if ($resultcreate > 0) { + // skillDet create + $this->createSkills(); + } + + return $resultcreate; + } + + /** + * @param int $i rank from which we want to create skilldets + * @return null + */ + public function createSkills($i = 1) + { + + global $conf, $user, $langs; + + $MaxNumberSkill = isset($conf->global->HRM_MAXRANK) ? $conf->global->HRM_MAXRANK : self::DEFAULT_MAX_RANK_PER_SKILL; + $defaultSkillDesc = !empty($conf->global->HRM_DEFAULT_SKILL_DESCRIPTION) ? $conf->global->HRM_DEFAULT_SKILL_DESCRIPTION : 'no Description'; + require_once __DIR__ . '/skilldet.class.php'; + for ($i; $i <= $MaxNumberSkill ; $i++) { + $skilldet = new Skilldet($this->db); + $skilldet->description = $defaultSkillDesc . " " . $i ; + $skilldet->rank = $i; + $skilldet->fk_skill = $this->id; + + $result = $skilldet->create($user); + + if ($result > 0) { + setEventMessage($langs->trans('TraductionCreadted'), $i); + } + } + } + + /** + * 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 array|int <0 if KO, 0 if not found, array if OK + */ + public function fetchLines() + { + $this->lines = array(); + require_once __DIR__ . '/skilldet.class.php'; + $skilldet = new Skilldet($this->db); + $this->lines = $skilldet->fetchAll('ASC', '', '', '', array('fk_skill' => $this->id), ''); + + return (count($this->lines) > 0 ) ? $this->lines : 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.'='.$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);; + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * 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; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->skill->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->skill->skill_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " 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('SKILL_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + } + + if (!$error) { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'skill/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'skill/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; $this->error = $this->db->lasterror(); + } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->hrm->dir_output.'/skill/'.$oldref; + $dirdest = $conf->hrm->dir_output.'/skill/'.$newref; + if (!$error && file_exists($dirsource)) { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->hrm->dir_output.'/skill/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) { + $this->ref = $num; + $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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'SKILL_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'SKILL_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'SKILL_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 + */ + /** + * 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("Skill").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Label').': '.$this->label; + + $url = dol_buildpath('/hrm/skill_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("ShowSkill"); + $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->label; + } + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array('jobdao')); + $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 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("hrm"); + $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(); + + $objectline = new SkillLine($this->db); + $result = $objectline->fetchAll('ASC', 'rank', 0, 0, array('customsql'=>'fk_skill = '.$this->id)); + + if (is_numeric($result)) { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("hrm"); + + if (empty($conf->global->hrm_SKILL_ADDON)) { + $conf->global->hrm_SKILL_ADDON = 'mod_skill_standard'; + } + + if (!empty($conf->global->hrm_SKILL_ADDON)) { + $mybool = false; + + $file = $conf->global->hrm_SKILL_ADDON.".php"; + $classname = $conf->global->hrm_SKILL_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/hrm/"); + + // 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 = 0; + + $langs->load("hrm"); + + if (!dol_strlen($modele)) { + $modele = 'standard_skill'; + + if (!empty($this->model_pdf)) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->SKILL_ADDON_PDF)) { + $modele = $conf->global->SKILL_ADDON_PDF; + } + } + + $modelpath = "core/modules/hrm/doc/"; + + if ($includedocgeneration && !empty($modele)) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * 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; + } + + /** + * @param int $code number of code label + * @return int|string + */ + public static function typeCodeToLabel($code) + { + global $langs; + $result = ''; + switch ($code) { + case 0 : $result = $langs->trans("knowHow"); break; //"Savoir Faire" + case 1 : $result = $langs->trans("HowToBe"); break; // "Savoir être" + case 9 : $result = $langs->trans("knowledge"); break; //"Savoir" + } + return $result; + } +} diff --git a/htdocs/hrm/class/skilldet.class.php b/htdocs/hrm/class/skilldet.class.php new file mode 100644 index 00000000000..c3acdd0982e --- /dev/null +++ b/htdocs/hrm/class/skilldet.class.php @@ -0,0 +1,1030 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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/skilldet.class.php + * \ingroup hrm + * \brief This file is a CRUD class file for Skilldet (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 Skilldet + */ +class Skilldet extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'hrm'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'skilldet'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'hrm_skilldet'; + + /** + * @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; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 1; + + /** + * @var string String with name of icon for skilldet. Must be the part after the 'object_' into object_skilldet.png + */ + public $picto = 'skilldet@hrm'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', '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 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: '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. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // 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', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'rankorder' => array('type'=>'integer', 'label'=>'rank', 'enabled'=>'1', 'position'=>2, 'notnull'=>0, 'visible'=>2,), + 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>1,), + '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'=>0,), + 'fk_skill' => array('type'=>'integer:Skill:/hrm/class/skill.class.php', 'label'=>'fk_skill', 'enabled'=>'1', 'position'=>513, 'notnull'=>1, 'visible'=>0,), + ); + public $rowid; + public $description; + public $fk_user_creat; + public $fk_user_modif; + public $fk_skill; + public $rank; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + // /** + // * @var string Name of subtable line + // */ + // public $table_element_line = 'hrm_skilldetline'; + + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + // public $fk_element = 'fk_skilldet'; + + // /** + // * @var string Name of subtable class that manage subtable lines + // */ + // public $class_element_line = 'Skilldetline'; + + // /** + // * @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('hrm_skilldetdet'); + + // /** + // * @var SkilldetLine[] Array of subtable lines + // */ + // public $lines = array(); + + + + /** + * 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; + } + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->hrm->skilldet->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 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); + + //$resultvalidate = $this->validate($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(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + + /** + * 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.'='.$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); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * 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; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->skilldet->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->skilldet->skilldet_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " 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('SKILLDET_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + } + + if (!$error) { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'skilldet/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'skilldet/".$this->db->escape($this->ref)."' and entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; $this->error = $this->db->lasterror(); + } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->hrm->dir_output.'/skilldet/'.$oldref; + $dirdest = $conf->hrm->dir_output.'/skilldet/'.$newref; + if (!$error && file_exists($dirsource)) { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->hrm->dir_output.'/skilldet/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) { + $this->ref = $num; + $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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'SKILLDET_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'SKILLDET_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'SKILLDET_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("Skilldet").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + + $url = dol_buildpath('/hrm/skilldet_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("ShowSkilldet"); + $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('skilldetdao')); + $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 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("hrm"); + $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(); + + $objectline = new SkilldetLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_skilldet = '.$this->id)); + + if (is_numeric($result)) { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("hrm"); + + if (empty($conf->global->hrm_SKILLDET_ADDON)) { + $conf->global->hrm_SKILLDET_ADDON = 'mod_skilldet_standard'; + } + + if (!empty($conf->global->hrm_SKILLDET_ADDON)) { + $mybool = false; + + $file = $conf->global->hrm_SKILLDET_ADDON.".php"; + $classname = $conf->global->hrm_SKILLDET_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/hrm/"); + + // 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 = 0; + + $langs->load("hrm"); + + if (!dol_strlen($modele)) { + $modele = 'standard_skilldet'; + + if (!empty($this->model_pdf)) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->SKILLDET_ADDON_PDF)) { + $modele = $conf->global->SKILLDET_ADDON_PDF; + } + } + + $modelpath = "core/modules/hrm/doc/"; + + if ($includedocgeneration && !empty($modele)) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * 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/hrm/class/skillrank.class.php b/htdocs/hrm/class/skillrank.class.php new file mode 100644 index 00000000000..a07015ef763 --- /dev/null +++ b/htdocs/hrm/class/skillrank.class.php @@ -0,0 +1,1086 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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/skillrank.class.php + * \ingroup hrm + * \brief This file is a CRUD class file for SkillRank (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 . '/hrm/lib/hrm_skillrank.lib.php'; + +/** + * Class for SkillRank + */ +class SkillRank extends CommonObject +{ + /** + * @var string ID of module. + */ + public $module = 'hrm'; + + /** + * @var string ID to identify managed object. + */ + public $element = 'skillrank'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'hrm_skillrank'; + + /** + * @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; + + /** + * @var int Does object support extrafields ? 0=No, 1=Yes + */ + public $isextrafieldmanaged = 0; + + /** + * @var string String with name of icon for skillrank. Must be the part after the 'object_' into object_skillrank.png + */ + public $picto = 'skillrank@hrm'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + const SKILLRANK_TYPE_JOB = "job"; + const SKILLRANK_TYPE_USER = "user"; + const SKILLRANK_TYPE_EVALDET = "evaluationdet"; + + /** + * 'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', '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 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: '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. + * + * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. + */ + + // 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', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), + 'fk_skill' => array('type'=>'integer:Skill:hrm/class/skill.class.php:1', 'label'=>'Skill', 'enabled'=>'1', 'position'=>3, 'notnull'=>1, 'visible'=>1, 'index'=>1,), + 'rank' => array('type'=>'integer', 'label'=>'Rank', 'enabled'=>'1', 'position'=>4, 'notnull'=>1, 'visible'=>1, 'default' => 0), + 'fk_object' => array('type'=>'integer', 'label'=>'object', 'enabled'=>'1', 'position'=>5, 'notnull'=>1, 'visible'=>0,), + '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,), + 'objecttype' => array('type'=>'varchar(128)', 'label'=>'objecttype', 'enabled'=>'1', 'position'=>6, 'notnull'=>1, 'visible'=>0,), + ); + public $rowid; + public $fk_skill; + public $rank; + public $fk_object; + public $date_creation; + public $tms; + public $fk_user_creat; + public $fk_user_modif; + public $objecttype; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + // /** + // * @var string Name of subtable line + // */ + // public $table_element_line = 'hrm_skillrankline'; + + // /** + // * @var string Field with ID of parent key if this object has a parent + // */ + // public $fk_element = 'fk_skillrank'; + + // /** + // * @var string Name of subtable class that manage subtable lines + // */ + // public $class_element_line = 'SkillRankline'; + + // /** + // * @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('hrm_skillrankdet'); + + // /** + // * @var SkillRankLine[] Array of subtable lines + // */ + // public $lines = array(); + + + + /** + * 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; + } + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->hrm->skillrank->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 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) + { + global $langs; + + $sqlfilter = 'fk_object='.((int) $this->fk_object)." AND objecttype='".$this->db->escape($this->objecttype)."' AND fk_skill = ".((int) $this->fk_skill); + $alreadyLinked = $this->fetchAll('ASC', 'rowid', 0, 0, array('customsql' => $sqlfilter)); + if (!empty($alreadyLinked)) { + $this->error = $langs->trans('ErrSkillAlreadyAdded'); + return -1; + } + + $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(); + + $result = $this->fetchLinesCommon(); + return $result; + } + + /** + * Clone skillrank Object linked to job with user id + * The skillrank table is a join table that is marked for multiple objects + * + * @param SkillRank $currentSkill line of evaluation (skill) we need to clone and add to user skills list + * @param int $fk_user id of user linked to skillrank + * @return int > 0 if ok, < 0 if ko + */ + public function cloneFromCurrentSkill($currentSkill, $fk_user) + { + + global $user; + + $this->fk_skill = $currentSkill->fk_skill; + $this->rank = $currentSkill->rank; + $this->fk_object = $fk_user; + $this->date_creation = dol_now(); + $this->fk_user_creat = $user->id; + $this->fk_user_modif = $user->id; + $this->objecttype = self::SKILLRANK_TYPE_USER; + $result = $this->create($user); + + return $result; + } + + /** + * 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.'='.$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); + } + + /** + * Delete a line of object in database + * + * @param User $user User that delete + * @param int $idline Id of line to delete + * @param bool $notrigger false=launch triggers after, true=disable triggers + * @return int >0 if OK, <0 if KO + */ + public function deleteLine(User $user, $idline, $notrigger = false) + { + if ($this->status < 0) { + $this->error = 'ErrorDeleteLineNotAllowedByObjectStatus'; + return -2; + } + + return $this->deleteLineCommon($user, $idline, $notrigger); + } + + + /** + * 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; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $error = 0; + + // Protection + if ($this->status == self::STATUS_VALIDATED) { + dol_syslog(get_class($this)."::validate action abandonned: already validated", LOG_WARNING); + return 0; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->skillrank->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->skillrank->skillrank_advance->validate)))) + { + $this->error='NotEnoughPermissions'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + }*/ + + $now = dol_now(); + + $this->db->begin(); + + // Define new ref + if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + $num = $this->getNextNumRef(); + } else { + $num = $this->ref; + } + $this->newref = $num; + + if (!empty($num)) { + // Validate + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " SET ref = '".$this->db->escape($num)."',"; + $sql .= " 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('SKILLRANK_VALIDATE', $user); + if ($result < 0) { + $error++; + } + // End call triggers + } + } + + if (!$error) { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) { + // Now we rename also files into index + $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'skillrank/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'skillrank/".$this->db->escape($this->ref)."' and entity = ".((int) $conf->entity); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; $this->error = $this->db->lasterror(); + } + + // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->hrm->dir_output.'/skillrank/'.$oldref; + $dirdest = $conf->hrm->dir_output.'/skillrank/'.$newref; + if (!$error && file_exists($dirsource)) { + dol_syslog(get_class($this)."::validate() rename dir ".$dirsource." into ".$dirdest); + + if (@rename($dirsource, $dirdest)) { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles = dol_dir_list($conf->hrm->dir_output.'/skillrank/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/')); + foreach ($listoffiles as $fileentry) { + $dirsource = $fileentry['name']; + $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource); + $dirsource = $fileentry['path'].'/'.$dirsource; + $dirdest = $fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } + } + + // Set new ref and current status + if (!$error) { + $this->ref = $num; + $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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'SKILLRANK_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'SKILLRANK_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->hrm->hrm_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'SKILLRANK_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("SkillRank").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + + $url = dol_buildpath('/hrm/skillrank_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("ShowSkillRank"); + $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('skillrankdao')); + $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 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("hrm"); + $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(); + + $objectline = new SkillRankLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_skillrank = '.((int) $this->id))); + + if (is_numeric($result)) { + $this->error = $this->error; + $this->errors = $this->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("hrm"); + + if (empty($conf->global->hrm_SKILLRANK_ADDON)) { + $conf->global->hrm_SKILLRANK_ADDON = 'mod_skillrank_standard'; + } + + if (!empty($conf->global->hrm_SKILLRANK_ADDON)) { + $mybool = false; + + $file = $conf->global->hrm_SKILLRANK_ADDON.".php"; + $classname = $conf->global->hrm_SKILLRANK_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/hrm/"); + + // 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 = 0; + + $langs->load("hrm"); + + if (!dol_strlen($modele)) { + $modele = 'standard_skillrank'; + + if (!empty($this->model_pdf)) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->SKILLRANK_ADDON_PDF)) { + $modele = $conf->global->SKILLRANK_ADDON_PDF; + } + } + + $modelpath = "core/modules/hrm/doc/"; + + if ($includedocgeneration && !empty($modele)) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * 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; + } + + /** + * @param array $val + * @param string $key + * @param string $value + * @param string $moreparam + * @param string $keysuffix + * @param string $keyprefix + * @param string $morecss + * @return string + */ + // public function showOutputField($val, $key, $value, $moreparam = '', $keysuffix = '', $keyprefix = '', $morecss = '') + // { + // if ($key == "rank") { + // return displayRankInfos($this); + // } else return parent::showOutputField($val, $key, $value, $moreparam, $keysuffix, $keyprefix, $morecss); + // } +} diff --git a/htdocs/hrm/compare.php b/htdocs/hrm/compare.php new file mode 100644 index 00000000000..07097443628 --- /dev/null +++ b/htdocs/hrm/compare.php @@ -0,0 +1,569 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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/compare.php + * \ingroup hrm + * \brief This file compares skills of user groups + * + * Displays a table in three parts. + * 1- the left part displays the list of users of the selected group 1. + * + * 2- the central part displays the skills. display of the maximum score for this group and the number of occurrences. + * + * 3- the right part displays the members of group 2 or the job to be compared + * + * + * + */ + +require_once '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + +ini_set('display_errors', 1); + +require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/evaluation.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/position.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm.lib.php'; + +$permissiontoread = $user->rights->hrm->compare->read; +if (empty($conf->hrm->enabled)) accessforbidden(); +if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) accessforbidden(); + +$langs->load('hrm'); + +$css = array(); +$css[] = '/hrm/css/style.css'; +llxHeader('', $langs->trans('SkillComparison'), '', '', 0, 0, '', $css); + +$head = array(); + +$h = 0; +$head[$h][0] = $_SERVER["PHP_SELF"]; +$head[$h][1] = $langs->trans("SkillComparison"); +$head[$h][2] = 'compare'; + +print dol_get_fiche_head($head, 'compare', '', 1); + +//$PDOdb = new TPDOdb; +$form = new Form($db); +?> + + + + + + +
    +
    + +
    +
    + + + + + + + + + + + + + + +
    trans('group1ToCompare').''.$form->select_dolgroups($fk_usergroup1, 'fk_usergroup1', 1); ?>
     
    trans('group2ToCompare').''.$form->select_dolgroups($fk_usergroup2, 'fk_usergroup2', 1); ?>
    trans('or'); ?>
    trans('OrJobToCompare') . ''; + $j = new Job($db); + $jobs = $j->fetchAll(); + $TJobs = array(); + + foreach ($jobs as &$j) { + $TJobs[$j->id] = $j->label; + } + + print $form->selectarray('fk_job', $TJobs, $fk_job, 1); + ?>
    +
    + +
    + + + + + + + + + + + + + + + + + +
    + trans('CompetenceAcquiredByOneOrMore'); ?>
    + trans('MaxlevelGreaterThan'); ?>
    + trans('MaxLevelEqualTo'); ?>
    + trans('MaxLevelLowerThan'); ?>
    + trans('SkillNotAcquired'); ?>
    + +
    + +
    + +
    + +

    +
    + +
    +

    + +
    + + 0 || $fk_usergroup2 > 0 || $fk_job > 0) { ?> + + + + + + + + + + + '; + + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + + ?> + +
    trans('skill'); ?>trans('rank'); ?>trans('difference'); ?>trans('rank'); ?>
    '; + + $TUser1 = $TUser2 = array(); + + $userlist1 = displayUsersListWithPicto($TUser1, $fk_usergroup1, 'list1'); + + + $skill = new Skill($db); + $TSkill1 = getSkillForUsers($TUser1); + + if ($fk_job > 0) { + $TSkill2 = getSkillForJob($fk_job); + + $job = new Job($db); + $job->fetch($fk_job); + $userlist2 = '
      +
    • +

      ' . $job->label . '

      +

      ' . $job->description . '

      +
    • +
    '; + } else { + $userlist2 = displayUsersListWithPicto($TUser2, $fk_usergroup2, 'list2'); + $TSkill2 = getSkillForUsers($TUser2); + } + + $TMergedSkills = mergeSkills($TSkill1, $TSkill2); + + echo $userlist1; + + echo '
    ' . skillList($TMergedSkills) . '' . rate($TMergedSkills, 'rate1') . '' . diff($TMergedSkills) . '' . rate($TMergedSkills, 'rate2') . ''; + + echo $userlist2; + + echo '
    + + + +
    + +
    + +
    + +'; + + foreach ($TMergedSkills as $id => &$sk) { + $class = 'diffnote'; + + if (empty($sk->rate2)) $class .= ' toohappy'; + elseif (empty($sk->rate1)) $class .= ' toosad'; + elseif ($sk->rate1 == $sk->rate2) $class .= ' happy'; + elseif ($sk->rate2 < $sk->rate1) $class .= ' veryhappy'; + elseif ($sk->rate2 > $sk->rate1) $class .= ' sad'; + + $out .= '
  • +   +
  • '; + } + + $out .= ''; + + return $out; +} + +/** + * Return a html list with rank informations + * @param array $TMergedSkills skill list for display + * @param string $field which column of comparison we are working with + * @return string + */ +function rate(&$TMergedSkills, $field) +{ + global $langs, $fk_job; + + $out = '
      '; + + foreach ($TMergedSkills as $id => &$sk) { + $class = "note"; + $how_many = 0; + if (empty($sk->{$field})) { + $note = 'x'; + $class .= ' none'; + } else { + $note = $sk->{$field}; + $how_many = ($field === 'rate1') ? $sk->how_many_max1 : $sk->how_many_max2; + } + + if ($field === 'rate2' && $fk_job > 0) $trad = $langs->trans('RequiredRank'); + else $trad = $langs->trans('HighestRank'); + + $out .= '
    • +

      ' . $note . '' . ($how_many > 0 ? '' . $how_many . '' : '') . '

      +
    • '; + } + + $out .= '
    '; + + return $out; +} + +/** + * return a html ul list of skills + * + * @param array $TMergedSkills skill list for display + * @return string (ul list in html ) + */ +function skillList(&$TMergedSkills) +{ + + $out = '
      '; + + foreach ($TMergedSkills as $id => &$sk) { + $out .= '
    • +

      ' . $sk->label . '

      +

      ' . $sk->description . '

      +
    • '; + } + + $out .= '
    '; + + return $out; +} + +/** + * create an array of lines [ skillLabel,dscription, maxrank on group1 , minrank needed for this skill ] + * + * @param array $TSkill1 skill list of first column + * @param array $TSkill2 skill list of second column + * @return array + */ +function mergeSkills($TSkill1, $TSkill2) +{ + + $Tab = array(); + + foreach ($TSkill1 as &$sk) { + if (empty($Tab[$sk->fk_skill])) $Tab[$sk->fk_skill] = new stdClass; + + $Tab[$sk->fk_skill]->rate1 = $sk->rank; + $Tab[$sk->fk_skill]->how_many_max1 = $sk->how_many_max; + $Tab[$sk->fk_skill]->label = $sk->label; + $Tab[$sk->fk_skill]->description = $sk->description; + } + + foreach ($TSkill2 as &$sk) { + if (empty($Tab[$sk->fk_skill])) $Tab[$sk->fk_skill] = new stdClass; + $Tab[$sk->fk_skill]->rate2 = $sk->rank; + $Tab[$sk->fk_skill]->label = $sk->label; + $Tab[$sk->fk_skill]->description = $sk->description; + $Tab[$sk->fk_skill]->how_many_max2 = $sk->how_many_max; + } + + return $Tab; +} + +/** + * Display a list of User with picto + * @param array $TUser list of users (employees) in selected usergroup of a column + * @param int $fk_usergroup selected usergroup id + * @param string $namelist html name + * @return string + */ +function displayUsersListWithPicto(&$TUser, $fk_usergroup = 0, $namelist = 'list-user') +{ + global $db, $langs, $conf, $form; + + $out = ''; + if ($fk_usergroup > 0) { + $list = $namelist . '_excluded_id'; + + $excludedIdsList = GETPOST($list); + + + $sql = "SELECT DISTINCT u.rowid FROM " . MAIN_DB_PREFIX . "user u + LEFT JOIN " . MAIN_DB_PREFIX . "usergroup_user as ugu ON (u.rowid = ugu.fk_user) + WHERE u.statut > 0 + AND ugu.fk_usergroup=" . ((int) $fk_usergroup); + + $res = $db->query($sql); + $out .= '
      '; + + $TExcludedId = explode(',', $excludedIdsList); + + $form = new Form($db); + $out .= ' '; + + while ($obj = $db->fetch_object($res)) { + $class = ''; + + $user = new User($db); + $user->fetch($obj->rowid); + + $name = $user->getFullName($langs); + if (empty($name)) $name = $user->login; + + if (in_array($user->id, $TExcludedId)) { + $class .= ' disabled'; + } else { + if (!in_array($user->id, $TUser)) $TUser[] = $user->id; + } + + + $desc = ''; + + $job = Job::getLastJobForUser($user->id); + $desc .= $job; + + $static_eval = new Evaluation($db); + $evaluation = $static_eval->getLastEvaluationForUser($user->id); + + if (!empty($evaluation) && !empty($evaluation->date_eval)) { + $desc .= $langs->trans('DateLastEval') . ' : ' . dol_print_date($evaluation->date_eval); + } else { + $desc .= $langs->trans('NoEval'); + } + + if (!empty($user->array_options['options_DDA'])) $desc .= '
      ' . $langs->trans('Anciennete') . ' : ' . dol_print_date(strtotime($user->array_options['options_DDA'])); + + $out .= '
    • + ' . $form->showphoto('userphoto', $user, 0, 0, 0, 'photoref', 'small', 1, 0, 1) . ' +

      ' . $name . '

      +

      ' . $desc . '

      +
    • '; + } + + $out .= '
    '; + } + + return $out; +} + + +/** + * + * Allow to get skill(s) of a user + * + * @param array $TUser array of employees we need to get skills + * @return array|int + */ +function getSkillForUsers($TUser) +{ + global $db; + + //I go back to the user with the highest score in a given group for all the skills assessed in that group + if (empty($TUser)) return array(); + + $sql = 'SELECT sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill, '; + $sql.= ' MAX(sr.rank) as "rank"'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'hrm_skill sk'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'hrm_skillrank sr ON (sk.rowid = sr.fk_skill)'; + $sql.= " WHERE sr.objecttype = '".SkillRank::SKILLRANK_TYPE_USER."'"; + $sql.= ' AND sr.fk_object IN ('.$db->sanitize(implode(',', $TUser)).')'; + $sql.= " GROUP BY sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill "; // group par competence + + $resql = $db->query($sql); + $Tab = array(); + + if ($resql) { + //For each skill, we count the number of times that the max score has been reached within a given group + $num = 0; + while ($obj = $db->fetch_object($resql) ) { + $sql1 = "SELECT count(*) as how_many_max FROM ".MAIN_DB_PREFIX."hrm_skillrank sr"; + $sql1.=" WHERE sr.rank = ".((int) $obj->rank); + $sql1.=" AND sr.objecttype = '".Skillrank::SKILLRANK_TYPE_USER."'"; + $sql1.=" AND sr.fk_skill = ".((int) $obj->fk_skill); + $sql1.=" AND sr.fk_object IN (".$db->sanitize(implode(',', $TUser)).")"; + $resql1 = $db->query($sql1); + + $objMax = $db->fetch_object($resql1); + + $Tab[$num] = new stdClass(); + $Tab[$num]->fk_skill = $obj->fk_skill; + $Tab[$num]->label = $obj->label; + $Tab[$num]->description = $obj->description; + $Tab[$num]->skill_type = $obj->skill_type; + $Tab[$num]->fk_object = $obj->fk_object; + $Tab[$num]->objectType = SkillRank::SKILLRANK_TYPE_USER; + $Tab[$num]->rank = $obj->rank; + $Tab[$num]->how_many_max = $objMax->how_many_max; + + $num++; + } + } else { + dol_print_error($db); + } + + return $Tab; +} + +/** + * Allow to get skill(s) of a job + * + * @param int $fk_job job we need to get required skills + * @return array|int + */ +function getSkillForJob($fk_job) +{ + global $db; + + if (empty($fk_job)) return array(); + + $sql = 'SELECT sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill, '; + $sql.= ' MAX(sr.rank) as "rank"'; + $sql.=' FROM '.MAIN_DB_PREFIX.'hrm_skill sk'; + $sql.=' LEFT JOIN '.MAIN_DB_PREFIX.'hrm_skillrank sr ON (sk.rowid = sr.fk_skill)'; + $sql.=" WHERE sr.objecttype = '".SkillRank::SKILLRANK_TYPE_JOB."'"; + $sql.=' AND sr.fk_object = '.((int) $fk_job); + $sql.=' GROUP BY sk.rowid, sk.label, sk.description, sk.skill_type, sr.fk_object, sr.objecttype, sr.fk_skill '; // group par competence*/ + + $resql = $db->query($sql); + $Tab = array(); + + + if ($resql) { + $num = 0; + while ($obj = $db->fetch_object($resql) ) { + $Tab[$num] = new stdClass(); + $Tab[$num]->fk_skill = $obj->fk_skill; + $Tab[$num]->label = $obj->label; + $Tab[$num]->description = $obj->description; + $Tab[$num]->skill_type = $obj->skill_type; + //$Tab[$num]->date_start = '';// du poste + //$Tab[$num]->date_end = ''; // du poste + $Tab[$num]->fk_object = $obj->fk_object; + $Tab[$num]->objectType = SkillRank::SKILLRANK_TYPE_JOB; + $Tab[$num]->rank = $obj->rank; + $Tab[$num]->how_many_max = $obj->how_many_max; + + $num++; + } + } else { + dol_print_error($db); + } + + + return $Tab; +} diff --git a/htdocs/hrm/core/tpl/objectline_title.tpl.php b/htdocs/hrm/core/tpl/objectline_title.tpl.php new file mode 100644 index 00000000000..3801288543a --- /dev/null +++ b/htdocs/hrm/core/tpl/objectline_title.tpl.php @@ -0,0 +1,80 @@ + + * Copyright (C) 2010-2011 Laurent Destailleur + * Copyright (C) 2012-2013 Christophe Battarel + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2017 Juanjo Menent + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 . + * + * Need to have following variables defined: + * $object (invoice, order, ...) + * $conf + * $langs + * $element (used to test $user->rights->$element->creer) + * $permtoedit (used to replace test $user->rights->$element->creer) + * $inputalsopricewithtax (0 by default, 1 to also show column with unit price including tax) + * $outputalsopricetotalwithtax + * $usemargins (0 to disable all margins columns, 1 to show according to margin setup) + * + * $type, $text, $description, $line + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +print "\n"; + +// Title line +print "\n"; + +print ''; + +// Adds a line numbering column +if (!empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { + print ' '; +} + +// Skill type +print ''.$langs->trans('SkillType').''; + +// Label skill +print ''.$langs->trans('Label').''; + +// Description +print ''.$langs->trans('Description').''; + +// Note +print ''.$langs->trans('EmployeeRank').''; + + +//print ''; // No width to allow autodim + +//print ''; + +//print ''; + +print "\n"; +print "\n"; + +print "\n"; diff --git a/htdocs/hrm/core/tpl/objectline_view.tpl.php b/htdocs/hrm/core/tpl/objectline_view.tpl.php new file mode 100644 index 00000000000..9dd0e0099ab --- /dev/null +++ b/htdocs/hrm/core/tpl/objectline_view.tpl.php @@ -0,0 +1,160 @@ + + * Copyright (C) 2010-2011 Laurent Destailleur + * Copyright (C) 2012-2013 Christophe Battarel + * Copyright (C) 2012 Cédric Salvador + * Copyright (C) 2012-2014 Raphaël Doursenaud + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2017 Juanjo Menent + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 . + * + * Need to have following variables defined: + * $object (invoice, order, ...) + * $conf + * $langs + * $dateSelector + * $forceall (0 by default, 1 for supplier invoices/orders) + * $element (used to test $user->rights->$element->creer) + * $permtoedit (used to replace test $user->rights->$element->creer) + * $senderissupplier (0 by default, 1 for supplier invoices/orders) + * $inputalsopricewithtax (0 by default, 1 to also show column with unit price including tax) + * $outputalsopricetotalwithtax + * $usemargins (0 to disable all margins columns, 1 to show according to margin setup) + * $object_rights->creer initialized from = $object->getRights() + * $disableedit, $disablemove, $disableremove + * + * $text, $description, $line + */ + +// Protection to avoid direct call of template +if (empty($object) || !is_object($object)) { + print "Error, template page can't be called as URL"; + exit; +} + +global $mysoc; +global $forceall, $senderissupplier, $inputalsopricewithtax, $outputalsopricetotalwithtax; + +// add html5 elements +$domData = ' data-element="'.$line->element.'"'; +$domData .= ' data-id="'.$line->id.'"'; +$domData .= ' data-qty="'.$line->qty.'"'; +$domData .= ' data-product_type="'.$line->product_type.'"'; + +$coldisplay = 0; +?> + + > +global->MAIN_VIEW_LINE_NUMBER)) { ?> + + +
    +fk_skill > 0) { + $skill = new Skill($this->db); + $resSkill = $skill->fetch($line->fk_skill); + if ($resSkill > 0) { + print Skill::typeCodeToLabel($skill->skill_type).''; + print ''.$skill->getNomUrl(1); + } +} +?> + + + +fk_skill > 0 && $resSkill > 0) { + print $skill->description; +} + +print ''; + +?> + + +rank, $line->fk_skill, 'TNote', ($this->status == 0 && $permissiontoadd) ? 'edit' : 'view'); + +?> + + + +statut == 0 && !empty($object_rights->creer) && $action != 'selectlines') { + $situationinvoicelinewithparent = 0; + if ($line->fk_prev_id != null && in_array($object->element, array('facture', 'facturedet'))) { + if ($object->type == $object::TYPE_SITUATION) { // The constant TYPE_SITUATION exists only for object invoice + // Set constant to disallow editing during a situation cycle + $situationinvoicelinewithparent = 1; + } + } + + print ''; + $coldisplay++; + if (($line->info_bits & 2) == 2 || !empty($disableedit)) { + } else { ?> + id.'#line_'.$line->id; ?>"> + '; + } + print ''; + + /*print ''; + $coldisplay++; + if (!$situationinvoicelinewithparent && empty($disableremove)) { // For situation invoice, deletion is not possible if there is a parent company. + print 'id.'">'; + print img_delete(); + print ''; + } + print ''; + + if ($num > 1 && $conf->browser->layout != 'phone' && ($this->situation_counter == 1 || !$this->situation_cycle_ref) && empty($disablemove)) { + print ''; + $coldisplay++; + if ($i > 0) { ?> + id; ?>"> + + + + id; ?>"> + + + '; + } else { + print 'browser->layout != 'phone' && empty($disablemove)) ? ' class="linecolmove tdlineupdown center"' : ' class="linecolmove center"').'>'; + $coldisplay++; + }*/ +} else { + //print ''; + $coldisplay = $coldisplay + 3; +} + +if ($action == 'selectlines') { ?> + +\n"; + +print "\n"; diff --git a/htdocs/hrm/core/tpl/skilldet.fiche.tpl.php b/htdocs/hrm/core/tpl/skilldet.fiche.tpl.php new file mode 100644 index 00000000000..60bb56ff173 --- /dev/null +++ b/htdocs/hrm/core/tpl/skilldet.fiche.tpl.php @@ -0,0 +1,113 @@ +rights->module->create +// $cssclass must be defined by caller. For example $cssclass='fieldtitle' +$module = $object->element; +$note_public = 'note_public'; +$note_private = 'note_private'; + +$colwidth = (isset($colwidth) ? $colwidth : (empty($cssclass) ? '25' : '')); +// Set $permission from the $permissionnote var defined on calling page +$permission = (isset($permissionnote) ? $permissionnote : (isset($permission) ? $permission : (isset($user->rights->$module->create) ? $user->rights->$module->create : (isset($user->rights->$module->creer) ? $user->rights->$module->creer : 0)))); +$moreparam = (isset($moreparam) ? $moreparam : ''); +$value_public = $object->note_public; +$value_private = $object->note_private; +if (!empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PUBLIC_NOTES)) { +$stringtoadd = dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --'; +if (GETPOST('action', 'aZ09') == 'edit'.$note_public) { +$value_public = dol_concatdesc($value_public, ($value_public ? "\n" : "")."-- ".$stringtoadd); +if (dol_textishtml($value_public)) { +$value_public .= "
    \n"; +} else { +$value_public .= "\n"; +} +} +} +if (!empty($conf->global->MAIN_AUTO_TIMESTAMP_IN_PRIVATE_NOTES)) { +$stringtoadd = dol_print_date(dol_now(), 'dayhour').' '.$user->getFullName($langs).' --'; +if (GETPOST('action', 'aZ09') == 'edit'.$note_private) { +$value_private = dol_concatdesc($value_private, ($value_private ? "\n" : "")."-- ".$stringtoadd); +if (dol_textishtml($value_private)) { +$value_private .= "
    \n"; +} else { +$value_private .= "\n"; +} +} +}*/ +/* +// Special cases +if ($module == 'propal') { +$permission = $user->rights->propale->creer; +} elseif ($module == 'supplier_proposal') { +$permission = $user->rights->supplier_proposal->creer; +} elseif ($module == 'fichinter') { +$permission = $user->rights->ficheinter->creer; +} elseif ($module == 'project') { +$permission = $user->rights->projet->creer; +} elseif ($module == 'project_task') { +$permission = $user->rights->projet->creer; +} elseif ($module == 'invoice_supplier') { +if (empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) { +$permission = $user->rights->fournisseur->facture->creer; +} else { +$permission = $user->rights->supplier_invoice->creer; +} +} elseif ($module == 'order_supplier') { +if (empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) { +$permission = $user->rights->fournisseur->commande->creer; +} else { +$permission = $user->rights->supplier_order->creer; +} +} elseif ($module == 'societe') { +$permission = $user->rights->societe->creer; +} elseif ($module == 'contact') { +$permission = $user->rights->societe->creer; +} elseif ($module == 'shipping') { +$permission = $user->rights->expedition->creer; +} elseif ($module == 'product') { +$permission = $user->rights->produit->creer; +} elseif ($module == 'ecmfiles') { +$permission = $user->rights->ecm->setup; +}*/ +//else dol_print_error('','Bad value '.$module.' for param module'); + +if (!empty($object->table_element_line)) { + // Show object lines + $result = $object->getLinesArray(); +} + + + +print ''."\n"; + +print '
    '."\n"; + print '
    '."\n"; + $editmode = (GETPOST('action', 'aZ09') == 'edit'.$note_public); + print '
    '."\n"; + print $form->editfieldkey("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, $moreparam, '', 0); + print '
    '."\n"; + print '
    '."\n"; + print $form->editfieldval("NotePublic", $note_public, $value_public, $object, $permission, $typeofdata, '', null, null, $moreparam, 1)."\n"; + print '
    '."\n"; + print '
    '."\n"; +if (empty($user->socid)) { + // Private notes (always hidden to external users) + print '
    '."\n"; + $editmode = (GETPOST('action', 'aZ09') == 'edit'.$note_private); + print '
    '."\n"; + print $form->editfieldkey("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, $moreparam, '', 0); + print '
    '."\n"; + print '
    '."\n"; + print $form->editfieldval("NotePrivate", $note_private, $value_private, $object, $permission, $typeofdata, '', null, null, $moreparam, 1); + print '
    '."\n"; + print '
    '."\n"; +} +print '
    '."\n"; +?> + diff --git a/htdocs/hrm/css/radio_js_number.css b/htdocs/hrm/css/radio_js_number.css new file mode 100644 index 00000000000..320b0ddc1f2 --- /dev/null +++ b/htdocs/hrm/css/radio_js_number.css @@ -0,0 +1,18 @@ +.radio_js_bloc_number { + display:inline-block; + padding:5px 7px; + min-width:20px; + border-radius:3px; + border:1px solid #ccc; + background:#eee; + color:#555; + cursor:pointer; + margin:2px; + text-align:center; +} +.radio_js_bloc_number.selected { + transition:0.2s ease background; + background:#888; + color:#fff; + border-color:#555; +} \ No newline at end of file diff --git a/htdocs/hrm/css/style.css b/htdocs/hrm/css/style.css new file mode 100644 index 00000000000..0c8ba81d827 --- /dev/null +++ b/htdocs/hrm/css/style.css @@ -0,0 +1,130 @@ +#compare ul,#compare li,#compare h3 {margin: 0; padding: 0;} + +#compare div { + margin: 20px; +} + +#compare ul { + list-style-type: none; + width: 100%; +} + +#compare h3 { + font: bold 20px/1.5 Helvetica, Verdana, sans-serif; +} + +#compare li img { + float: left; + margin: 0 15px 0 0; + max-width:80px; +} + +#compare li p { + font: 200 12px/1.5 Georgia, Times New Roman, serif; +} + +#compare li { + padding: 10px; + overflow: auto; + border-bottom: 2px solid #98b880; +} +#compare ul.competence li,#compare ul.note li { + height:48px; + overflow: hidden; + border-bottom: 2px solid #6C286C; +} + +#compare li:hover { + background: #eee; + cursor: pointer; +} + +#compare li.disabled { + color:#999; + border-bottom: 2px solid #ff0000; +} + +#compare li.disabled img,#compare li.disabled p { + display:none; +} + +span.note { + font: bold Helvetica, Verdana, sans-serif; + background: #eee none repeat scroll 0 0; + border: 1px solid #ccc; + border-radius: 3px; + color: #555; + cursor: pointer; + display: inline-block; + margin: 2px; + min-width: 20px; + padding: 5px 7px; + text-align: center; + font-weight: bold; +} +span.note.none { + background: #BA7777 none repeat scroll 0 0; +} +#compare ul.diff li { + text-align: center; + border-bottom:0 none; + height:48px; + overflow: hidden; + border-bottom: 2px solid #77BABA; +} +span.diffnote { + display: inline-block; + background: #c3e6cb; + width:42px; + height: 42px; + overflow: hidden; + border:none; + box-sizing: border-box; +} +span.diffnote.little { + width:25px; + height: 25px; + border-width:3px; +} +span.toohappy { + background: #3097D1; + border:5px solid #3097D1; +} +span.veryhappy { + border:5px solid #3097D1; +} +span.toosad { + background: #ccc; + border:5px solid #ccc; +} +span.sad { + background:#bd4147; +} +/*span.diffnote { + display: inline-block; + background: url(img/smiley.png); + width:42px; + height: 42px; + overflow: hidden; +} +span.toohappy { + background-position: -105px 0px; +} +span.veryhappy { + background-position: -53px 0px; +} +span.toosad { + background-position: -105px -52px; +} +span.sad { + background-position: 0px -52px; +}*/ + +span.bubble { + background-color: #ccc; + border:1px; + display:inline-block; + width:20px; + height:20px; + border-radius:20px; +} \ No newline at end of file diff --git a/htdocs/hrm/establishment/card.php b/htdocs/hrm/establishment/card.php index 9daf1d768b8..0ce7d793003 100644 --- a/htdocs/hrm/establishment/card.php +++ b/htdocs/hrm/establishment/card.php @@ -419,7 +419,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea * Action bar */ print ''; } diff --git a/htdocs/hrm/establishment/info.php b/htdocs/hrm/establishment/info.php index 517b76de93a..30dbd932dcb 100644 --- a/htdocs/hrm/establishment/info.php +++ b/htdocs/hrm/establishment/info.php @@ -137,7 +137,7 @@ if ($object->id > 0) { // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
    '; /* @@ -154,7 +154,7 @@ if ($object->id > 0) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/hrm/evaluation_agenda.php b/htdocs/hrm/evaluation_agenda.php new file mode 100644 index 00000000000..91a0615bc95 --- /dev/null +++ b/htdocs/hrm/evaluation_agenda.php @@ -0,0 +1,234 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 evaluation_agenda.php + * \ingroup hr + * \brief Tab of events on Evaluation + */ + + +// Load Dolibarr environment +require '../main.inc.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'; +require_once DOL_DOCUMENT_ROOT.'/hrm/class/evaluation.class.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm_evaluation.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/class/job.class.php'; + + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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 Evaluation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('evaluationagenda', '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->hrm->multidir_output[$object->entity]."/".$object->id; +} + +$permissiontoadd = $user->rights->hrm->evaluation->write; // Used by the include of actions_addupdatedelete.inc.php +$permissiontoread = $user->rights->hrm->evaluation->read; // 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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->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 = evaluationPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("Agenda"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $morehtmlref .= $langs->trans('Label').' : '.$object->label; + $u_position = new User(($db)); + $u_position->fetch($object->fk_user); + $morehtmlref .= '
    '.$langs->trans('Employee').' : '.$u_position->getNomUrl(1); + $job = new Job($db); + $job->fetch($object->fk_job); + $morehtmlref .= '
    '.$langs->trans('Job').' : '.$job->getNomUrl(1); + $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("ActionsOnEvaluation"), '', ''); + + // 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/hrm/evaluation_card.php b/htdocs/hrm/evaluation_card.php new file mode 100644 index 00000000000..28e030ffc42 --- /dev/null +++ b/htdocs/hrm/evaluation_card.php @@ -0,0 +1,717 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 evaluation_card.php + * \ingroup hrm + * \brief Page to create/edit/view evaluation + */ + +// 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.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/class/evaluation.class.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/class/skill.class.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/class/skillrank.class.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm_evaluation.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm_skillrank.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "other", 'products')); + +// 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') : 'evaluationcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +//$lineid = GETPOST('lineid', 'int'); + +// Initialize technical objects +$object = new Evaluation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('evaluationcard', '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 = $user->rights->hrm->evaluation->read; +$permissiontoadd = $user->rights->hrm->evaluation->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontovalidate = $user->rights->hrm->evaluation->validate; +$permissiontoClose = $user->rights->hrm->evaluation->write; +$permissiontodelete = $user->rights->hrm->evaluation->delete/* || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT)*/; +$permissiondellink = $user->rights->hrm->evaluation->write; // Used by the include of actions_dellink.inc.php +$upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1].'/evaluation'; + +// 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->hrm->enabled)) accessforbidden(); +if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) 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_buildpath('/hrm/evaluation_list.php', 1); + + 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_buildpath('/hrm/evaluation_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + } + } + } + + $triggermodname = 'hrm_EVALUATION_MODIFY'; // Name of trigger action code to execute when we modify record + + // 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'; + + // Actions when linking object each other + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; + + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + + // Action to move up and down lines of object + //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; + + // 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, $triggermodname); + } + if ($action == 'classin' && $permissiontoadd) { + $object->setProject(GETPOST('projectid', 'int')); + } + + // Actions to send emails + $triggersendname = 'hrm_EVALUATION_SENTBYMAIL'; + $autocopy = 'MAIN_MAIL_AUTOCOPY_EVALUATION_TO'; + $trackid = 'evaluation'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; + + if ($action == 'saveSkill') { + $TNote = GETPOST('TNote', 'array'); + if (!empty($TNote)) { + foreach ($object->lines as $line) { + $line->rank = $TNote[$line->fk_skill]; + $line->update($user); + } + } + } + + if ($action == 'close') { + // save evaldet lines to user; + $sk = new SkillRank($db); + $SkillrecordsForActiveUser = $sk->fetchAll('ASC', 'fk_skill', 0, 0, array("customsql"=>"fk_object = ".$object->fk_user ." AND objecttype ='".SkillRank::SKILLRANK_TYPE_USER."'"), 'AND'); + + $errors = 0; + // we go through the evaldets of the eval + foreach ($object->lines as $key => $line) { + // no reference .. we add the line to use it + if (count($SkillrecordsForActiveUser) == 0) { + if ($res > 0) { + $newSkill = new SkillRank($db); + $resCreate = $newSkill->cloneFromCurrentSkill($line, $object->fk_user); + + if ($resCreate <= 0) { + $errors++; + setEventMessage($langs->trans('ErrorCreateUserSkill'), $line->fk_skill); + } + } else { + setEventMessage($langs->trans('NoSkilRankLoaded')); + } + } else { + //check if the skill is present to use it + $find = false; + $keyFind = 0; + foreach ($SkillrecordsForActiveUser as $k => $sr) { + if ($sr->fk_skill == $line->fk_skill) { + $keyFind = $k; + $find = true; + break; + } + } + //we update the skill user + if ($find) { + $updSkill = $SkillrecordsForActiveUser[$k]; + + $updSkill->rank = $line->rank; + $updSkill->update($user); + } else { // sinon on ajoute la skill + $newSkill = new SkillRank($db); + $resCreate = $newSkill->cloneFromCurrentSkill($line, $object->fk_user); + } + } + } + if (empty($errors)) { + $object->setStatut(Evaluation::STATUS_CLOSED); + setEventMessage('EmployeeSkillsUpdated'); + } + } + + if ($action == 'reopen' ) { + // no update here we just change the evaluation status + $object->setStatut(Evaluation::STATUS_VALIDATED); + } +} + + + + +/* + * View + * + * Put here all code to build page + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formproject = new FormProjets($db); + +$title = $langs->trans("Evaluation"); +$help_url = ''; +$css = array(); +$css[] = '/hrm/css/style.css'; +llxHeader('', $title, $help_url, '', 0, 0, '', $css); + +print ''; + +// Part to create +if ($action == 'create') { + print load_fiche_titre($langs->trans("NewEval"), '', '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 '
    '; + print ''; + print '  '; + print ''; // Cancel for create does not post form if we don't know the backtopage + print '
    '; + + print '
    '; +} + +// Part to edit record +if (($id || $ref) && $action == 'edit') { + print load_fiche_titre($langs->trans("Evaluation"), '', '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 '
    '; + print '   '; + print '
    '; + + print '
    '; +} + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $res = $object->fetch_optionals(); + + $head = evaluationPrepareHead($object); + print dol_get_fiche_head($head, 'card', $langs->trans("Workstation"), -1, $object->picto); + + $formconfirm = ''; + + if ($action == 'validate' && $permissiontovalidate) { + // Confirm validate proposal + $error = 0; + + // We verify whether the object is provisionally numbering + $ref = substr($object->ref, 1, 4); + if ($ref == 'PROV') { + $numref = $object->getNextNumRef(); + if (empty($numref)) { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } else { + $numref = $object->ref; + } + + $text = $langs->trans('ConfirmValidateEvaluation', $numref); + if (!empty($conf->notification->enabled)) { + require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php'; + $notify = new Notify($db); + $text .= '
    '; + $text .= $notify->confirmMessage('HRM_EVALUATION_VALIDATE', $object->socid, $object); + } + + if (!$error) { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateEvaluation'), $text, 'confirm_validate', '', 0, 1); + } + } + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteEvaluation'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } + // Confirmation to delete line + if ($action == 'deleteline') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); + } + // Clone confirmation + if ($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); + } + + // Confirmation of action xxxx + if ($action == 'xxx') { + $formquestion = array(); + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220); + } + + // 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 .= $langs->trans('Label').' : '.$object->label; + $u_position = new User(($db)); + $u_position->fetch($object->fk_user); + $morehtmlref .= '
    '.$langs->trans('Employee').' : '.$u_position->getNomUrl(1); + $job = new Job($db); + $job->fetch($object->fk_job); + $morehtmlref .= '
    '.$langs->trans('Job').' : '.$job->getNomUrl(1); + $morehtmlref .= '
    '; + + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + + print '
    '; + print '
    '; + print '
    '; + print ''."\n"; + + $object->fields['label']['visible']=0; // Already in banner + $object->fields['fk_user']['visible']=0; // Already in banner + $object->fields['fk_job']['visible']=0; // Already in banner + 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(); + + + /* + * Lines + */ + + if (!empty($object->table_element_line)) { + if ($object->status == Evaluation::STATUS_DRAFT) { + $result = $object->getLinesArray(); + + print '
    + + + + + + '; + + if (!empty($conf->use_javascript_ajax) && $object->status == 0) { + include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php'; + } + + print '
    '; + /*if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + }*/ + + + if (!empty($object->lines)) { + $conf->modules_parts['tpl']['hrm']='/hrm/core/tpl/'; // Pour utilisation du tpl hrm sur cet écran + print '
    '.$langs->trans('Skill').''.$langs->trans('Description').''.$langs->trans('Rank').'
    '; + $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1, ''); + print '
    '; + } + + + + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print ''; + + if ($object->status == $object::STATUS_DRAFT && $permissiontoadd) { + print '
    '; + print ''; + print '
    '; + } + } + + + print '
    '; + + print "
    \n"; + print "
    "; + } + } + + // list of comparison + if ($object->status != Evaluation::STATUS_DRAFT) { + // Recovery of skills related to this evaluation + + $sql = 'select'; + $sql .= ' e.ref,'; + $sql .= ' e.date_creation,'; + $sql .= ' e.fk_job,'; + $sql .= ' j.label as "refjob",'; + $sql .= ' ed.fk_skill,'; + + $sql .= ' sk.label as "skilllabel",'; + $sql .= ' sk.skill_type,'; + $sql .= ' sk.description,'; + $sql .= ' ed.rank,'; + $sql .= ' ed.required_rank,'; + $sql .= ' ed.rank as "userRankForSkill",'; + $sql .= ' skdet_user.description as "userRankForSkillDesc",'; + $sql .= ' skdet_required.description as "required_rank_desc"'; + + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'hrm_evaluation as e'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_evaluationdet as ed ON e.rowid = ed.fk_evaluation'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_job as j ON e.fk_job = j.rowid'; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_skill as sk ON ed.fk_skill = sk.rowid'; + $sql .= ' INNER JOIN ' . MAIN_DB_PREFIX . 'hrm_skilldet as skdet_user ON (skdet_user.fk_skill = sk.rowid AND skdet_user.rank = ed.rank)'; + //$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "hrm_skillrank as skr ON (j.rowid = skr.fk_object AND skr.fk_skill = ed.fk_skill AND skr.objecttype = 'job')"; + $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'hrm_skilldet as skdet_required ON (skdet_required.fk_skill = sk.rowid AND skdet_required.rank = ed.required_rank)'; + $sql .= " WHERE e.rowid =" . ((int) $object->id); + + // echo $sql; + + $resql = $db->query($sql); + $Tab = array(); + + if ($resql) { + $num = 0; + while ($obj = $db->fetch_object($resql)) { + $Tab[$num] = new stdClass(); + $class = ''; + $Tab[$num]->skill_type = $obj->skill_type; + $Tab[$num]->skill_id = $obj->fk_skill; + $Tab[$num]->skilllabel = $obj->skilllabel; + $Tab[$num]->description = $obj->description; + $Tab[$num]->userRankForSkill = '' . $obj->userRankForSkill . ''; + $Tab[$num]->required_rank = '' . $obj->required_rank . ''; + + if ($obj->userRankForSkill > $obj->required_rank) { + $title=$langs->trans('MaxlevelGreaterThanShort'); + $class .= 'veryhappy diffnote'; + } elseif ($obj->userRankForSkill == $obj->required_rank) { + $title=$langs->trans('MaxLevelEqualToShort'); + $class .= 'happy diffnote'; + } elseif ($obj->userRankForSkill < $obj->required_rank) { + $title=$langs->trans('MaxLevelLowerThanShort'); + $class .= 'sad'; + } + + $Tab[$num]->result = ' '; + + $num++; + } + + print '
    '; + print ''; + + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + $sk = new Skill($db); + foreach ($Tab as $t) { + $sk->fetch($t->skill_id); + print ''; + print ' '; + print ' '; + print ' '; + print ' '; + print ' '; + print ' '; + print ''; + } + + print '
    ' . $langs->trans("TypeSkill") . ' ' . $langs->trans("Label") . '' . $langs->trans("Description") . '' . $langs->trans("EmployeeRank") . '' . $langs->trans("RequiredRank") . '' . $langs->trans("Result") . '
    ' . Skill::typeCodeToLabel($t->skill_type) . '' . $sk->getNomUrl(1) . '' . $t->description . '' . $t->userRankForSkill . '' . $t->required_rank . '' . $t->result . '
    '; + + ?> + + + + '."\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)) { + // Send + if (empty($user->socid)) { + print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init&token='.newToken().'#formmailbeforetitle'); + } + + // Back to draft + if ($object->status == $object::STATUS_VALIDATED) { + print dolGetButtonAction($langs->trans('SetToDraft'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken(), '', $permissiontoadd); + print dolGetButtonAction($langs->trans('Close'), '', 'close', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=close&token='.newToken(), '', $permissiontodelete || ($object->status == $object::STATUS_CLOSED && $permissiontoclose)); + } elseif ($object->status != $object::STATUS_CLOSED) { + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken(), '', $permissiontoadd); + } + + if ($object->status == $object::STATUS_CLOSED) { + print dolGetButtonAction($langs->trans('ReOpen'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=reopen&token='.newToken(), '', $permissiontoadd); + } + + + // Validate + if ($object->status == $object::STATUS_DRAFT) { + if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { + print dolGetButtonAction($langs->trans('Save').' '.$langs->trans('and').' '.$langs->trans('Valid'), '', 'default', '#', 'btn_valid', $permissiontovalidate); + } else { + $langs->load("errors"); + print dolGetButtonAction($langs->trans("ErrorAddAtLeastOneLineFirst"), $langs->trans("Validate"), 'default', '#', '', 0); + } + } + + + // 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); + } + + + print '
    '."\n"; + } + + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + if ($action != 'presend') { + print '
    '; + print ''; // ancre + + $includedocgeneration = 0; + + // Documents + if ($includedocgeneration) { + $objref = dol_sanitizeFileName($object->ref); + $relativepath = $objref.'/'.$objref.'.pdf'; + $filedir = $conf->hrm->dir_output.'/'.$object->element.'/'.$objref; + $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; + $genallowed = $user->rights->hrm->evaluation->read; // If you can read, you can build the PDF to read content + $delallowed = $user->rights->hrm->evaluation->write; // If you can create/edit, you can remove a file on card + print $formfile->showdocuments('hrm:Evaluation', $object->element.'/'.$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('evaluation')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + + print '
    '; + + $MAXEVENT = 10; + + $morehtmlright = ''; + $morehtmlright .= $langs->trans("SeeAll"); + $morehtmlright .= ''; + + // 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, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); + + print '
    '; + } + + //Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + // Presend form + $modelmail = 'evaluation'; + $defaulttopic = 'InformationMessage'; + $diroutput = $conf->hrm->dir_output; + $trackid = 'evaluation'.$object->id; + + include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/evaluation_contact.php b/htdocs/hrm/evaluation_contact.php new file mode 100644 index 00000000000..61af793b28a --- /dev/null +++ b/htdocs/hrm/evaluation_contact.php @@ -0,0 +1,192 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 evaluation_contact.php + * \ingroup hrm + * \brief Tab for contacts linked to Evaluation + */ + +// Load Dolibarr environment +require '../main.inc.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 . '/hrm/class/evaluation.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_evaluation.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "companies", "other", "mails")); + +$id = (GETPOST('id') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility +$ref = GETPOST('ref', 'alpha'); +$lineid = GETPOST('lineid', 'int'); +$socid = GETPOST('socid', 'int'); +$action = GETPOST('action', 'aZ09'); + +// Initialize technical objects +$object = new Evaluation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('evaluationcontact', '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 + +$permission = $user->rights->hrm->evaluation->write; + +// 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->hrm->enabled)) accessforbidden(); +//if (!$permissiontoread) accessforbidden(); + + +/* + * Add a new contact + */ + +if ($action == 'addcontact' && $permission) { + $contactid = (GETPOST('userid') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int')); + $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type')); + $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09')); + + if ($result >= 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } else { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors'); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } +} elseif ($action == 'swapstatut' && $permission) { + // Toggle the status of a contact + $result = $object->swapContactStatus(GETPOST('ligne', 'int')); +} elseif ($action == 'deletecontact' && $permission) { + // Deletes a contact + $result = $object->delete_contact($lineid); + + if ($result >= 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } else { + dol_print_error($db); + } +} + + +/* + * View + */ + +$title = $langs->trans('Evaluation')." - ".$langs->trans('ContactsAddresses'); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +$form = new Form($db); +$formcompany = new FormCompany($db); +$contactstatic = new Contact($db); +$userstatic = new User($db); + + +/* *************************************************************************** */ +/* */ +/* View and edit mode */ +/* */ +/* *************************************************************************** */ + +if ($object->id) { + /* + * Show tabs + */ + $head = evaluationPrepareHead($object); + + print dol_get_fiche_head($head, 'contact', '', -1, $object->picto); + + $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') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
    '.$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + 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 .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + }*/ + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1); + + print dol_get_fiche_end(); + + print '
    '; + + // Contacts lines (modules that overwrite templates must declare this into descriptor) + $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl')); + foreach ($dirtpls as $reldir) { + $res = @include dol_buildpath($reldir.'/contacts.tpl.php'); + if ($res) { + break; + } + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/evaluation_document.php b/htdocs/hrm/evaluation_document.php new file mode 100644 index 00000000000..7318819644e --- /dev/null +++ b/htdocs/hrm/evaluation_document.php @@ -0,0 +1,176 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 evaluation_document.php + * \ingroup hrm + * \brief Tab for documents linked to Evaluation + */ + + +// Load Dolibarr environment +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/evaluation.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_evaluation.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "companies", "other", "mails")); + + +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm'); +$id = (GETPOST('socid', 'int') ? GETPOST('socid', 'int') : GETPOST('id', 'int')); +$ref = GETPOST('ref', 'alpha'); + +// Get parameters +$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 = $liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortorder) { + $sortorder = "ASC"; +} +if (!$sortfield) { + $sortfield = "name"; +} +//if (! $sortfield) $sortfield="position_name"; + +// Initialize technical objects +$object = new Evaluation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('evaluationdocument', '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->hrm->multidir_output[$object->entity ? $object->entity : $conf->entity]."/evaluation/".get_exdir(0, 0, 0, 1, $object); +} + +$permissiontoadd = $user->rights->hrm->evaluation->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php +$permissiontoread = $user->rights->hrm->evaluation->read; + +// 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->hrm->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans("Evaluation").' - '.$langs->trans("Files"); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +if ($object->id) { + /* + * Show tabs + */ + $head = evaluationPrepareHead($object); + + print dol_get_fiche_head($head, 'document', $langs->trans("Documents"), -1, $object->picto); + + + // 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 .= $langs->trans('Label').' : '.$object->label; + $u_position = new User(($db)); + $u_position->fetch($object->fk_user); + $morehtmlref .= '
    '.$langs->trans('Employee').' : '.$u_position->getNomUrl(1); + $job = new Job($db); + $job->fetch($object->fk_job); + $morehtmlref .= '
    '.$langs->trans('Job').' : '.$job->getNomUrl(1); + $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 = 'hrm'; + $permtoedit = $permissiontoadd; + $param = '&id='.$object->id; + + //$relativepathwithnofile='evaluation/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile = 'evaluation/'.dol_sanitizeFileName($object->ref).'/'; + + include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; +} else { + accessforbidden('', 0, 1); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/evaluation_list.php b/htdocs/hrm/evaluation_list.php new file mode 100644 index 00000000000..35189f11b87 --- /dev/null +++ b/htdocs/hrm/evaluation_list.php @@ -0,0 +1,683 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 evaluation_list.php + * \ingroup hrm + * \brief List page for evaluation + */ + + +// 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'; + +// load hrm libraries +require_once __DIR__.'/class/evaluation.class.php'; + +// for other modules +//dol_include_once('/othermodule/class/otherobject.class.php'); + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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') : 'evaluationlist'; // 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')) { + // If $page is not defined, or '' or -1 or if we click on clear filters + $page = 0; +} +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical objects +$object = new Evaluation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('evaluationlist')); // 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') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', '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" +$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 = $user->rights->hrm->evaluation->read; +$permissiontoadd = $user->rights->hrm->evaluation->write; +$permissiontodelete = $user->rights->hrm->evaluation->delete; + +// Security check +if (empty($conf->hrm->enabled)) { + accessforbidden('Module not enabled'); +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +//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->hrm->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 (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 = 'Evaluation'; + $objectlabel = 'Evaluation'; + $uploaddir = $conf->hrm->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); + +//$help_url="EN:Module_Evaluation|FR:Module_Evaluation_FR|ES:Módulo_Evaluation"; +$help_url = ''; +$title = $langs->trans("List").' '.$langs->trans('Evaluations'); +$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); +*/ + +$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); +} + +// 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_buildpath('/hrm/evaluation_card.php', 1).'?id='.$id); + exit; +} + + +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +// Example : Adding jquery code +// print ''; + +$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) { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } else { + $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_buildpath('/hrm/evaluation_card.php', 1).'?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 = "SendEvaluationRef"; +$modelmail = "evaluation"; +$objecttmp = new Evaluation($db); +$trackid = 'xxxx'.$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 ''; + } 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 '
    '; + } + 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_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/evaluation_note.php b/htdocs/hrm/evaluation_note.php new file mode 100644 index 00000000000..1b6b5a35564 --- /dev/null +++ b/htdocs/hrm/evaluation_note.php @@ -0,0 +1,133 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 evaluation_note.php + * \ingroup hrm + * \brief Tab for notes on Evaluation + */ + +// Load Dolibarr environment +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT . '/hrm/class/evaluation.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_evaluation.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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 Evaluation($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('evaluationnote', '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->hrm->multidir_output[$object->entity]."/".$object->id; +} + +$permissionnote = $user->rights->hrm->evaluation->write; // Used by the include of actions_setnotes.inc.php +$permissiontoread = $user->rights->hrm->evaluation->read; // 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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +//if (empty($conf->hrm->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='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; +$help_url = ''; +llxHeader('', $langs->trans('Evaluation'), $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = evaluationPrepareHead($object); + + print dol_get_fiche_head($head, 'note', $langs->trans('Notes'), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $morehtmlref .= $langs->trans('Label').' : '.$object->label; + $u_position = new User(($db)); + $u_position->fetch($object->fk_user); + $morehtmlref .= '
    '.$langs->trans('Employee').' : '.$u_position->getNomUrl(1); + $job = new Job($db); + $job->fetch($object->fk_job); + $morehtmlref .= '
    '.$langs->trans('Job').' : '.$job->getNomUrl(1); + $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/hrm/index.php b/htdocs/hrm/index.php index 68bcd78636b..0b887667561 100644 --- a/htdocs/hrm/index.php +++ b/htdocs/hrm/index.php @@ -96,7 +96,7 @@ print load_fiche_titre($langs->trans("HRMArea"), '', 'hrm'); if (!empty($setupcompanynotcomplete)) { $langs->load("errors"); $warnpicto = img_warning($langs->trans("WarningMandatorySetupNotComplete")); - print '
    '; + print '
    '; llxFooter(); exit; @@ -175,7 +175,7 @@ if (!empty($conf->holiday->enabled)) { } -print '
    '; +print '
    '; @@ -189,7 +189,7 @@ if (!empty($conf->holiday->enabled) && $user->rights->holiday->read) { if (empty($user->rights->holiday->readall)) { $sql .= ' AND x.fk_user IN ('.$db->sanitize(join(',', $childids)).')'; } - //if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND x.fk_soc = s. rowid AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); + //if (empty($user->rights->societe->client->voir) && !$user->socid) $sql.= " AND x.fk_soc = s. rowid AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); //if (!empty($socid)) $sql.= " AND x.fk_soc = ".((int) $socid); $sql .= $db->order("x.tms", "DESC"); $sql .= $db->plimit($max, 0); @@ -264,13 +264,13 @@ if (!empty($conf->expensereport->enabled) && $user->rights->expensereport->lire) $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.login, u.email, u.statut as user_status, u.photo,"; $sql .= " x.rowid, x.ref, x.date_debut as date, x.tms as dm, x.total_ttc, x.fk_statut as status"; $sql .= " FROM ".MAIN_DB_PREFIX."expensereport as x, ".MAIN_DB_PREFIX."user as u"; - //if (!$user->rights->societe->client->voir && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + //if (empty($user->rights->societe->client->voir) && !$user->socid) $sql.= ", ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql .= " WHERE u.rowid = x.fk_user_author"; $sql .= " AND x.entity = ".$conf->entity; if (empty($user->rights->expensereport->readall) && empty($user->rights->expensereport->lire_tous)) { $sql .= ' AND x.fk_user_author IN ('.$db->sanitize(join(',', $childids)).')'; } - //if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND x.fk_soc = s. rowid AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); + //if (empty($user->rights->societe->client->voir) && !$user->socid) $sql.= " AND x.fk_soc = s. rowid AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); //if (!empty($socid)) $sql.= " AND x.fk_soc = ".((int) $socid); $sql .= $db->order("x.tms", "DESC"); $sql .= $db->plimit($max, 0); @@ -339,11 +339,11 @@ if (!empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitme $sql.= " rp.rowid as jobid, rp.ref as jobref, rp.label"; $sql .= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentcandidature as rc"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as rp ON rc.fk_recruitmentjobposition = rp.rowid"; - if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$socid) { + if ($conf->societe->enabled && empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE rc.entity IN (".getEntity($staticrecruitmentcandidature->element).")"; - if ($conf->societe->enabled && !$user->rights->societe->client->voir && !$socid) { + if ($conf->societe->enabled && empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND rp.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if ($socid) { @@ -404,7 +404,7 @@ if (!empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitme } } -print '
    '; +print ''; // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array $parameters = array('user' => $user); diff --git a/htdocs/hrm/job_agenda.php b/htdocs/hrm/job_agenda.php new file mode 100644 index 00000000000..d7772763d8d --- /dev/null +++ b/htdocs/hrm/job_agenda.php @@ -0,0 +1,227 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 job_agenda.php + * \ingroup hrm + * \brief Tab of events on Job + */ + + +// Load Dolibarr environment +require '../main.inc.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'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php'; + + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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 Job($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('jobagenda', '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->hrm->multidir_output[$object->entity]."/".$object->id; +} + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->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 = jobPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("Agenda"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $morehtmlref.= $object->label; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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("ActionsOnJob"), '', ''); + + // 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/hrm/job_card.php b/htdocs/hrm/job_card.php new file mode 100644 index 00000000000..42ee4d6f4b1 --- /dev/null +++ b/htdocs/hrm/job_card.php @@ -0,0 +1,480 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 job_card.php + * \ingroup hrm + * \brief Page to create/edit/view job + */ + + +// 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 . '/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "other", 'products')); + +// 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') : 'jobcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +//$lineid = GETPOST('lineid', 'int'); + +// Initialize technical objects +$object = new Job($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('jobcard', '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 = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->hrm->all->delete; +$upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1] . '/job'; + +// 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->hrm->enabled)) accessforbidden(); +if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) 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_buildpath('/hrm/job_list.php', 1); + + 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_buildpath('/hrm/job_card.php', 1) . '?id=' . ($id > 0 ? $id : '__ID__'); + } + } + } + + $triggermodname = 'hrm_JOB_MODIFY'; // Name of trigger action code to execute when we modify record + + + // 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'; + + // Actions when linking object each other + include DOL_DOCUMENT_ROOT . '/core/actions_dellink.inc.php'; + + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT . '/core/actions_printing.inc.php'; + + // Action to move up and down lines of object + //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; + + // 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, $triggermodname); + } + if ($action == 'classin' && $permissiontoadd) { + $object->setProject(GETPOST('projectid', 'int')); + } + + // Actions to send emails + $triggersendname = 'hrm_JOB_SENTBYMAIL'; + $autocopy = 'MAIN_MAIL_AUTOCOPY_JOB_TO'; + $trackid = 'job' . $object->id; + include DOL_DOCUMENT_ROOT . '/core/actions_sendmails.inc.php'; +} + + +/* + * View + * + * Put here all code to build page + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formproject = new FormProjets($db); + +$title = $langs->trans("Job"); +$help_url = ''; +llxHeader('', $title, $help_url); + +// Example : Adding jquery code +// print ''; + + +// Part to create +if ($action == 'create') { + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentities('Job')), '', '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 '
    '; + print ''; + print '  '; + print ''; // Cancel for create does not post form if we don't know the backtopage + print '
    '; + + print '
    '; + + //dol_set_focus('input[name="ref"]'); +} + +// Part to edit record +if (($id || $ref) && $action == 'edit') { + print load_fiche_titre($langs->trans("Job"), '', '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 '
    '; + print '   '; + print '
    '; + + print '
    '; +} + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $res = $object->fetch_optionals(); + + $head = jobPrepareHead($object); + $picto = 'company.png'; + print dol_get_fiche_head($head, 'job_card', $langs->trans("Workstation"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteJob'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } + // Confirmation to delete line + if ($action == 'deleteline') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); + } + // Clone confirmation + if ($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); + } + + // Confirmation of action xxxx + if ($action == 'xxx') { + $formquestion = array(); + /* + $forcecombo=0; + if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy + $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' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo)) + ); + */ + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220); + } + + // 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.= $object->label; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref); + + + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + + // Common attributes + //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // 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 + $object->fields['label']['visible']=0; // Already in banner + 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(); + + + /* + * Lines + */ + + if (!empty($object->table_element_line)) { + // Show object lines + $result = $object->getLinesArray(); + + print '
    + + + + + + '; + + if (!empty($conf->use_javascript_ajax) && $object->status == 0) { + include DOL_DOCUMENT_ROOT . '/core/tpl/ajaxrow.tpl.php'; + } + + print '
    '; + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print ''; + } + + if (!empty($object->lines)) { + $object->printObjectLines($action, $mysoc, null, GETPOST('lineid', 'int'), 1); + } + + // Form to add new line + if ($object->status == 0 && $permissiontoadd && $action != 'selectlines') { + if ($action != 'editline') { + // Add products/services form + + $parameters = array(); + $reshook = $hookmanager->executeHooks('formAddObjectLine', $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)) + $object->formAddObjectLine(1, $mysoc, $soc); + } + } + + if (!empty($object->lines) || ($object->status == $object::STATUS_DRAFT && $permissiontoadd && $action != 'selectlines' && $action != 'editline')) { + print '
    '; + } + print '
    '; + + print "
    \n"; + } + + + // 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)) { + // Back to draft + if ($object->status == $object::STATUS_VALIDATED) { + print dolGetButtonAction($langs->trans('SetToDraft'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=confirm_setdraft&confirm=yes&token=' . newToken(), '', $permissiontoadd); + } + + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&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); + } + print '
    ' . "\n"; + } + + + // Select mail models is same action as presend + if (GETPOST('modelselected')) { + $action = 'presend'; + } + + if ($action != 'presend') { + print '
    '; + print ''; // ancre + + $includedocgeneration = 0; + + // Documents + if ($includedocgeneration) { + $objref = dol_sanitizeFileName($object->ref); + $relativepath = $objref . '/' . $objref . '.pdf'; + $filedir = $conf->hrm->dir_output . '/' . $object->element . '/' . $objref; + $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; + $genallowed = $user->rights->hrm->job->read; // If you can read, you can build the PDF to read content + $delallowed = $user->rights->hrm->job->write; // If you can create/edit, you can remove a file on card + print $formfile->showdocuments('hrm:Job', $object->element . '/' . $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('job')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + + print '
    '; + + $MAXEVENT = 10; + + $morehtmlright = ''; + $morehtmlright .= $langs->trans("SeeAll"); + $morehtmlright .= ''; + + // 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, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); + + print '
    '; + } + + // Presend form + $modelmail = 'job'; + $defaulttopic = 'InformationMessage'; + $diroutput = $conf->hrm->dir_output; + $trackid = 'job' . $object->id; + + include DOL_DOCUMENT_ROOT . '/core/tpl/card_presend.tpl.php'; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/job_contact.php b/htdocs/hrm/job_contact.php new file mode 100644 index 00000000000..67da8ecfd91 --- /dev/null +++ b/htdocs/hrm/job_contact.php @@ -0,0 +1,192 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 job_contact.php + * \ingroup hrm + * \brief Tab for contacts linked to Job + */ + +// Load Dolibarr environment +require '../main.inc.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 . '/hrm/class/job.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "companies", "other", "mails")); + +$id = (GETPOST('id') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility +$ref = GETPOST('ref', 'alpha'); +$lineid = GETPOST('lineid', 'int'); +$socid = GETPOST('socid', 'int'); +$action = GETPOST('action', 'aZ09'); + +// Initialize technical objects +$object = new Job($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('jobcontact', '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 + +$permission = $user->rights->hrm->job->write; + +// 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->hrm->enabled)) accessforbidden(); +//if (!$permissiontoread) accessforbidden(); + + +/* + * Add a new contact + */ + +if ($action == 'addcontact' && $permission) { + $contactid = (GETPOST('userid') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int')); + $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type')); + $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09')); + + if ($result >= 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } else { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors'); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } +} elseif ($action == 'swapstatut' && $permission) { + // Toggle the status of a contact + $result = $object->swapContactStatus(GETPOST('ligne', 'int')); +} elseif ($action == 'deletecontact' && $permission) { + // Deletes a contact + $result = $object->delete_contact($lineid); + + if ($result >= 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } else { + dol_print_error($db); + } +} + + +/* + * View + */ + +$title = $langs->trans('Job')." - ".$langs->trans('ContactsAddresses'); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +$form = new Form($db); +$formcompany = new FormCompany($db); +$contactstatic = new Contact($db); +$userstatic = new User($db); + + +/* *************************************************************************** */ +/* */ +/* View and edit mode */ +/* */ +/* *************************************************************************** */ + +if ($object->id) { + /* + * Show tabs + */ + $head = jobPrepareHead($object); + + print dol_get_fiche_head($head, 'contact', '', -1, $object->picto); + + $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') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
    '.$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + 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 .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + }*/ + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1); + + print dol_get_fiche_end(); + + print '
    '; + + // Contacts lines (modules that overwrite templates must declare this into descriptor) + $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl')); + foreach ($dirtpls as $reldir) { + $res = @include dol_buildpath($reldir.'/contacts.tpl.php'); + if ($res) { + break; + } + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/job_document.php b/htdocs/hrm/job_document.php new file mode 100644 index 00000000000..a055fbbc325 --- /dev/null +++ b/htdocs/hrm/job_document.php @@ -0,0 +1,170 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 job_document.php + * \ingroup hrm + * \brief Tab for documents linked to Job + */ + +// Load Dolibarr environment +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "companies", "other", "mails")); + + +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm'); +$id = (GETPOST('socid', 'int') ? GETPOST('socid', 'int') : GETPOST('id', 'int')); +$ref = GETPOST('ref', 'alpha'); + +// Get parameters +$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 = $liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortorder) { + $sortorder = "ASC"; +} +if (!$sortfield) { + $sortfield = "name"; +} +//if (! $sortfield) $sortfield="position_name"; + +// Initialize technical objects +$object = new Job($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('jobdocument', '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->hrm->multidir_output[$object->entity ? $object->entity : $conf->entity]."/job/".get_exdir(0, 0, 0, 1, $object); +} + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans("Job").' - '.$langs->trans("Files"); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +if ($object->id) { + /* + * Show tabs + */ + $head = jobPrepareHead($object); + + print dol_get_fiche_head($head, 'document', $langs->trans("Document"), -1, $object->picto); + + + // 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.= $object->label; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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 = 'hrm'; + //$permissiontoadd = $user->rights->hrm->job->write; + //$permtoedit = $user->rights->hrm->job->write; + $permtoedit = $permissiontoadd; + $param = '&id='.$object->id; + + //$relativepathwithnofile='job/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile = 'job/'.dol_sanitizeFileName($object->ref).'/'; + + include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; +} else { + accessforbidden('', 0, 1); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/job_list.php b/htdocs/hrm/job_list.php new file mode 100644 index 00000000000..55363d729b5 --- /dev/null +++ b/htdocs/hrm/job_list.php @@ -0,0 +1,685 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 job_list.php + * \ingroup hrm + * \brief List page for job + */ + + +// 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'; + +// load hrm libraries +require_once __DIR__.'/class/job.class.php'; + +// for other modules +//dol_include_once('/othermodule/class/otherobject.class.php'); + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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') : 'joblist'; // 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')) { + // If $page is not defined, or '' or -1 or if we click on clear filters + $page = 0; +} +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical objects +$object = new Job($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('joblist')); // 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') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', '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" +$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 = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; +$permissiontodelete = $user->rights->hrm->all->delete; + +// Security check +if (empty($conf->hrm->enabled)) { + accessforbidden('Module not enabled'); +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +//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->hrm->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 (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 = 'Job'; + $objectlabel = 'Job'; + $uploaddir = $conf->hrm->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); + +//$help_url="EN:Module_Job|FR:Module_Job_FR|ES:Módulo_Job"; +$help_url = ''; +$title = $langs->trans("ListOf", $langs->transnoentities('Jobs')); +$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); +*/ + +$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); +} + +// 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_buildpath('/hrm/job_card.php', 1).'?id='.$id); + exit; +} + + +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +// Example : Adding jquery code +// print ''; + +$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) { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } else { + $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_buildpath('/hrm/job_card.php', 1).'?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 = "SendJobRef"; +$modelmail = "job"; +$objecttmp = new Job($db); +$trackid = 'xxxx'.$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, ''); + } elseif ($key == 'label') { + print $object->getNomUrl(1); + } 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 ''; + } 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 '
    '; + } + 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_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/job_note.php b/htdocs/hrm/job_note.php new file mode 100644 index 00000000000..7205afec247 --- /dev/null +++ b/htdocs/hrm/job_note.php @@ -0,0 +1,127 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 job_note.php + * \ingroup hrm + * \brief Tab for notes on Job + */ + + +// Load Dolibarr environment +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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 Job($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('jobnote', '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->hrm->multidir_output[$object->entity]."/".$object->id; +} + +$permissiontoread = $user->rights->hrm->all->read; +$permissionnote = $user->rights->hrm->all->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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->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='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; +$help_url = ''; +llxHeader('', $langs->trans('Job'), $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = jobPrepareHead($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("Notes"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $morehtmlref.= $object->label; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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/hrm/lib/hrm.lib.php b/htdocs/hrm/lib/hrm.lib.php new file mode 100644 index 00000000000..e875f61b9e4 --- /dev/null +++ b/htdocs/hrm/lib/hrm.lib.php @@ -0,0 +1,76 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 hrm/lib/hrm.lib.php + * \ingroup hr + * \brief Library files with common functions for Workstation + */ + +/** + * Prepare admin pages header + * + * @return array + */ +function hrmAdminPrepareHead() +{ + global $langs, $conf; + + $langs->load("hrm"); + + $h = 0; + $head = array(); + $head[$h][0] = DOL_URL_ROOT . "/admin/hrm.php"; + $head[$h][1] = $langs->trans("Settings"); + $head[$h][2] = 'settings'; + $h++; + + $head[$h][0] = DOL_URL_ROOT.'/hrm/admin/admin_establishment.php'; + $head[$h][1] = $langs->trans("Establishments"); + $head[$h][2] = 'establishments'; + $h++; + + /* + $head[$h][0] = dol_buildpath("/workstation/admin/myobject_extrafields.php", 1); + $head[$h][1] = $langs->trans("ExtraFields"); + $head[$h][2] = 'myobject_extrafields'; + $h++; + */ + + /*$head[$h][0] = require_once "/admin/about.php"; + $head[$h][1] = $langs->trans("About"); + $head[$h][2] = 'about'; + $h++;*/ + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@workstation:/workstation/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@workstation:/workstation/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, null, $head, $h, 'hrm_admin'); + + complete_head_from_modules($conf, $langs, null, $head, $h, 'hrm_admin', 'remove'); + + return $head; +} diff --git a/htdocs/hrm/lib/hrm_evaluation.lib.php b/htdocs/hrm/lib/hrm_evaluation.lib.php new file mode 100644 index 00000000000..87e6b80adaa --- /dev/null +++ b/htdocs/hrm/lib/hrm_evaluation.lib.php @@ -0,0 +1,95 @@ + + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 lib/hrm_evaluation.lib.php + * \ingroup hrm + * \brief Library files with common functions for Evaluation + */ + +/** + * Prepare array of tabs for Evaluation + * + * @param Evaluation $object Evaluation + * @return array Array of tabs + */ +function evaluationPrepareHead($object) +{ + global $db, $langs, $conf; + + $langs->load("hrm"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/hrm/evaluation_card.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("EvaluationCard"); + $head[$h][2] = 'card'; + $h++; + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = dol_buildpath('/hrm/evaluation_note.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + } + $head[$h][2] = 'note'; + $h++; + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->hrm->dir_output."/evaluation/".dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = dol_buildpath("/hrm/evaluation_document.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) { + $head[$h][1] .= ''.($nbFiles + $nbLinks).''; + } + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = dol_buildpath("/hrm/evaluation_agenda.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'evaluation@hrm'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'evaluation@hrm', 'remove'); + + return $head; +} diff --git a/htdocs/hrm/lib/hrm_job.lib.php b/htdocs/hrm/lib/hrm_job.lib.php new file mode 100644 index 00000000000..f465d934b0f --- /dev/null +++ b/htdocs/hrm/lib/hrm_job.lib.php @@ -0,0 +1,106 @@ + + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 lib/hrm_job.lib.php + * \ingroup hrm + * \brief Library files with common functions for Job + */ + +/** + * Prepare array of tabs for Job + * + * @param Job $object Job + * @return array Array of tabs + */ +function jobPrepareHead($object) +{ + global $db, $langs, $conf; + + $langs->load("hrm"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/hrm/job_card.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("JobCard"); + $head[$h][2] = 'job_card'; + $h++; + + $head[$h][0] = dol_buildpath("/hrm/skill_tab.php", 1).'?id='.$object->id.'&objecttype=job'; + $head[$h][1] = $langs->trans("RequiredSkills"); + $head[$h][2] = 'skill_tab'; + $h++; + + $head[$h][0] = dol_buildpath("/hrm/position.php", 1).'?fk_job='.$object->id; + $head[$h][1] = $langs->trans("EmployeesInThisPosition"); + $head[$h][2] = 'position'; + $h++; + + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = dol_buildpath('/hrm/job_note.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + } + $head[$h][2] = 'note'; + $h++; + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->hrm->dir_output."/job/".dol_sanitizeFileName($object->label); + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = dol_buildpath("/hrm/job_document.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) { + $head[$h][1] .= ''.($nbFiles + $nbLinks).''; + } + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = dol_buildpath("/hrm/job_agenda.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'job@hrm'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'job@hrm', 'remove'); + + return $head; +} diff --git a/htdocs/hrm/lib/hrm_position.lib.php b/htdocs/hrm/lib/hrm_position.lib.php new file mode 100644 index 00000000000..da9a7b3123a --- /dev/null +++ b/htdocs/hrm/lib/hrm_position.lib.php @@ -0,0 +1,96 @@ + + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 lib/hrm_position.lib.php + * \ingroup hrm + * \brief Library files with common functions for Position + */ + + +/** + * Prepare array of tabs for positions + * + * @param Position $object Position + * @return array Array of tabs + */ +function PositionCardPrepareHead($object) +{ + global $db, $langs, $conf; + + $langs->load("hrm"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/hrm/position_card.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("PositionCard"); + $head[$h][2] = 'position'; + $h++; + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = dol_buildpath('/hrm/position_note.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + } + $head[$h][2] = 'note'; + $h++; + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->hrm->dir_output."/position/".dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = dol_buildpath("/hrm/position_document.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) { + $head[$h][1] .= ''.($nbFiles + $nbLinks).''; + } + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = dol_buildpath("/hrm/position_agenda.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'position@hrm'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'position@hrm', 'remove'); + + return $head; +} diff --git a/htdocs/hrm/lib/hrm_skill.lib.php b/htdocs/hrm/lib/hrm_skill.lib.php new file mode 100644 index 00000000000..c9c83fa6411 --- /dev/null +++ b/htdocs/hrm/lib/hrm_skill.lib.php @@ -0,0 +1,95 @@ + + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 lib/hrm_skill.lib.php + * \ingroup hrm + * \brief Library files with common functions for Skill + */ + +/** + * Prepare array of tabs for Skill + * + * @param Skill $object Skill + * @return array Array of tabs + */ +function skillPrepareHead($object) +{ + global $db, $langs, $conf; + + $langs->load("hrm"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/hrm/skill_card.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("SkillCard"); + $head[$h][2] = 'card'; + $h++; + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = dol_buildpath('/hrm/skill_note.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + } + $head[$h][2] = 'note'; + $h++; + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->hrm->dir_output."/skill/".dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = dol_buildpath("/hrm/skill_document.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) { + $head[$h][1] .= ''.($nbFiles + $nbLinks).''; + } + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = dol_buildpath("/hrm/skill_agenda.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'skill@hrm'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'skill@hrm', 'remove'); + + return $head; +} diff --git a/htdocs/hrm/lib/hrm_skilldet.lib.php b/htdocs/hrm/lib/hrm_skilldet.lib.php new file mode 100644 index 00000000000..df7e1af45fc --- /dev/null +++ b/htdocs/hrm/lib/hrm_skilldet.lib.php @@ -0,0 +1,95 @@ + + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 lib/hrm_skilldet.lib.php + * \ingroup hrm + * \brief Library files with common functions for Skilldet + */ + +/** + * Prepare array of tabs for Skilldet + * + * @param Skilldet $object Skilldet + * @return array Array of tabs + */ +function skilldetPrepareHead($object) +{ + global $db, $langs, $conf; + + $langs->load("hrm"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/hrm/skilldet_card.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Card"); + $head[$h][2] = 'card'; + $h++; + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = dol_buildpath('/hrm/skilldet_note.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + } + $head[$h][2] = 'note'; + $h++; + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->hrm->dir_output."/skilldet/".dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = dol_buildpath("/hrm/skilldet_document.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) { + $head[$h][1] .= ''.($nbFiles + $nbLinks).''; + } + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = dol_buildpath("/hrm/skilldet_agenda.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'skilldet@hrm'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'skilldet@hrm', 'remove'); + + return $head; +} diff --git a/htdocs/hrm/lib/hrm_skillrank.lib.php b/htdocs/hrm/lib/hrm_skillrank.lib.php new file mode 100644 index 00000000000..2aca41504ad --- /dev/null +++ b/htdocs/hrm/lib/hrm_skillrank.lib.php @@ -0,0 +1,159 @@ + + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 lib/hrm_skillrank.lib.php + * \ingroup hrm + * \brief Library files with common functions for SkillRank + */ + +/** + * Prepare array of tabs for SkillRank + * + * @param SkillRank $object SkillRank + * @return array Array of tabs + */ +function skillrankPrepareHead($object) +{ + global $db, $langs, $conf; + + $langs->load("hrm"); + + $h = 0; + $head = array(); + + $head[$h][0] = dol_buildpath("/hrm/skillrank_card.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Card"); + $head[$h][2] = 'card'; + $h++; + + if (isset($object->fields['note_public']) || isset($object->fields['note_private'])) { + $nbNote = 0; + if (!empty($object->note_private)) { + $nbNote++; + } + if (!empty($object->note_public)) { + $nbNote++; + } + $head[$h][0] = dol_buildpath('/hrm/skillrank_note.php', 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Notes'); + if ($nbNote > 0) { + $head[$h][1] .= (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) ? ''.$nbNote.'' : ''); + } + $head[$h][2] = 'note'; + $h++; + } + + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php'; + $upload_dir = $conf->hrm->dir_output."/skillrank/".dol_sanitizeFileName($object->ref); + $nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$')); + $nbLinks = Link::count($db, $object->element, $object->id); + $head[$h][0] = dol_buildpath("/hrm/skillrank_document.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans('Documents'); + if (($nbFiles + $nbLinks) > 0) { + $head[$h][1] .= ''.($nbFiles + $nbLinks).''; + } + $head[$h][2] = 'document'; + $h++; + + $head[$h][0] = dol_buildpath("/hrm/skillrank_agenda.php", 1).'?id='.$object->id; + $head[$h][1] = $langs->trans("Events"); + $head[$h][2] = 'agenda'; + $h++; + + // Show more tabs from modules + // Entries must be declared in modules descriptor with line + //$this->tabs = array( + // 'entity:+tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to add new tab + //$this->tabs = array( + // 'entity:-tabname:Title:@hrm:/hrm/mypage.php?id=__ID__' + //); // to remove a tab + complete_head_from_modules($conf, $langs, $object, $head, $h, 'skillrank@hrm'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'skillrank@hrm', 'remove'); + + return $head; +} + +/** + * Used to print ranks of a skill into several case, view or edit pour js necessary to select a rank + * + * @param int $selected_rank rank we want to preselect + * @param int $fk_skill id of skill we display ranks + * @param string $inputname html name of input + * @param string $mode view or edit + * + * @return string string result + */ +function displayRankInfos($selected_rank, $fk_skill, $inputname = 'TNote', $mode = 'view') +{ + global $db, $conf, $langs; + + require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php'; + require_once DOL_DOCUMENT_ROOT . '/hrm/class/skilldet.class.php'; + + // On charge les différentes notes possibles pour la compétence $fk_skill + $skilldet = new Skilldet($db); + $Lines = $skilldet->fetchAll('ASC', 'rank', 0, 0, array('customsql'=>'fk_skill = '.$fk_skill)); + + if (empty($Lines)) return $langs->trans('SkillHasNoLines'); + + $ret = '0'; + + foreach ($Lines as $line) { + $MaxNumberSkill = isset($conf->global->HRM_MAXRANK) ? $conf->global->HRM_MAXRANK : Skill::DEFAULT_MAX_RANK_PER_SKILL; + if ($line->rank > $MaxNumberSkill) { + continue; + } + + $ret.= ''.$line->rank.''; + } + + if ($mode == 'edit') { + $ret.= ' + + '; + } + + return $ret; +} diff --git a/htdocs/hrm/modulebuilder.txt b/htdocs/hrm/modulebuilder.txt new file mode 100644 index 00000000000..670a1774929 --- /dev/null +++ b/htdocs/hrm/modulebuilder.txt @@ -0,0 +1,3 @@ +# DO NOT DELETE THIS FILE MANUALLY +# File to flag module built using official module template. +# When this file is present into a module directory, you can edit it with the module builder tool. \ No newline at end of file diff --git a/htdocs/hrm/position.php b/htdocs/hrm/position.php new file mode 100644 index 00000000000..208a397f135 --- /dev/null +++ b/htdocs/hrm/position.php @@ -0,0 +1,948 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 position.php + * \ingroup hrm + * \brief Page to create/edit/view position + */ + +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Do not create database handler $db +//if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Do not load object $user +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); // Do not load object $mysoc +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); // Do not load object $langs +//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION', '1'); // Do not check injection attack on GET parameters +//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION', '1'); // Do not check injection attack on POST parameters +//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); // Do not check CSRF attack (test on referer + on token if option MAIN_SECURITY_CSRF_WITH_TOKEN is on). +//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); // Do not roll the Anti CSRF token (used if MAIN_SECURITY_CSRF_WITH_TOKEN is on) +//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK', '1'); // Do not check style html tag into posted data +//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu +//if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +//if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library +//if (! defined("NOLOGIN")) define("NOLOGIN", '1'); // If this page is public (can be called outside logged session). This include the NOIPCHECK too. +//if (! defined('NOIPCHECK')) define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip +//if (! defined("MAIN_LANG_DEFAULT")) define('MAIN_LANG_DEFAULT', 'auto'); // Force lang to a particular value +//if (! defined("MAIN_AUTHENTICATION_MODE")) define('MAIN_AUTHENTICATION_MODE', 'aloginmodule'); // Force authentication handler +//if (! defined("NOREDIRECTBYMAINTOLOGIN")) define('NOREDIRECTBYMAINTOLOGIN', 1); // The main.inc.php does not make a redirect if not logged, instead show simple error message +//if (! defined("FORCECSP")) define('FORCECSP', 'none'); // Disable all Content Security Policies +//if (! defined('CSRFCHECK_WITH_TOKEN')) define('CSRFCHECK_WITH_TOKEN', '1'); // Force use of CSRF protection with tokens even for GET +//if (! defined('NOBROWSERNOTIF')) define('NOBROWSERNOTIF', '1'); // Disable browser notification + +// 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"); +} + +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 . '/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/position.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_position.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php'; + +$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +$fk_job = GETPOST('fk_job', 'int'); + +// Get parameters +$id = GETPOST('fk_job', 'int'); +$fk_job = GETPOST('fk_job', 'int'); +$fk_user = GETPOST('fk_user', 'int'); +//$start_date = date('Y-m-d', GETPOST('date_startyear', 'int').'-'.GETPOST('date_startmonth', 'int').'-'.GETPOST('date_startday', 'int')); +$start_date = dol_mktime(0, 0, 0, GETPOST('date_startmonth', 'int'), GETPOST('date_startday', 'int'), GETPOST('date_startyear', 'int')); + +$ref = GETPOST('ref', 'alpha'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'positioncard'; // To manage different context of search + +// Initialize technical objects +$object = new Job($db); + +$extrafields = new ExtraFields($db); + +$diroutputmassaction = $conf->hrm->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('positiontab', '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'); + } +} + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->hrm->all->delete; +$upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1] . '/position'; + +// 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->hrm->enabled)) accessforbidden(); +if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) 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_buildpath('/hrm/position_list.php', 1); + //$backtopage = dol_buildpath('/hrm/position.php', 1) . '?fk_job=' . ($fk_job > 0 ? $fk_job : '__ID__'); + + if (empty($backtopage) || ($cancel && empty($fk_job))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($fk_job) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + if ($fk_job > 0) { + $backtopage = dol_buildpath('/hrm/position.php', 1) . '?fk_job=' . ($fk_job > 0 ? $fk_job : '__ID__'); + } else { + $backtopage = dol_buildpath('/hrm/position_card.php', 1) . '?id=__ID__'; + } + } + } + } + + $triggermodname = 'hrm_POSITION_MODIFY'; // Name of trigger action code to execute when we modify record + + // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen + $job = $object; + $object = new Position($db); + include DOL_DOCUMENT_ROOT . '/core/actions_addupdatedelete.inc.php'; +} + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "other", 'products')); + +$title = $langs->trans("Position"); +$help_url = ''; +llxHeader('', $title, $help_url); + +if ($job->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + DisplayJob($job); + DisplayPositionList(); +} + + +/** + * Show the top of the page including informations of a job + * + * @param Job $object Job object + * + * @return void + */ +function DisplayJob($object) +{ + global $conf, $langs, $db, $extrafields, $hookmanager, $action, $backtopage, $backtopageforcancel, $permissiontoadd; + + /* + * View + * + * Put here all code to build page + */ + + $form = new Form($db); + $formfile = new FormFile($db); + $formproject = new FormProjets($db); + + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } + + // Part to show record + + $res = $object->fetch_optionals(); + + $head = jobPrepareHead($object); + print dol_get_fiche_head($head, 'position', $langs->trans("Workstation"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $morehtmlref.= $object->label; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'fk_job', $linkback, 1, 'rowid', 'rowid', $morehtmlref); + + + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + + // Common attributes + //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // 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 + $object->fields['label']['visible']=0; // Already in banner + 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(); +} + + +/** + * Show a list of positions for the current job + * + * @return void + */ +function DisplayPositionList() +{ + global $user, $langs, $db, $conf, $extrafields, $hookmanager, $permissiontoadd, $permissiontodelete; + + 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'; + + // load hrm libraries + require_once __DIR__ . '/class/position.class.php'; + + // for other modules + //dol_include_once('/othermodule/class/otherobject.class.php'); + + $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') : 'positionlist'; // To manage different context of search + $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') + $id = GETPOST('id', 'int'); + $fk_job = GETPOST('fk_job', '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')) { + // If $page is not defined, or '' or -1 or if we click on clear filters + $page = 0; + } + $offset = $limit * $page; + $pageprev = $page - 1; + $pagenext = $page + 1; + + // Initialize technical objects + $object = new Position($db); + + $extrafields = new ExtraFields($db); + $diroutputmassaction = $conf->hrm->dir_output . '/temp/massgeneration/' . $user->id; + $hookmanager->initHooks(array('positiontablist')); // 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') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', '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" + $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'); + + // Security check + if (empty($conf->hrm->enabled)) { + accessforbidden('Module not enabled'); + } + + // Security check (enable the most restrictive one) + if ($user->socid > 0) accessforbidden(); + //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->hrm->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 (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 = 'Position'; + $objectlabel = 'Position'; + $uploaddir = $conf->hrm->dir_output; + include DOL_DOCUMENT_ROOT . '/core/actions_massactions.inc.php'; + } + + + /* + * View + */ + + $form = new Form($db); + + $now = dol_now(); + + //$help_url="EN:Module_Position|FR:Module_Position_FR|ES:Módulo_Position"; + $help_url = ''; + $title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("Positions")); + $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"; + } + $sql .= " AND t.fk_job = " . ((int) $fk_job) . " "; + + 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') { + $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); + */ + + $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); + } + + // 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_buildpath('/hrm/position.php', 1) . '?id=' . $id); + exit; + } + + $arrayofselected = is_array($toselect) ? $toselect : array(); + + $param = 'fk_job=' . $fk_job; + 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) { + $param .= '&search_' . $key . '[]=' . urlencode($skey); + } + } else { + $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 ''; + print ''; + + $newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/position.php', 1) . '?action=create&backtopage=' . urlencode($_SERVER['PHP_SELF'].'?fk_job=' . $fk_job).'&fk_job=' . $fk_job, '', $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 = "SendPositionRef"; + $modelmail = "position"; + $objecttmp = new Position($db); + $trackid = 'xxxx' . $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->getNomUrl(1); + } 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 ''; + } 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 '
    '; + } + 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_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); + } +} + +// Part to create +if ($action == 'create') { + $object = new Position($db); + print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("Position")), '', '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 '
    '; + + print ''; + print '  '; + print ''; // Cancel for create does not post form if we don't know the backtopage + print '
    '; + + print '
    '; + + //dol_set_focus('input[name="ref"]'); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/position_agenda.php b/htdocs/hrm/position_agenda.php new file mode 100644 index 00000000000..b3b68d9bcbc --- /dev/null +++ b/htdocs/hrm/position_agenda.php @@ -0,0 +1,234 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 position_agenda.php + * \ingroup hrm + * \brief Tab of events on Position + */ + + +// Load Dolibarr environment +require '../main.inc.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'; +require_once DOL_DOCUMENT_ROOT.'/hrm/class/position.class.php'; +require_once DOL_DOCUMENT_ROOT.'/hrm/lib/hrm_position.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; + + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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 Position($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('positionagenda', '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->hrm->multidir_output[$object->entity]."/".$object->id; +} + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->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 = PositionCardPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("Agenda"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $u_position = new User(($db)); + $u_position->fetch($object->fk_user); + $morehtmlref .= $langs->trans('Employee').' : '.$u_position->getNomUrl(1); + $job = new Job($db); + $job->fetch($object->fk_job); + $morehtmlref .= '
    '.$langs->trans('Job').' : '.$job->getNomUrl(1); + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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("ActionsOnPosition"), '', ''); + + // List of all actions + $filters = array(); + $filters['search_agenda_label'] = $search_agenda_label; + $object->fields['label']=array(); // Usefull to get only get agenda events linked to position (this object doesn't need label of ref field, but show_actions_done() needs it to work correctly) + + // 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/hrm/position_card.php b/htdocs/hrm/position_card.php new file mode 100644 index 00000000000..4d6b36b52f3 --- /dev/null +++ b/htdocs/hrm/position_card.php @@ -0,0 +1,394 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 position_card.php + * \ingroup hrm + * \brief Page to create/edit/view position + */ + + +// 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 . '/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/position.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_position.lib.php'; +//dol_include_once('/hrm/position.php'); + +$action = GETPOST('action', 'aZ09') ? GETPOST('action', 'aZ09') : 'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +$id = GETPOST('id', 'int'); + +// Initialize technical objects +$form = new Form($db); +$object = new Position($db); +$res = $object->fetch($id); +if ($res < 0) { + dol_print_error($db, $object->error); +} + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->hrm->all->delete; +$permissiondellink = $user->rights->hrm->all->write; // Used by the include of actions_dellink.inc.php +$upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1] . '/position'; + +// 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->hrm->enabled)) accessforbidden(); +if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) accessforbidden(); + +$langs->loadLangs(array("hrm", "other")); + + + +// Get parameters +$id = GETPOST('id', 'int'); +$fk_job = GETPOST('fk_job', 'int'); + +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'positioncard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +// $lineid = GETPOST('lineid', 'int'); + +// Initialize technical objects +//$object = new Position($db); +//$res = $object->fetch($id); +/*if ($res < 0) { + dol_print_error($db, &$object->error); +}*/ + +$extrafields = new ExtraFields($db); + +$diroutputmassaction = $conf->hrm->dir_output . '/temp/massgeneration/' . $user->id; +$hookmanager->initHooks(array('positioncard', '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. + + +/* + * 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_buildpath('/hrm/position_list.php', 1); + + if (empty($backtopage) || ($cancel && empty($fk_job))) { + if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { + if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) { + $backtopage = $backurlforlist; + } else { + $backtopage = dol_buildpath('/hrm/position_card.php', 1) . '?id=' . ($id > 0 ? $id : '__ID__'); + } + } + } + + $triggermodname = 'hrm_POSITION_MODIFY'; // Name of trigger action code to execute when we modify record + + // 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'; + + // Actions when linking object each other + include DOL_DOCUMENT_ROOT . '/core/actions_dellink.inc.php'; + + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT . '/core/actions_printing.inc.php'; + + // Action to move up and down lines of object + //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; + + // 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, $triggermodname); + } + if ($action == 'classin' && $permissiontoadd) { + $object->setProject(GETPOST('projectid', 'int')); + } + + // Actions to send emails + $triggersendname = 'hrm_POSITION_SENTBYMAIL'; + $autocopy = 'MAIN_MAIL_AUTOCOPY_POSITION_TO'; + $trackid = 'position' . $object->id; + include DOL_DOCUMENT_ROOT . '/core/actions_sendmails.inc.php'; +} + +DisplayPositionCard($object); + +/** + * Show the card of a position + * + * @param Position $object Position object + * + * @return void + */ +function DisplayPositionCard(&$object) +{ + + global $user, $langs, $db, $conf, $extrafields, $hookmanager, $action, $permissiontoadd, $permissiontodelete; + + $id = $object->id; + + /* + * View + * + * Put here all code to build page + */ + + $form = new Form($db); + $formfile = new FormFile($db); + $formproject = new FormProjets($db); + + $title = $langs->trans("Position"); + $help_url = ''; + llxHeader('', $title, $help_url); + + + // Part to edit record + if (($id || $ref) && $action == 'edit') { + print load_fiche_titre($langs->trans("Position"), '', '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 '
    '; + print '   '; + print '
    '; + + print '
    '; + } + + + // Part to show record + if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $res = $object->fetch_optionals(); + + + $head = PositionCardPrepareHead($object); + print dol_get_fiche_head($head, 'position', $langs->trans("Workstation"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeletePosition'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } + + // 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") . ''; + $linkback = '' . $langs->trans("BackToList") . ''; + + $morehtmlref = '
    '; + $u_position = new User(($db)); + $u_position->fetch($object->fk_user); + $morehtmlref .= $langs->trans('Employee').' : '.$u_position->getNomUrl(1); + $job = new Job($db); + $job->fetch($object->fk_job); + $morehtmlref .= '
    '.$langs->trans('Job').' : '.$job->getNomUrl(1); + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref); + + + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + + // Common attributes + //$keyforbreak='fieldkeytoswitchonsecondcolumn'; // 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 + $object->fields['fk_user']['visible']=0; // Already in banner + $object->fields['fk_job']['visible']=0; // Already in banner + 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(); + + /* + * Action bar + */ + print '
    '; + + $parameters = array(); + $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + + + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&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); + } +} + +//if ($action != 'presend') { +// $formfile = new FormFile($db); +// print '
    '; +// +// if (empty($conf->global->SOCIETE_DISABLE_BUILDDOC)) { +// print ''; // ancre +// +// /* +// * Generated documents +// */ +// $filedir = $conf->societe->multidir_output[$object->entity].'/'.$object->id; +// $urlsource = $_SERVER["PHP_SELF"]."?socid=".$object->id; +// $genallowed = $user->rights->societe->lire; +// $delallowed = $user->rights->societe->creer; +// +// print $formfile->showdocuments('company', $object->id, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 0, 0, 0, 28, 0, 'entity='.$object->entity, 0, '', $object->default_lang); +// } +// +// +// print '
    '; +// +// $MAXEVENT = 10; +// +// $morehtmlright = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-list-alt imgforviewmode', DOL_URL_ROOT.'/societe/agenda.php?socid='.$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->id, 1, '', $MAXEVENT, '', $morehtmlright); // Show all action for thirdparty +// +// print '
    '; +//} + + +print '' . "\n"; +print '
    ' . "\n"; + +print '' . "\n"; + + +if ($action !== 'edit' && $action !== 'create') { + print '
    '; + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, array('position')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + + print '
    '; + + $MAXEVENT = 10; + + $morehtmlright = ''; + $morehtmlright .= $langs->trans("SeeAll"); + $morehtmlright .= ''; + // 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, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); + + print '
    '; +} + + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/position_contact.php b/htdocs/hrm/position_contact.php new file mode 100644 index 00000000000..a7246e3a82b --- /dev/null +++ b/htdocs/hrm/position_contact.php @@ -0,0 +1,192 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 position_contact.php + * \ingroup hrm + * \brief Tab for contacts linked to Position + */ + +// Load Dolibarr environment +require '../main.inc.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 . '/hrm/class/position.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_position.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "companies", "other", "mails")); + +$id = (GETPOST('id') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility +$ref = GETPOST('ref', 'alpha'); +$lineid = GETPOST('lineid', 'int'); +$socid = GETPOST('socid', 'int'); +$action = GETPOST('action', 'aZ09'); + +// Initialize technical objects +$object = new Position($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('positioncontact', '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 + +$permission = $user->rights->hrm->position->write; + +// 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->hrm->enabled)) accessforbidden(); +//if (!$permissiontoread) accessforbidden(); + + +/* + * Add a new contact + */ + +if ($action == 'addcontact' && $permission) { + $contactid = (GETPOST('userid') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int')); + $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type')); + $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09')); + + if ($result >= 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } else { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors'); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } +} elseif ($action == 'swapstatut' && $permission) { + // Toggle the status of a contact + $result = $object->swapContactStatus(GETPOST('ligne', 'int')); +} elseif ($action == 'deletecontact' && $permission) { + // Deletes a contact + $result = $object->delete_contact($lineid); + + if ($result >= 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } else { + dol_print_error($db); + } +} + + +/* + * View + */ + +$title = $langs->trans('Position')." - ".$langs->trans('ContactsAddresses'); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +$form = new Form($db); +$formcompany = new FormCompany($db); +$contactstatic = new Contact($db); +$userstatic = new User($db); + + +/* *************************************************************************** */ +/* */ +/* View and edit mode */ +/* */ +/* *************************************************************************** */ + +if ($object->id) { + /* + * Show tabs + */ + $head = PositionCardPrepareHead($object); + + print dol_get_fiche_head($head, 'contact', '', -1, $object->picto); + + $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') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
    '.$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + 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 .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + }*/ + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1); + + print dol_get_fiche_end(); + + print '
    '; + + // Contacts lines (modules that overwrite templates must declare this into descriptor) + $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl')); + foreach ($dirtpls as $reldir) { + $res = @include dol_buildpath($reldir.'/contacts.tpl.php'); + if ($res) { + break; + } + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/position_document.php b/htdocs/hrm/position_document.php new file mode 100644 index 00000000000..7a820310ee2 --- /dev/null +++ b/htdocs/hrm/position_document.php @@ -0,0 +1,174 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 position_document.php + * \ingroup hrm + * \brief Tab for documents linked to Position + */ + +// Load Dolibarr environment +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/position.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_position.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "companies", "other", "mails")); + + +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm'); +$id = (GETPOST('socid', 'int') ? GETPOST('socid', 'int') : GETPOST('id', 'int')); +$ref = GETPOST('ref', 'alpha'); + +// Get parameters +$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 = $liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortorder) { + $sortorder = "ASC"; +} +if (!$sortfield) { + $sortfield = "name"; +} +//if (! $sortfield) $sortfield="position_name"; + +// Initialize technical objects +$object = new Position($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('positiondocument', '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->hrm->multidir_output[$object->entity ? $object->entity : $conf->entity]."/position/".get_exdir(0, 0, 0, 1, $object); +} + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans("Position").' - '.$langs->trans("Files"); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +if ($object->id) { + /* + * Show tabs + */ + $head = PositionCardPrepareHead($object); + + print dol_get_fiche_head($head, 'document', $langs->trans("Document"), -1, $object->picto); + + + // 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 = '
    '; + $u_position = new User(($db)); + $u_position->fetch($object->fk_user); + $morehtmlref .= $langs->trans('Employee').' : '.$u_position->getNomUrl(1); + $job = new Job($db); + $job->fetch($object->fk_job); + $morehtmlref .= '
    '.$langs->trans('Job').' : '.$job->getNomUrl(1); + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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 = 'hrm'; + $permtoedit = $permissiontoadd; + $param = '&id='.$object->id; + + //$relativepathwithnofile='position/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile = 'position/'.dol_sanitizeFileName($object->ref).'/'; + + include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; +} else { + accessforbidden('', 0, 1); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/position_list.php b/htdocs/hrm/position_list.php new file mode 100644 index 00000000000..d6ed72c2612 --- /dev/null +++ b/htdocs/hrm/position_list.php @@ -0,0 +1,684 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 position_list.php + * \ingroup hrm + * \brief List page for position + */ + + +// 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'; + +// load hrm libraries +require_once __DIR__.'/class/position.class.php'; + +// for other modules +//dol_include_once('/othermodule/class/otherobject.class.php'); + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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') : 'positionlist'; // 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')) { + // If $page is not defined, or '' or -1 or if we click on clear filters + $page = 0; +} +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical objects +$object = new Position($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('positionlist')); // 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') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', '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" +$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 = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; +$permissiontodelete = $user->rights->hrm->all->delete; + +// Security check +if (empty($conf->hrm->enabled)) { + accessforbidden('Module not enabled'); +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +//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->hrm->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 (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 = 'Position'; + $objectlabel = 'Position'; + $uploaddir = $conf->hrm->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); + +//$help_url="EN:Module_Position|FR:Module_Position_FR|ES:Módulo_Position"; +$help_url = ''; +$title = $langs->trans("ListOf", $langs->trans('Positions')); +$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') { + $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); +*/ + +$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); +} + +// 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_buildpath('/hrm/position.php', 1).'?id='.$id); + exit; +} + + +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +// Example : Adding jquery code +// print ''; + +$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) { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } else { + $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_buildpath('/hrm/position.php', 1).'?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 = "SendPositionRef"; +$modelmail = "position"; +$objecttmp = new Position($db); +$trackid = 'xxxx'.$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->getNomUrl(1); + } 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 ''; + } 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 '
    '; + } + 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_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/position_note.php b/htdocs/hrm/position_note.php new file mode 100644 index 00000000000..1eea4b82676 --- /dev/null +++ b/htdocs/hrm/position_note.php @@ -0,0 +1,135 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 position_note.php + * \ingroup hrm + * \ingroup hrm + * \brief Tab for notes on Position + */ + + +// Load Dolibarr environment +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT . '/hrm/class/position.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_position.lib.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php';; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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 Position($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('positionnote', '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->hrm->multidir_output[$object->entity]."/".$object->id; +} + +$permissionnote = $user->rights->hrm->all->write; +$permissiontoread = $user->rights->hrm->all->read; // 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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->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='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; +$help_url = ''; +llxHeader('', $langs->trans('Position'), $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = PositionCardPrepareHead($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("Notes"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $u_position = new User(($db)); + $u_position->fetch($object->fk_user); + $morehtmlref .= $langs->trans('Employee').' : '.$u_position->getNomUrl(1); + $job = new Job($db); + $job->fetch($object->fk_job); + $morehtmlref .= '
    '.$langs->trans('Job').' : '.$job->getNomUrl(1); + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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/hrm/skill_agenda.php b/htdocs/hrm/skill_agenda.php new file mode 100644 index 00000000000..9c1821fb8d7 --- /dev/null +++ b/htdocs/hrm/skill_agenda.php @@ -0,0 +1,227 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 skill_agenda.php + * \ingroup hrm + * \brief Tab of events on skill + */ + + +// Load Dolibarr environment +require '../main.inc.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'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_skill.lib.php'; + + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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 Skill($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('skillagenda', '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->hrm->multidir_output[$object->entity]."/".$object->id; +} + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->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 = skillPrepareHead($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("Agenda"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $morehtmlref.= $object->label; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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("ActionsOnskill"), '', ''); + + // 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/hrm/skill_card.php b/htdocs/hrm/skill_card.php new file mode 100644 index 00000000000..ed66dc4ebb9 --- /dev/null +++ b/htdocs/hrm/skill_card.php @@ -0,0 +1,856 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 skill_card.php + * \ingroup hrm + * \brief Page to create/edit/view skill + */ + + +// 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 . '/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_skill.lib.php'; + + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "other", 'products')); + +// 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') : 'skillcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); +//$lineid = GETPOST('lineid', 'int'); + +// Initialize technical objects +$object = new Skill($db); +//$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('skillcard', 'globalcard')); // Note that conf->hooks_modules contains array + +// 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 = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php +$permissiontodelete = $user->rights->hrm->all->delete; +$upload_dir = $conf->hrm->multidir_output[isset($object->entity) ? $object->entity : 1] . '/skill'; + +// 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->hrm->enabled)) accessforbidden(); +if (!$permissiontoread || ($action === 'create' && !$permissiontoadd)) 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_buildpath('/hrm/skill_list.php', 1); + + 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_buildpath('/hrm/skill_card.php', 1) . '?id=' . ($id > 0 ? $id : '__ID__'); + } + } + } + + $triggermodname = 'hrm_SKILL_MODIFY'; // Name of trigger action code to execute when we modify record + + + // 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'; + + // action update on Skilldet + + $skilldetArray = GETPOST("descriptionline", "array"); + + if (!$error) { + if (is_array($skilldetArray) && count($skilldetArray) > 0) { + foreach ($skilldetArray as $key => $SkValueToUpdate) { + $skilldetObj = new Skilldet($object->db); + $res = $skilldetObj->fetch($key); + if ($res > 0) { + $skilldetObj->description = $SkValueToUpdate; + $resupd = $skilldetObj->update($user); + if ($resupd <= 0) { + setEventMessage($langs->trans('errorUpdateSkilldet')); + } + } + } + } + } + + + // Actions when linking object each other + include DOL_DOCUMENT_ROOT . '/core/actions_dellink.inc.php'; + + // Actions when printing a doc from card + include DOL_DOCUMENT_ROOT . '/core/actions_printing.inc.php'; + + // Action to move up and down lines of object + //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; + + // 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, $triggermodname); + } + if ($action == 'classin' && $permissiontoadd) { + $object->setProject(GETPOST('projectid', 'int')); + } + + // Actions to send emails + $triggersendname = 'hrm_SKILL_SENTBYMAIL'; + $autocopy = 'MAIN_MAIL_AUTOCOPY_SKILL_TO'; + $trackid = 'skill' . $object->id; + include DOL_DOCUMENT_ROOT . '/core/actions_sendmails.inc.php'; +} + + +/* + * View + * + * Put here all code to build page + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formproject = new FormProjets($db); + +$title = $langs->trans("skill"); +$help_url = ''; +llxHeader('', $title, $help_url); + + +// Part to create +if ($action == 'create') { + print load_fiche_titre($langs->trans("NewSkill"), '', 'object_' . $object->picto); + + print '
    '; + print ''; + print ''; + $backtopage .= "&objecttype=job"; + 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'; + + + // SKILLDET ADD + //@todo je stop ici ... à continuer (affichage des 5 skilled input pour create action + //print $object->showInputField($val, $key, $value, '', '['']', '', 0); + + print '
    ' . "\n"; + + print dol_get_fiche_end(); + + print '
    '; + print ''; + print '  '; + + print ''; // Cancel for create does not post form if we don't know the backtopage + print '
    '; + + print '
    '; + + //dol_set_focus('input[name="ref"]'); +} + +// Part to edit record +// and skilldet edition +if (($id || $ref) && $action == 'edit') { + print load_fiche_titre($langs->trans("Skill"), '', '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'; + + print '
    '; + + + // SKILLDET + + print dol_get_fiche_head(array(), ''); + $SkilldetRecords = $object->fetchLines(); + if (is_array($SkilldetRecords) && count($SkilldetRecords) > 0) { + print ''; + foreach ($SkilldetRecords as $sk) { + $MaxNumberSkill = isset($conf->global->HRM_MAXRANK) ? $conf->global->HRM_MAXRANK : Skill::DEFAULT_MAX_RANK_PER_SKILL; + if ($sk->rank > $MaxNumberSkill) { + continue; + } + + print '
    ' . "\n"; + $sk->fields = dol_sort_array($sk->fields, 'position'); + foreach ($sk->fields as $key => $val) { + if (abs($val['visible']) != 1 && abs($val['visible']) != 3 && abs($val['visible']) != 4) { + continue; + } + + if (array_key_exists('enabled', $val) && isset($val['enabled']) && !verifCond($val['enabled'])) { + continue; // We don't want this field + } + + print ''; + // if (!empty($val['help'])) { + // print $form->textwithpicto($langs->trans($val['label']), $langs->trans($val['help'])); + // } else { + print $langs->trans($val['label']).' '.$langs->trans('rank').' '.$sk->rank; + // } + print ''; + print ''; + print ''; + } + } + print '
    '; + // if (!empty($val['picto'])) { + // print img_picto('', $val['picto'], '', false, 0, 0, '', 'pictofixedwidth'); + // } + // if (in_array($val['type'], array('int', 'integer'))) { + // $value = GETPOSTISSET($key) ? GETPOST($key, 'int') : $sk->$key; + // } elseif ($val['type'] == 'double') { + // $value = GETPOSTISSET($key) ? price2num(GETPOST($key, 'alphanohtml')) : $sk->$key; + // } elseif (preg_match('/^(text|html)/', $val['type'])) { + // $tmparray = explode(':', $val['type']); + if (!empty($tmparray[1])) { + $check = $tmparray[1]; + } else { + $check = 'restricthtml'; + } + + $skilldetArray = GETPOST("descriptionline", "array"); + if (empty($skilldetArray)) { + $value = GETPOSTISSET($key) ? GETPOST($key, $check) : $sk->$key; + } else { + $value=$skilldetArray[$sk->id]; + } + // + // } elseif ($val['type'] == 'price') { + // $value = GETPOSTISSET($key) ? price2num(GETPOST($key)) : price2num($sk->$key); + // } else { + // $value = GETPOSTISSET($key) ? GETPOST($key, 'alpha') : $sk->$key; + // } + //var_dump($val.' '.$key.' '.$value); + if ($val['noteditable']) { + print $sk->showOutputField($val, $key, $value, '', '', '', 0); + } else { + /** @var Skilldet $sk */ + print $sk->showInputField($val, $key, $value, "", "line[" . $sk->id . "]", "", ""); + } + print '
    '; + } + + + print dol_get_fiche_end(); + + print '
    '; + print '   '; + print '
    '; + + print '
    '; +} + + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $res = $object->fetch_optionals(); + + $head = skillPrepareHead($object); + print dol_get_fiche_head($head, 'card', $langs->trans("Workstation"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('DeleteSkill'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + } + // Confirmation to delete line + if ($action == 'deleteline') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&lineid=' . $lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1); + } + // Clone confirmation + if ($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); + } + + // Confirmation of action xxxx + if ($action == 'xxx') { + $formquestion = array(); + /* + $forcecombo=0; + if ($conf->browser->name == 'ie') $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy + $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' => 'idwarehouse', 'label' => $langs->trans("SelectWarehouseForStockDecrease"), 'value' => $formproduct->selectWarehouses(GETPOST('idwarehouse')?GETPOST('idwarehouse'):'ifone', 'idwarehouse', '', 1, 0, 0, '', 0, $forcecombo)) + ); + */ + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('XXX'), $text, 'confirm_xxx', $formquestion, 0, 1, 220); + } + + // 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.= $object->label; + $morehtmlref .= '
    '; + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref); + + + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + + $object->fields['label']['visible']=0; // Already in banner + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php'; + + + print '
    '; + print '
    '; + print '
    '; + + print '
    '; + + print dol_get_fiche_end(); + + + //dol_include_once('/hrm/tpl/hrm_skillde.fiche.tpl.php'); + + // 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)) { + // Back to draft + if ($object->status == $object::STATUS_VALIDATED) { + print dolGetButtonAction($langs->trans('SetToDraft'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=confirm_setdraft&confirm=yes&token=' . newToken(), '', $permissiontoadd); + } + + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=edit&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); + } + print '
    ' . "\n"; + } +} + +//*---------------------------------------------------------------------------- +//*---------------------------------------------------------------------------- + + +//*--------------------------------------------------------------------------- + +if ($action != "create" && $action != "edit") { + 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'; + + // load hrm libraries + require_once __DIR__ . '/class/skilldet.class.php'; + + // for other modules + //dol_include_once('/othermodule/class/otherobject.class.php'); + + $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') : 'skilldetlist'; // 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 = 0; + $sortfield = GETPOST('sortfield', 'aZ09comma'); + $sortorder = GETPOST('sortorder', 'aZ09comma'); + $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); + if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) { + // If $page is not defined, or '' or -1 or if we click on clear filters + $page = 0; + } + $offset = $limit * $page; + $pageprev = $page - 1; + $pagenext = $page + 1; + + // Initialize technical objects + $objectline = new Skilldet($db); + // $diroutputmassaction = $conf->hrm->dir_output . '/temp/massgeneration/' . $user->id; + // $hookmanager->initHooks(array('skilldetlist')); // Note that conf->hooks_modules contains array + + // Default sort order (if not yet defined by previous GETPOST) + if (!$sortfield) { + reset($objectline->fields); // Reset is required to avoid key() to return null. + $sortfield = "t." . key($objectline->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') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'); + $search = array(); + foreach ($objectline->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" + $fieldstosearchall = array(); + foreach ($objectline->fields as $key => $val) { + if (!empty($val['searchall'])) { + $fieldstosearchall['t.' . $key] = $val['label']; + } + } + + // Definition of array of fields for columns + $arrayfields = array(); + foreach ($objectline->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'] : '' + ); + } + } + + $objectline->fields = dol_sort_array($objectline->fields, 'position'); + $arrayfields = dol_sort_array($arrayfields, 'position'); + + + /* + * View + */ + + $form = new Form($db); + + $now = dol_now(); + + $help_url = ''; + $title = $langs->transnoentitiesnoconv("Skilldets"); + $morejs = array(); + $morecss = array(); + + + // Build and execute select + // -------------------------------------------------------------------- + $sql = 'SELECT '; + $sql .= $objectline->getFieldList('t'); + $sql .= " FROM " . MAIN_DB_PREFIX . $objectline->table_element . " as t"; + if ($objectline->ismultientitymanaged == 1) { + $sql .= " WHERE t.entity IN (" . getEntity($objectline->element) . ")"; + } else { + $sql .= " WHERE 1 = 1 "; + } + + if (!empty($id)) { + $sql .= " AND fk_skill = " . ((int) $id) . " "; + } + + // 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); + } + + print '
    ' . "\n"; + if ($optioncss != '') { + print ''; + } + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if (!empty($id)) { + print ''; + } + + $param_fk = "&fk_skill=" . $id . "&fk_user_creat=" . $user->rowid; + $backtopage = dol_buildpath('/hrm/skill_card.php', 1) . '?id=' . $id; + //$newcardbutton = dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', dol_buildpath('/hrm/skilldet_card.php', 1) . '?action=create&backtopage=' . urlencode($_SERVER['PHP_SELF']) . $param_fk . '&backtopage=' . $backtopage, '', $permissiontoadd); + + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'object_' . $object->picto, 0, "", '', '', 0, 0, 1); + + // Add code for pre mass action (confirmation or email presend form) + $topicmail = "SendSkilldetRef"; + $modelmail = "skilldet"; + $objecttmp = new Skilldet($db); + $trackid = 'xxxx' . $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, $objectline); // Note that $action and $objectline 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 label + // -------------------------------------------------------------------- + print ''; + foreach ($objectline->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"; + } + } + print ''; + print ''; + print '' . "\n"; + + + // Display all ranks of skill + // -------------------------------------------------------------------- + + $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 + } + + $MaxNumberSkill = isset($conf->global->HRM_MAXRANK) ? $conf->global->HRM_MAXRANK : Skill::DEFAULT_MAX_RANK_PER_SKILL; + if ($obj->rank > $MaxNumberSkill) { + continue; + } + + // Store properties in $objectline + $objectline->setVarsFromFetchObj($obj); + + // Show here line of result + print ''; + foreach ($objectline->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 $objectline->getLibStatut(5); + } elseif ($key == 'rowid') { + print $objectline->showOutputField($val, $key, $objectline->id, ''); + // ajout pencil + print ''; + } else { + print $objectline->showOutputField($val, $key, $objectline->$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] += $objectline->$key; + } + } + } + + + // LINE EDITION | SUPPRESSION + + print ''; + print ''; + + + // Fields from hook + $parameters = array('arrayfields' => $arrayfields, 'object' => $objectline, 'obj' => $obj, 'i' => $i, 'totalarray' => &$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $objectline); // Note that $action and $objectline may have been modified by hook + print $hookmanager->resPrint; + /*// Action column + print '';*/ + if (!$i) { + $totalarray['nbfield']++; + } + + print '' . "\n"; + + $i++; + } + + + // 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, $objectline); // Note that $action and $objectline may have been modified by hook + print $hookmanager->resPrint; + + print '
    '; + + print ''; + // add pencil + //@todo change to proper call dol_ + //print 'id, 1) . '">'; + // add trash + //@todo change to proper call dol_ + //print 'id,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_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); + // } + + print '
    '; + + // Show links to link elements + $linktoelem = $form->showLinkToObjectBlock($object, null, array('skill')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); + + print '
    '; + + $MAXEVENT = 10; + + $morehtmlright = ''; + $morehtmlright .= $langs->trans("SeeAll"); + $morehtmlright .= ''; + // 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, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); + + print '
    '; +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/skill_contact.php b/htdocs/hrm/skill_contact.php new file mode 100644 index 00000000000..f8ea2a04a9f --- /dev/null +++ b/htdocs/hrm/skill_contact.php @@ -0,0 +1,192 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 skill_contact.php + * \ingroup hrm + * \brief Tab for contacts linked to Skill + */ + +// Load Dolibarr environment +require '../main.inc.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 . '/hrm/class/skill.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_skill.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "companies", "other", "mails")); + +$id = (GETPOST('id') ?GETPOST('id', 'int') : GETPOST('facid', 'int')); // For backward compatibility +$ref = GETPOST('ref', 'alpha'); +$lineid = GETPOST('lineid', 'int'); +$socid = GETPOST('socid', 'int'); +$action = GETPOST('action', 'aZ09'); + +// Initialize technical objects +$object = new Skill($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('skillcontact', '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 + +$permission = $user->rights->hrm->skill->write; + +// 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->hrm->enabled)) accessforbidden(); +//if (!$permissiontoread) accessforbidden(); + + +/* + * Add a new contact + */ + +if ($action == 'addcontact' && $permission) { + $contactid = (GETPOST('userid') ? GETPOST('userid', 'int') : GETPOST('contactid', 'int')); + $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type')); + $result = $object->add_contact($contactid, $typeid, GETPOST("source", 'aZ09')); + + if ($result >= 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } else { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"), null, 'errors'); + } else { + setEventMessages($object->error, $object->errors, 'errors'); + } + } +} elseif ($action == 'swapstatut' && $permission) { + // Toggle the status of a contact + $result = $object->swapContactStatus(GETPOST('ligne', 'int')); +} elseif ($action == 'deletecontact' && $permission) { + // Deletes a contact + $result = $object->delete_contact($lineid); + + if ($result >= 0) { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } else { + dol_print_error($db); + } +} + + +/* + * View + */ + +$title = $langs->trans('Skill')." - ".$langs->trans('ContactsAddresses'); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +$form = new Form($db); +$formcompany = new FormCompany($db); +$contactstatic = new Contact($db); +$userstatic = new User($db); + + +/* *************************************************************************** */ +/* */ +/* View and edit mode */ +/* */ +/* *************************************************************************** */ + +if ($object->id) { + /* + * Show tabs + */ + $head = skillPrepareHead($object); + + print dol_get_fiche_head($head, 'contact', '', -1, $object->picto); + + $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') . ' : ' . (is_object($object->thirdparty) ? $object->thirdparty->getNomUrl(1) : ''); + // Project + if (! empty($conf->projet->enabled)) + { + $langs->load("projects"); + $morehtmlref.='
    '.$langs->trans('Project') . ' '; + if ($permissiontoadd) + { + 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 .= ': '.$proj->getNomUrl(); + } else { + $morehtmlref .= ''; + } + } + }*/ + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '', 1); + + print dol_get_fiche_end(); + + print '
    '; + + // Contacts lines (modules that overwrite templates must declare this into descriptor) + $dirtpls = array_merge($conf->modules_parts['tpl'], array('/core/tpl')); + foreach ($dirtpls as $reldir) { + $res = @include dol_buildpath($reldir.'/contacts.tpl.php'); + if ($res) { + break; + } + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/skill_document.php b/htdocs/hrm/skill_document.php new file mode 100644 index 00000000000..77f3325de15 --- /dev/null +++ b/htdocs/hrm/skill_document.php @@ -0,0 +1,169 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 skill_document.php + * \ingroup hrm + * \brief Tab for documents linked to skill + */ + + +// Load Dolibarr environment +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_skill.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "companies", "other", "mails")); + + +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm'); +$id = (GETPOST('socid', 'int') ? GETPOST('socid', 'int') : GETPOST('id', 'int')); +$ref = GETPOST('ref', 'alpha'); + +// Get parameters +$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 = $liste_limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortorder) { + $sortorder = "ASC"; +} +if (!$sortfield) { + $sortfield = "name"; +} +//if (! $sortfield) $sortfield="position_name"; + +// Initialize technical objects +$object = new Skill($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('skilldocument', '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->hrm->multidir_output[$object->entity ? $object->entity : $conf->entity]."/skill/".get_exdir(0, 0, 0, 1, $object); +} + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->enabled)) accessforbidden(); +if (!$permissiontoread) accessforbidden(); + + +/* + * Actions + */ + +include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; + + +/* + * View + */ + +$form = new Form($db); + +$title = $langs->trans("Skilldet").' - '.$langs->trans("Files"); +$help_url = ''; +//$help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; +llxHeader('', $title, $help_url); + +if ($object->id) { + /* + * Show tabs + */ + $head = skillPrepareHead($object); + + print dol_get_fiche_head($head, 'document', $langs->trans("Documents"), -1, $object->picto); + + + // 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.= $object->label; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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 = 'hrm'; + $permtoedit = $permissiontoadd; + $param = '&id='.$object->id; + + //$relativepathwithnofile='skill/' . dol_sanitizeFileName($object->id).'/'; + $relativepathwithnofile = 'skill/'.dol_sanitizeFileName($object->ref).'/'; + + include DOL_DOCUMENT_ROOT.'/core/tpl/document_actions_post_headers.tpl.php'; +} else { + accessforbidden('', 0, 1); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/skill_list.php b/htdocs/hrm/skill_list.php new file mode 100644 index 00000000000..1fc5440e589 --- /dev/null +++ b/htdocs/hrm/skill_list.php @@ -0,0 +1,685 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 skill_list.php + * \ingroup hrm + * \brief List page for skill + */ + + +// 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'; + +// load hrm libraries +require_once __DIR__.'/class/skill.class.php'; + +// for other modules +//dol_include_once('/othermodule/class/otherobject.class.php'); + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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') : 'skilllist'; // 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')) { + // If $page is not defined, or '' or -1 or if we click on clear filters + $page = 0; +} +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +// Initialize technical objects +$object = new Skill($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('skilllist')); // 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') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', '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" +$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 = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; +$permissiontodelete = $user->rights->hrm->all->delete; + +// Security check +if (empty($conf->hrm->enabled)) { + accessforbidden('Module not enabled'); +} + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +//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->hrm->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 (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 = 'Skill'; + $objectlabel = 'Skill'; + $uploaddir = $conf->hrm->dir_output; + include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; +} + + + +/* + * View + */ + +$form = new Form($db); + +$now = dol_now(); + +//$help_url="EN:Module_Skill|FR:Module_Skill_FR|ES:Módulo_Skill"; +$help_url = ''; +$title = $langs->trans('ListOf', $langs->transnoentitiesnoconv("Skills")); +$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); +*/ + +$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); +} + +// 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_buildpath('/hrm/skill_card.php', 1).'?id='.$id); + exit; +} + + +// Output page +// -------------------------------------------------------------------- + +llxHeader('', $title, $help_url, '', 0, 0, $morejs, $morecss, '', ''); + +// Example : Adding jquery code +// print ''; + +$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) { + $param .= '&search_'.$key.'[]='.urlencode($skey); + } + } else { + $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_buildpath('/hrm/skill_card.php', 1).'?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 = "SendSkillRef"; +$modelmail = "skill"; +$objecttmp = new Skill($db); +$trackid = 'xxxx'.$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, ''); + } elseif ($key == 'label') { + print $object->getNomUrl(1); + } 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 ''; + } 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 '
    '; + } + 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_hrm', '', $filedir, $urlsource, 0, $delallowed, '', 1, 1, 0, 48, 1, $param, $title, '', '', '', null, $hidegeneratedfilelistifempty); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/hrm/skill_note.php b/htdocs/hrm/skill_note.php new file mode 100644 index 00000000000..1510f746e5e --- /dev/null +++ b/htdocs/hrm/skill_note.php @@ -0,0 +1,127 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 skill_note.php + * \ingroup hrm + * \brief Tab for notes on skill + */ + + +// Load Dolibarr environment +require '../main.inc.php'; + +require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_skill.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "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 Skill($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->hrm->dir_output.'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('skillnote', '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->hrm->multidir_output[$object->entity]."/".$object->id; +} + +$permissionnote = $user->rights->hrm->all->write; +$permissiontoread = $user->rights->hrm->all->read; // 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, $object->element, $object->id, $object->table_element, '', 'fk_soc', 'rowid', $isdraft); +if (empty($conf->hrm->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='EN:Customers_Orders|FR:Commandes_Clients|ES:Pedidos de clientes'; +$help_url = ''; +llxHeader('', $langs->trans('Skill'), $help_url); + +if ($id > 0 || !empty($ref)) { + $object->fetch_thirdparty(); + + $head = skillPrepareHead($object); + + print dol_get_fiche_head($head, 'note', $langs->trans("Notes"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
    '; + $morehtmlref.= $object->label; + $morehtmlref .= '
    '; + + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $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/hrm/skill_tab.php b/htdocs/hrm/skill_tab.php new file mode 100644 index 00000000000..9a9ea39e31d --- /dev/null +++ b/htdocs/hrm/skill_tab.php @@ -0,0 +1,333 @@ + + * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2021 Greg Rastklan + * Copyright (C) 2021 Jean-Pascal BOUDET + * Copyright (C) 2021 Grégory BLEMAND + * + * 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 skill_tab.php + * \ingroup hrm + * \brief Page to add/delete/view skill to jobs/users + */ + + + +// 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 . '/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/skill.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/class/skillrank.class.php'; +require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_skill.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("hrm", "other")); + +$id = GETPOST('id', 'int'); +$TSkillsToAdd = GETPOST('fk_skill', 'array'); +$objecttype = GETPOST('objecttype', 'alpha'); +$TNote = GETPOST('TNote', 'array'); +$lineid = GETPOST('lineid', 'int'); +$action = GETPOST('action', 'aZ09'); +$confirm = GETPOST('confirm', 'alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'skillcard'; // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); + +$TAuthorizedObjects = array('job', 'user'); +$skill = new SkillRank($db); + +// Initialize technical objects +if (in_array($objecttype, $TAuthorizedObjects)) { + if ($objecttype == 'job') { + require_once DOL_DOCUMENT_ROOT . '/hrm/class/job.class.php'; + $object = new Job($db); + } elseif ($objecttype == "user") { + $object = new User($db); + } +} else accessforbidden($langs->trans('ErrorBadObjectType')); + +$hookmanager->initHooks(array('skilltab', 'globalcard')); // Note that conf->hooks_modules contains array + +// Load object +include DOL_DOCUMENT_ROOT . '/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +$permissiontoread = $user->rights->hrm->all->read; +$permissiontoadd = $user->rights->hrm->all->write; // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php + +// Security check (enable the most restrictive one) +if ($user->socid > 0) accessforbidden(); +if (empty($conf->hrm->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_buildpath('/hrm/skill_list.php', 1); + + 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_buildpath('/hrm/skill_list.php', 1) . '?id=' . ($id > 0 ? $id : '__ID__'); + } + } + } + + if ($action == 'addSkill') { + $error = 0; + + if (empty($TSkillsToAdd)) { + setEventMessage('ErrNoSkillSelected', 'errors'); + $error++; + } + + if (!$error) { + foreach ($TSkillsToAdd as $k=>$v) { + $skillAdded = new SkillRank($db); + $skillAdded->fk_skill = $v; + $skillAdded->fk_object = $id; + $skillAdded->objecttype = $objecttype; + $ret = $skillAdded->create($user); + if ($ret < 0) setEventMessage($skillAdded->error, 'errors'); + //else unset($TSkillsToAdd); + } + } + } elseif ($action == 'saveSkill') { + if (!empty($TNote)) { + foreach ($TNote as $skillId => $rank) { + $TSkills = $skill->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_object=' . ((int) $id) . " AND objecttype='" . $db->escape($objecttype) . "' AND fk_skill = " . ((int) $skillId))); + if (is_array($TSkills) && !empty($TSkills)) { + foreach ($TSkills as $tmpObj) { + $tmpObj->rank = $rank; + $tmpObj->update($user); + } + } + } + } + } elseif ($action == 'confirm_deleteskill' && $confirm == 'yes') { + $skillToDelete = new SkillRank($db); + $ret = $skillToDelete->fetch($lineid); + if ($ret > 0) { + $skillToDelete->delete($user); + } + } +} + +/* + * View + * + * Put here all code to build page + */ + +$form = new Form($db); +$formfile = new FormFile($db); +$formproject = new FormProjets($db); + +$title = $langs->trans("RequiredSkills"); +$help_url = ''; +llxHeader('', $title, $help_url); + +// Part to show record +if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) { + $res = $object->fetch_optionals(); + + // view configuration + if ($objecttype == 'job') { + require_once DOL_DOCUMENT_ROOT . '/hrm/lib/hrm_job.lib.php'; + $head = jobPrepareHead($object); + $listLink = dol_buildpath('/hrm/job_list.php', 1); + } elseif ($objecttype == "user") { + require_once DOL_DOCUMENT_ROOT . "/core/lib/usergroups.lib.php"; + $object->getRights(); + $head = user_prepare_head($object); + $listLink = dol_buildpath('/user/list.php', 1); + } + + print dol_get_fiche_head($head, 'skill_tab', $langs->trans("Workstation"), -1, $object->picto); + + $formconfirm = ''; + + // Confirmation to delete + /*if ($action == 'delete') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteSkill'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); + }*/ + // Confirmation to delete line + if ($action == 'ask_deleteskill') { + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id . '&objecttype=' . $objecttype . '&lineid=' . $lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteskill', '', 0, 1); + } + // Clone confirmation + /*if ($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); + $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.= $object->label; + $morehtmlref .= '
    '; + + dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'rowid', $morehtmlref, '&objecttype='.$objecttype); + + + // Get all available skills + $static_skill = new Skill($db); + $TAllSkills = $static_skill->fetchAll(); + + // Array format for multiselectarray function + $TAllSkillsFormatted=array(); + if (!empty($TAllSkills)) { + foreach ($TAllSkills as $k=>$v) { + $TAllSkillsFormatted[$k] = $v->label; + } + } + + // table of skillRank linked to current object + $TSkillsJob = $skill->fetchAll('ASC', 't.rowid', 0, 0, array('customsql' => 'fk_object=' . ((int) $id) . " AND objecttype='" . $db->escape($objecttype) . "'")); + + $TAlreadyUsedSkill = array(); + if (is_array($TSkillsJob) && !empty($TSkillsJob)) { + foreach ($TSkillsJob as $skillElement) { + $TAlreadyUsedSkill[$skillElement->fk_skill] = $skillElement->fk_skill; + } + } + + print '
    '; + print '
    '; + print '
    '; + print '' . "\n"; + $object->fields['label']['visible']=0; // Already in banner + include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_view.tpl.php'; + print '
    '; + print '
    '; + + print '

    '; + + if ($objecttype != 'user' && $permissiontoadd) { + // form pour ajouter des compétences + print '
    '; + print ''; + print ''; + print ''; + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
    ' . $langs->trans('AddSkill') . '
    ' . $form->multiselectarray('fk_skill', array_diff_key($TAllSkillsFormatted, $TAlreadyUsedSkill), array(), 0, 0, '', 0, '100%') . '
    '; + print '
    '; + print '
    '; + } + print '
    '; + + print '
    '; + + if ($objecttype != 'user' && $permissiontoadd) { + print '
    '; + print ''; + print ''; + print ''; + } + print '
    '; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + if ($objecttype === 'job') { + print ''; + print ''; + } + print ''; + if (!is_array($TSkillsJob) || empty($TSkillsJob)) { + print ''; + } else { + $sk = new Skill($db); + foreach ($TSkillsJob as $skillElement) { + $sk->fetch($skillElement->fk_skill); + print ''; + print ''; + print ''; + if ($objecttype != 'user' && $permissiontoadd) { + print ''; + print ''; + print ''; + } + } + + print '
    '.$langs->trans('SkillType').''.$langs->trans('Label').''.$langs->trans('Description').''.$langs->trans($objecttype === 'job' ? 'RequiredRank' : 'EmployeeRank').'
    ' . $langs->trans("NoRecordFound") . '
    '; + print Skill::typeCodeToLabel($sk->skill_type); + print ''; + print $sk->getNomUrl(1); + print ''; + print $sk->description; + print ''; + print displayRankInfos($skillElement->rank, $skillElement->fk_skill, 'TNote', $objecttype == 'job' && $permissiontoadd ? 'edit' : 'view'); + print ''; + print 'id . '">'; + print img_delete(); + print ''; + } + print '
    '; + if ($objecttype != 'user' && $permissiontoadd) print ''; + print '
    '; + if ($objecttype != 'user' && $permissiontoadd) print '
    '; + + + // liste des compétences liées + + print dol_get_fiche_end(); + + llxFooter(); +} diff --git a/htdocs/imports/emptyexample.php b/htdocs/imports/emptyexample.php index b919a3c4c3e..6435f91241c 100644 --- a/htdocs/imports/emptyexample.php +++ b/htdocs/imports/emptyexample.php @@ -75,9 +75,6 @@ $filename = $langs->trans("ExampleOfImportFile").'_'.$datatoimport.'.'.$format; $objimport = new Import($db); $objimport->load_arrays($user, $datatoimport); // Load arrays from descriptor module -$entity = $objimport->array_import_entities[0][$code]; -$entityicon = $entitytoicon[$entity] ? $entitytoicon[$entity] : $entity; -$entitylang = $entitytolang[$entity] ? $entitytolang[$entity] : $entity; $fieldstarget = $objimport->array_import_fields[0]; $valuestarget = $objimport->array_import_examplevalues[0]; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 5139e12ab7a..cd416585101 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -465,7 +465,7 @@ if ($step == 2 && $datatoimport) { print ''; // Module - print ''; + print ''; print ''; } } else { - print ''; + print ''; } print '
    '.$langs->trans("Module").'
    '.$langs->trans("Module").''; $titleofmodule = $objimport->array_import_module[0]['module']->getName(); // Special cas for import common to module/services @@ -571,10 +571,10 @@ if ($step == 3 && $datatoimport) { print '
    '; print '
    '; - print ''; + print '
    '; // Module - print ''; + print ''; print ''; - print ''; + print ''; + print ''; print ''; } } else { - print ''; } print '
    '.$langs->trans("Module").'
    '.$langs->trans("Module").''; $titleofmodule = $objimport->array_import_module[0]['module']->getName(); // Special cas for import common to module/services @@ -603,7 +603,7 @@ if ($step == 3 && $datatoimport) { print ''; // Source file format - print ''; + print ''; print '
    '.$langs->trans("SourceFileFormat").'
    '.$langs->trans("SourceFileFormat").''; $text = $objmodelimport->getDriverDescForKey($format); print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text); @@ -706,12 +706,12 @@ if ($step == 3 && $datatoimport) { print $out; print ''; - print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table - print ''; - // Search available imports $filearray = dol_dir_list($conf->import->dir_temp, 'files', 0, '', '', 'name', SORT_DESC); if (count($filearray) > 0) { + print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table + print '
    '; + $dir = $conf->import->dir_temp; // Search available files to import @@ -733,8 +733,8 @@ if ($step == 3 && $datatoimport) { $relativepath = $file; print ''; - print ''; print ''; print ''; } - } - print '
    '.img_mime($file).''; + print img_mime($file, '', 'pictofixedwidth'); print ''; print $file; print ''; @@ -752,10 +752,10 @@ if ($step == 3 && $datatoimport) { print '
    '; - print '
    '; + print '
    '; + print ''; + } print ''; } @@ -876,7 +876,7 @@ if ($step == 4 && $datatoimport) { print ''; // Module - print ''; + print ''; print ''; print ''; - print ''; } else { print ''.$langs->trans("FileNotYetGenerated").''; @@ -3302,7 +3340,7 @@ if ($module == 'initmodule') { print ''; if (!empty($triggers)) { @@ -3311,13 +3349,14 @@ if ($module == 'initmodule') { print ''; + print ''; print ''; print ''; } } else { print ''; print ''; print ''; @@ -3407,11 +3446,11 @@ if ($module == 'initmodule') { print ' '.$langs->trans("JSFile").' : '; if (dol_is_file($dirins.'/'.$pathtohook)) { print ''.$pathtohook.''; - print ''; - print ''; + print ''; + print ''; } else { print ''.$langs->trans("FileNotYetGenerated").''; - print ''; + print ''; } print ''; } else { @@ -3455,13 +3494,13 @@ if ($module == 'initmodule') { $pathtofile = $widget['relpath']; print ''; + print ''; print ''; } } else { print ''; } print '
    '.$langs->trans("Module").'
    '.$langs->trans("Module").''; $titleofmodule = $objimport->array_import_module[0]['module']->getName(); // Special cas for import common to module/services @@ -905,7 +905,7 @@ if ($step == 4 && $datatoimport) { print ''; // Source file format - print ''; + print ''; print ''; } @@ -938,6 +938,7 @@ if ($step == 4 && $datatoimport) { $modulepart = 'import'; $relativepath = GETPOST('filetoimport'); print ''; + print img_mime($file, '', 'pictofixedwidth'); print $filetoimport; print ''; print ''; @@ -1205,7 +1206,7 @@ if ($step == 4 && $datatoimport) { // async: false // });'."\n"; // Now reload page - print 'var newlocation= \''.$_SERVER["PHP_SELF"].'?step=4'.$param.'&action=saveorder&boxorder=\' + boxorder;'."\n"; + print 'var newlocation= \''.$_SERVER["PHP_SELF"].'?step=4'.$param.'&action=saveorder&token='.newToken().'&boxorder=\' + boxorder;'."\n"; //print 'alert(newlocation);'; print 'window.location.href=newlocation;'."\n"; print '}'."\n"; @@ -1385,7 +1386,7 @@ if ($step == 5 && $datatoimport) { print '
    '.$langs->trans("SourceFileFormat").'
    '.$langs->trans("SourceFileFormat").''; $text = $objmodelimport->getDriverDescForKey($format); print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text); @@ -926,8 +926,8 @@ if ($step == 4 && $datatoimport) { print $langs->trans("Separator").' : '; print ''; print '    '.$langs->trans("Enclosure").' : '; - print ''; - print ''; + print ' '; + print ''; print ''; print '
    '; // Module - print ''; + print ''; print ''; } } else { - print ''; + print ''; } print '
    '.$langs->trans("Module").'
    '.$langs->trans("Module").''; $titleofmodule = $objimport->array_import_module[0]['module']->getName(); // Special cas for import common to module/services @@ -1414,7 +1415,7 @@ if ($step == 5 && $datatoimport) { print ''; // Source file format - print ''; + print ''; print ''; @@ -1451,10 +1453,10 @@ if ($step == 5 && $datatoimport) { print $langs->trans("ImportFromToLine"); print ''; print ''; print ''; } } else { - print ''; + print ''; } print '
    '.$langs->trans("SourceFileFormat").'
    '.$langs->trans("SourceFileFormat").''; $text = $objmodelimport->getDriverDescForKey($format); print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text); @@ -1435,6 +1436,7 @@ if ($step == 5 && $datatoimport) { $modulepart = 'import'; $relativepath = GETPOST('filetoimport'); print ''; + print img_mime($file, '', 'pictofixedwidth'); print $filetoimport; print ''; print '
    '; if ($action == 'launchsimu') { - print ''; + print ''; print ''; } else { - print ''; + print ''; print $form->textwithpicto("", $langs->trans("SetThisValueTo2ToExcludeFirstLine")); } print ' - '; @@ -1509,7 +1511,7 @@ if ($step == 5 && $datatoimport) { print ''; // Tables imported - print ''; + print ''; } print '
    '; + print '
    '; print $langs->trans("TablesTarget"); print ''; $listtables = array(); @@ -1675,10 +1677,15 @@ if ($step == 5 && $datatoimport) { print '
    '.img_picto($langs->trans("OK"), 'tick').' '.$langs->trans("NoError").'


    '; print '
    '; print $langs->trans("NbInsert", empty($obj->nbinsert) ? 0 : $obj->nbinsert).'
    '; - print $langs->trans("NbUpdate", empty($obj->nbupdate) ? 0 : $obj->nbupdate).'

    '; + print $langs->trans("NbUpdate", empty($obj->nbupdate) ? 0 : $obj->nbupdate).'
    '; print '
    '; + print '
    '; } else { - print $langs->trans("NbOfLinesOK", $nbok).'

    '; + print '
    '; + print '
    '; + print $langs->trans("NbOfLinesOK", $nbok).'
    '; + print '
    '; + print '
    '; } // Show Errors @@ -1823,7 +1830,7 @@ if ($step == 6 && $datatoimport) { print ''; // Module - print ''; + print ''; print ''; } print '
    '.$langs->trans("Module").'
    '.$langs->trans("Module").''; $titleofmodule = $objimport->array_import_module[0]['module']->getName(); // Special cas for import common to module/services @@ -1852,7 +1859,7 @@ if ($step == 6 && $datatoimport) { print ''; // Source file format - print ''; + print ''; print ''; diff --git a/htdocs/includes/printipp/http_class.php b/htdocs/includes/printipp/http_class.php index 30bb33d663b..553152b5c90 100644 --- a/htdocs/includes/printipp/http_class.php +++ b/htdocs/includes/printipp/http_class.php @@ -4,7 +4,7 @@ /* ==================================================================== * GNU Lesser General Public License * Version 2.1, February 1999 - * + * * Class http_class - Basic http client with "Basic" and Digest/MD5 * authorization mechanism. * handle ipv4/v6 addresses, Unix sockets, http and https @@ -31,13 +31,13 @@ * This class is intended to implement a subset of Hyper Text Transfer Protocol * (HTTP/1.1) on client side (currently: POST operation), with file streaming * capability. - * + * * It can perform Basic and Digest authentication. - * + * * References needed to debug / add functionnalities: * - RFC 2616 * - RFC 2617 - * + * * * Class and Function List: * Function list: @@ -66,58 +66,55 @@ ************************/ class httpException extends Exception { - protected $errno; + protected $errno; - public function __construct ($msg, $errno = null) - { - parent::__construct ($msg); - $this->errno = $errno; - } + public function __construct($msg, $errno = null) + { + parent::__construct($msg); + $this->errno = $errno; + } - public function getErrorFormatted () - { - return sprintf ("[http_class]: %s -- "._(" file %s, line %s"), - $this->getMessage (), $this->getFile (), $this->getLine ()); - } + public function getErrorFormatted() + { + return sprintf("[http_class]: %s -- "._(" file %s, line %s"), + $this->getMessage(), $this->getFile(), $this->getLine()); + } - public function getErrno () - { - return $this->errno; - } + public function getErrno() + { + return $this->errno; + } } function error2string($value) { - $level_names = array( - E_ERROR => 'E_ERROR', - E_WARNING => 'E_WARNING', - E_PARSE => 'E_PARSE', - E_NOTICE => 'E_NOTICE', - E_CORE_ERROR => 'E_CORE_ERROR', - E_CORE_WARNING => 'E_CORE_WARNING', - E_COMPILE_ERROR => 'E_COMPILE_ERROR', - E_COMPILE_WARNING => 'E_COMPILE_WARNING', - E_USER_ERROR => 'E_USER_ERROR', - E_USER_WARNING => 'E_USER_WARNING', - E_USER_NOTICE => 'E_USER_NOTICE' - ); - if(defined('E_STRICT')) { - $level_names[E_STRICT]='E_STRICT'; - } - $levels=array(); - if(($value&E_ALL)==E_ALL) - { - $levels[]='E_ALL'; - $value&=~E_ALL; - } - foreach($level_names as $level=>$name) - { - if(($value&$level)==$level) - { - $levels[]=$name; - } - } - return implode(' | ',$levels); + $level_names = array( + E_ERROR => 'E_ERROR', + E_WARNING => 'E_WARNING', + E_PARSE => 'E_PARSE', + E_NOTICE => 'E_NOTICE', + E_CORE_ERROR => 'E_CORE_ERROR', + E_CORE_WARNING => 'E_CORE_WARNING', + E_COMPILE_ERROR => 'E_COMPILE_ERROR', + E_COMPILE_WARNING => 'E_COMPILE_WARNING', + E_USER_ERROR => 'E_USER_ERROR', + E_USER_WARNING => 'E_USER_WARNING', + E_USER_NOTICE => 'E_USER_NOTICE' + ); + if (defined('E_STRICT')) { + $level_names[E_STRICT]='E_STRICT'; + } + $levels=array(); + if (($value&E_ALL)==E_ALL) { + $levels[]='E_ALL'; + $value&=~E_ALL; + } + foreach ($level_names as $level=>$name) { + if (($value&$level)==$level) { + $levels[]=$name; + } + } + return implode(' | ', $levels); } /*********************** @@ -127,486 +124,427 @@ function error2string($value) ************************/ class http_class { - // variables declaration - public $debug; - public $html_debug; - public $timeout = 30; // time waiting for connection, seconds - public $data_timeout = 30; // time waiting for data, milliseconds - public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond - public $force_multipart_form_post; - public $username; - public $password; - public $request_headers = array (); - public $request_body = "Not a useful information"; - public $status; - public $window_size = 1024; // chunk size of data - public $with_exceptions = 0; // compatibility mode for old scripts - public $port; - public $host; - private $default_port = 631; - private $headers; - private $reply_headers = array (); - private $reply_body = array (); - private $connection; - private $arguments; - private $bodystream = array (); - private $last_limit; - private $connected; - private $nc = 1; - private $user_agent = "PRINTIPP/0.81+CVS"; - private $readed_bytes = 0; + // variables declaration + public $debug; + public $html_debug; + public $timeout = 30; // time waiting for connection, seconds + public $data_timeout = 30; // time waiting for data, milliseconds + public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond + public $force_multipart_form_post; + public $username; + public $password; + public $request_headers = array (); + public $request_body = "Not a useful information"; + public $status; + public $window_size = 1024; // chunk size of data + public $with_exceptions = 0; // compatibility mode for old scripts + public $port; + public $host; + private $default_port = 631; + private $headers; + private $reply_headers = array (); + private $reply_body = array (); + private $connection; + private $arguments; + private $bodystream = array (); + private $last_limit; + private $connected; + private $nc = 1; + private $user_agent = "PRINTIPP/0.81+CVS"; + private $readed_bytes = 0; - public function __construct () - { - true; - } + public function __construct() + { + true; + } - /********************* - * - * Public functions - * - **********************/ + /********************* + * + * Public functions + * + **********************/ - public function GetRequestArguments ($url, &$arguments) - { - $this->arguments = array (); - $this->arguments["URL"] = $arguments["URL"] = $url; - $this->arguments["RequestMethod"] = $arguments["RequestMethod"] = "POST"; - $this->headers["Content-Length"] = 0; - $this->headers["Content-Type"] = "application/octet-stream"; - $this->headers["Host"] = $this->host; - $this->headers["User-Agent"] = $this->user_agent; - //$this->headers["Expect"] = "100-continue"; - } + public function GetRequestArguments($url, &$arguments) + { + $this->arguments = array (); + $this->arguments["URL"] = $arguments["URL"] = $url; + $this->arguments["RequestMethod"] = $arguments["RequestMethod"] = "POST"; + $this->headers["Content-Length"] = 0; + $this->headers["Content-Type"] = "application/octet-stream"; + $this->headers["Host"] = $this->host; + $this->headers["User-Agent"] = $this->user_agent; + //$this->headers["Expect"] = "100-continue"; + } - public function Open ($arguments) - { - $this->connected = false; - $url = $arguments["URL"]; - $port = $this->default_port; - #$url = split (':', $url, 2); - $url = preg_split ('#:#', $url, 2); - $transport_type = $url[0]; - $unix = false; - switch ($transport_type) - { - case 'http': - $transport_type = 'tcp://'; - break; + public function Open($arguments) + { + $this->connected = false; + $url = $arguments["URL"]; + $port = $this->default_port; + // $url = split (':', $url, 2); + $url = preg_split('#:#', $url, 2); + $transport_type = $url[0]; + $unix = false; + switch ($transport_type) { + case 'http': + $transport_type = 'tcp://'; + break; - case 'https': - $transport_type = 'tls://'; - break; + case 'https': + $transport_type = 'tls://'; + break; - case 'unix': - $transport_type = 'unix://'; - $port = 0; - $unix = true; - break; + case 'unix': + $transport_type = 'unix://'; + $port = 0; + $unix = true; + break; - default: - $transport_type = 'tcp://'; - break; - } - $url = $url[1]; - if (!$unix) - { - #$url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2); - $url = preg_split ("#/#", preg_replace ("#^/{1,}#", '', $url), 2); - $url = $url[0]; - $port = $this->port; - $error = sprintf (_("Cannot resolve url: %s"), $url); - $ip = gethostbyname ($url); - $ip = @gethostbyaddr ($ip); - if (!$ip) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - if (strstr ($url, ":")) // we got an ipv6 address - { - if (!strstr ($url, "[")) // it is not escaped - { - $url = sprintf ("[%s]", $url); - } - } - } - $this->connection = @fsockopen ($transport_type.$url, $port, $errno, $errstr, $this->timeout); - $error = - sprintf (_('Unable to connect to "%s%s port %s": %s'), $transport_type, - $url, $port, $errstr); - if (!$this->connection) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - $this->connected = true; - return array (true, "success"); - } + default: + $transport_type = 'tcp://'; + break; + } + $url = $url[1]; + if (!$unix) { + // $url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2); + $url = preg_split("#/#", preg_replace("#^/{1,}#", '', $url), 2); + $url = $url[0]; + $port = $this->port; + $error = sprintf(_("Cannot resolve url: %s"), $url); + $ip = gethostbyname($url); + $ip = @gethostbyaddr($ip); + if (!$ip) { + return $this->_HttpError($error, E_USER_WARNING); + } + if (strstr($url, ":")) { // we got an ipv6 address + if (!strstr($url, "[")) { // it is not escaped + $url = sprintf("[%s]", $url); + } + } + } + $this->connection = @fsockopen($transport_type.$url, $port, $errno, $errstr, $this->timeout); + $error = + sprintf(_('Unable to connect to "%s%s port %s": %s'), $transport_type, + $url, $port, $errstr); + if (!$this->connection) { + return $this->_HttpError($error, E_USER_WARNING); + } + $this->connected = true; + return array (true, "success"); + } - public function SendRequest ($arguments) - { - $error = - sprintf (_('Streaming request failed to %s'), $arguments['RequestURI']); - $result = self::_StreamRequest ($arguments); - if (!$result[0]) - { - return $this->_HttpError ($error." ".$result[1], E_USER_WARNING); - } - self::_ReadReply (); - if (!preg_match ('#http/1.1 401 unauthorized#', $this->status)) - { - return array (true, "success"); - } - $headers = array_keys ($this->reply_headers); - $error = _("need authentication but no mechanism provided"); - if (!in_array ("www-authenticate", $headers)) - { - return $this->_HttpError ($error, E_USER_WARNING); - } - #$authtype = split (' ', $this->reply_headers["www-authenticate"]); - $authtype = preg_split ('# #', $this->reply_headers["www-authenticate"]); - $authtype = strtolower ($authtype[0]); - switch ($authtype) - { - case 'basic': - $pass = base64_encode ($this->user.":".$this->password); - $arguments["Headers"]["Authorization"] = "Basic ".$pass; - break; + public function SendRequest($arguments) + { + $error = + sprintf(_('Streaming request failed to %s'), $arguments['RequestURI']); + $result = self::_StreamRequest($arguments); + if (!$result[0]) { + return $this->_HttpError($error." ".$result[1], E_USER_WARNING); + } + self::_ReadReply(); + if (!preg_match('#http/1.1 401 unauthorized#', $this->status)) { + return array (true, "success"); + } + $headers = array_keys($this->reply_headers); + $error = _("need authentication but no mechanism provided"); + if (!in_array("www-authenticate", $headers)) { + return $this->_HttpError($error, E_USER_WARNING); + } + // $authtype = split (' ', $this->reply_headers["www-authenticate"]); + $authtype = preg_split('# #', $this->reply_headers["www-authenticate"]); + $authtype = strtolower($authtype[0]); + switch ($authtype) { + case 'basic': + $pass = base64_encode($this->user.":".$this->password); + $arguments["Headers"]["Authorization"] = "Basic ".$pass; + break; - case 'digest': - $arguments["Headers"]["Authorization"] = self::_BuildDigest (); - break; + case 'digest': + $arguments["Headers"]["Authorization"] = self::_BuildDigest(); + break; - default: - $error = - sprintf (_("need '%s' authentication mechanism, but have not"), - $authtype[0]); - return $this->_HttpError ($error, E_USER_WARNING); - break; - } - self::Close (); - self::Open ($arguments); + default: + $error = + sprintf(_("need '%s' authentication mechanism, but have not"), + $authtype[0]); + return $this->_HttpError($error, E_USER_WARNING); + break; + } + self::Close(); + self::Open($arguments); - $error = sprintf(_('Streaming request failed to %s after a try to authenticate'), $arguments['RequestURI']); - $result = self::_StreamRequest ($arguments); - if (!$result[0]) - { - return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING); - } - self::_ReadReply (); - return array (true, "success"); - } + $error = sprintf(_('Streaming request failed to %s after a try to authenticate'), $arguments['RequestURI']); + $result = self::_StreamRequest($arguments); + if (!$result[0]) { + return $this->_HttpError($error.": ".$result[1], E_USER_WARNING); + } + self::_ReadReply(); + return array (true, "success"); + } - public function ReadReplyHeaders (&$headers) - { - $headers = $this->reply_headers; - } + public function ReadReplyHeaders(&$headers) + { + $headers = $this->reply_headers; + } - public function ReadReplyBody (&$body, $chunk_size) - { - $body = substr ($this->reply_body, $this->last_limit, $chunk_size); - $this->last_limit += $chunk_size; - } + public function ReadReplyBody(&$body, $chunk_size) + { + $body = substr($this->reply_body, $this->last_limit, $chunk_size); + $this->last_limit += $chunk_size; + } - public function Close () - { - if (!$this->connected) - { - return; - } - fclose ($this->connection); - } + public function Close() + { + if (!$this->connected) { + return; + } + fclose($this->connection); + } - /********************* - * - * Private functions - * - *********************/ + /********************* + * + * Private functions + * + *********************/ - private function _HttpError ($msg, $level, $errno = null) - { - $trace = ''; - $backtrace = debug_backtrace(); - foreach ($backtrace as $trace) - { - $trace .= sprintf ("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'],$trace['line']); - } - $msg = sprintf ( '%s\n%s: [errno: %s]: %s', - $trace, error2string ($level), $errno, $msg); - if ($this->with_exceptions) - { - throw new httpException ($msg, $errno); - } - else - { - trigger_error ($msg, $level); - return array (false, $msg); - } - } + private function _HttpError($msg, $level, $errno = null) + { + $trace = ''; + $backtrace = debug_backtrace(); + foreach ($backtrace as $trace) { + $trace .= sprintf("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'], $trace['line']); + } + $msg = sprintf( '%s\n%s: [errno: %s]: %s', + $trace, error2string($level), $errno, $msg); + if ($this->with_exceptions) { + throw new httpException($msg, $errno); + } else { + trigger_error($msg, $level); + return array (false, $msg); + } + } - private function _streamString ($string) - { - $success = fwrite ($this->connection, $string); - if (!$success) - { - return false; - } - return true; - } + private function _streamString($string) + { + $success = fwrite($this->connection, $string); + if (!$success) { + return false; + } + return true; + } - private function _StreamRequest ($arguments) - { - $this->status = false; - $this->reply_headers = array (); - $this->reply_body = ""; - if (!$this->connected) - { - return $this->_HttpError (_("not connected"), E_USER_WARNING); - } - $this->arguments = $arguments; - $content_length = 0; - foreach ($this->arguments["BodyStream"] as $argument) - { - list ($type, $value) = each ($argument); - reset ($argument); - if ($type == "Data") - { - $length = strlen ($value); - } - elseif ($type == "File") - { - if (is_readable ($value)) - { - $length = filesize ($value); - } - else - { - $length = 0; - return $this->_HttpError (sprintf (_("%s: file is not readable"), $value), E_USER_WARNING); - } - } - else - { - $length = 0; - return $this->_HttpError (sprintf(_("%s: not a valid argument for content"), $type), E_USER_WARNING); - } - $content_length += $length; - } - $this->request_body = sprintf (_("%s Bytes"), $content_length); - $this->headers["Content-Length"] = $content_length; - $this->arguments["Headers"] = array_merge ($this->headers, $this->arguments["Headers"]); - if ($this->arguments["RequestMethod"] != "POST") - { - return $this->_HttpError (sprintf(_("%s: method not implemented"), $arguments["RequestMethod"]), E_USER_WARNING); - } - $string = sprintf ("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]); - $this->request_headers[$string] = ''; - if (!$this->_streamString ($string)) - { - return $this->_HttpError (_("Error while puts POST operation"), E_USER_WARNING); - } - foreach ($this->arguments["Headers"] as $header => $value) - { - $string = sprintf ("%s: %s\r\n", $header, $value); - $this->request_headers[$header] = $value; - if (!$this->_streamString ($string)) - { - return $this->_HttpError (_("Error while puts HTTP headers"), E_USER_WARNING); - } - } - $string = "\r\n"; - if (!$this->_streamString ($string)) - { - return $this->_HttpError (_("Error while ends HTTP headers"), E_USER_WARNING); - } - foreach ($this->arguments["BodyStream"] as $argument) - { - list ($type, $value) = each ($argument); - reset ($argument); - if ($type == "Data") - { - $streamed_length = 0; - while ($streamed_length < strlen ($value)) - { - $string = substr ($value, $streamed_length, $this->window_size); - if (!$this->_streamString ($string)) - { - return $this->_HttpError (_("error while sending body data"), E_USER_WARNING); - } - $streamed_length += $this->window_size; - } - } - elseif ($type == "File") - { - if (is_readable ($value)) - { - $file = fopen ($value, 'rb'); - while (!feof ($file)) - { - if (gettype ($block = @fread ($file, $this->window_size)) != "string") - { - return $this->_HttpError (_("cannot read file to upload"), E_USER_WARNING); - } - if (!$this->_streamString ($block)) - { - return $this->_HttpError (_("error while sending body data"), E_USER_WARNING); - } - } - } - } - } - return array (true, "success"); - } + private function _StreamRequest($arguments) + { + $this->status = false; + $this->reply_headers = array (); + $this->reply_body = ""; + if (!$this->connected) { + return $this->_HttpError(_("not connected"), E_USER_WARNING); + } + $this->arguments = $arguments; + $content_length = 0; + foreach ($this->arguments["BodyStream"] as $argument) { + // list ($type, $value) = each ($argument); + $type = key($argument); + $value = current($argument); + reset($argument); + if ($type == "Data") { + $length = strlen($value); + } elseif ($type == "File") { + if (is_readable($value)) { + $length = filesize($value); + } else { + $length = 0; + return $this->_HttpError(sprintf(_("%s: file is not readable"), $value), E_USER_WARNING); + } + } else { + $length = 0; + return $this->_HttpError(sprintf(_("%s: not a valid argument for content"), $type), E_USER_WARNING); + } + $content_length += $length; + } + $this->request_body = sprintf(_("%s Bytes"), $content_length); + $this->headers["Content-Length"] = $content_length; + $this->arguments["Headers"] = array_merge($this->headers, $this->arguments["Headers"]); + if ($this->arguments["RequestMethod"] != "POST") { + return $this->_HttpError(sprintf(_("%s: method not implemented"), $arguments["RequestMethod"]), E_USER_WARNING); + } + $string = sprintf("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]); + $this->request_headers[$string] = ''; + if (!$this->_streamString($string)) { + return $this->_HttpError(_("Error while puts POST operation"), E_USER_WARNING); + } + foreach ($this->arguments["Headers"] as $header => $value) { + $string = sprintf("%s: %s\r\n", $header, $value); + $this->request_headers[$header] = $value; + if (!$this->_streamString($string)) { + return $this->_HttpError(_("Error while puts HTTP headers"), E_USER_WARNING); + } + } + $string = "\r\n"; + if (!$this->_streamString($string)) { + return $this->_HttpError(_("Error while ends HTTP headers"), E_USER_WARNING); + } + foreach ($this->arguments["BodyStream"] as $argument) { + // list ($type, $value) = each ($argument); + $type = key($argument); + $value = current($argument); + reset($argument); + if ($type == "Data") { + $streamed_length = 0; + while ($streamed_length < strlen($value)) { + $string = substr($value, $streamed_length, $this->window_size); + if (!$this->_streamString($string)) { + return $this->_HttpError(_("error while sending body data"), E_USER_WARNING); + } + $streamed_length += $this->window_size; + } + } elseif ($type == "File") { + if (is_readable($value)) { + $file = fopen($value, 'rb'); + while (!feof($file)) { + if (gettype($block = @fread($file, $this->window_size)) != "string") { + return $this->_HttpError(_("cannot read file to upload"), E_USER_WARNING); + } + if (!$this->_streamString($block)) { + return $this->_HttpError(_("error while sending body data"), E_USER_WARNING); + } + } + } + } + } + return array (true, "success"); + } - private function _ReadReply () - { - if (!$this->connected) - { - return array (false, _("not connected")); - } - $this->reply_headers = array (); - $this->reply_body = ""; - $headers = array (); - $body = ""; - while (!feof ($this->connection)) - { - $line = fgets ($this->connection, 1024); - if (strlen (trim($line)) == 0) - { - break; - } // \r\n => end of headers - if (preg_match ('#^[[:space:]]#', $line)) - { - $headers[-1] .= sprintf(' %s', trim ($line)); - continue; - } - $headers[] = trim ($line); - } - $this->status = isset ($headers[0]) ? strtolower ($headers[0]) : false; - foreach ($headers as $header) - { - $header = preg_split ("#: #", $header); - $header[0] = strtolower ($header[0]); - if ($header[0] !== "www-authenticate") - { - $header[1] = isset ($header[1]) ? strtolower ($header[1]) : ""; - } - if (!isset ($this->reply_headers[$header[0]])) - { - $this->reply_headers[$header[0]] = $header[1]; - } - } - self::_ReadStream (); - return true; - } + private function _ReadReply() + { + if (!$this->connected) { + return array (false, _("not connected")); + } + $this->reply_headers = array (); + $this->reply_body = ""; + $headers = array (); + $body = ""; + while (!feof($this->connection)) { + $line = fgets($this->connection, 1024); + if (strlen(trim($line)) == 0) { + break; + } // \r\n => end of headers + if (preg_match('#^[[:space:]]#', $line)) { + $headers[-1] .= sprintf(' %s', trim($line)); + continue; + } + $headers[] = trim($line); + } + $this->status = isset($headers[0]) ? strtolower($headers[0]) : false; + foreach ($headers as $header) { + $header = preg_split("#: #", $header); + $header[0] = strtolower($header[0]); + if ($header[0] !== "www-authenticate") { + $header[1] = isset($header[1]) ? strtolower($header[1]) : ""; + } + if (!isset($this->reply_headers[$header[0]])) { + $this->reply_headers[$header[0]] = $header[1]; + } + } + self::_ReadStream(); + return true; + } - private function _ReadStream () - { - if (! array_key_exists ("content-length", $this->reply_headers)) - { - stream_set_blocking($this->connection, 0); - $this->reply_body = stream_get_contents($this->connection); - return true; - } - stream_set_blocking($this->connection, 1); - $content_length = $this->reply_headers["content-length"]; - $this->reply_body = stream_get_contents($this->connection,$content_length); - return true; - } + private function _ReadStream() + { + if (! array_key_exists("content-length", $this->reply_headers)) { + stream_set_blocking($this->connection, 0); + $this->reply_body = stream_get_contents($this->connection); + return true; + } + stream_set_blocking($this->connection, 1); + $content_length = $this->reply_headers["content-length"]; + $this->reply_body = stream_get_contents($this->connection, $content_length); + return true; + } - private function _BuildDigest () - { - $auth = $this->reply_headers["www-authenticate"]; - #list ($head, $auth) = split (" ", $auth, 2); - list ($head, $auth) = preg_split ("# #", $auth, 2); - #$auth = split (", ", $auth); - $auth = preg_split ("#, #", $auth); - foreach ($auth as $sheme) - { - #list ($sheme, $value) = split ('=', $sheme); - list ($sheme, $value) = preg_split ('#=#', $sheme); - $fields[$sheme] = trim (trim ($value), '"'); - } - $nc = sprintf ('%x', $this->nc); - $prepend = ""; - while ((strlen ($nc) + strlen ($prepend)) < 8) - $prependi .= "0"; - $nc = $prepend.$nc; - $cnonce = "printipp"; - $username = $this->user; - $password = $this->password; - $A1 = $username.":".$fields["realm"].":".$password; - if (array_key_exists ("algorithm", $fields)) - { - $algorithm = strtolower ($fields["algorithm"]); - switch ($algorithm) - { - case "md5": - break; + private function _BuildDigest() + { + $auth = $this->reply_headers["www-authenticate"]; + // list ($head, $auth) = split (" ", $auth, 2); + list ($head, $auth) = preg_split("# #", $auth, 2); + // $auth = split (", ", $auth); + $auth = preg_split("#, #", $auth); + foreach ($auth as $sheme) { + // list ($sheme, $value) = split ('=', $sheme); + list ($sheme, $value) = preg_split('#=#', $sheme); + $fields[$sheme] = trim(trim($value), '"'); + } + $nc = sprintf('%x', $this->nc); + $prepend = ""; + while ((strlen($nc) + strlen($prepend)) < 8) + $prependi .= "0"; + $nc = $prepend.$nc; + $cnonce = "printipp"; + $username = $this->user; + $password = $this->password; + $A1 = $username.":".$fields["realm"].":".$password; + if (array_key_exists("algorithm", $fields)) { + $algorithm = strtolower($fields["algorithm"]); + switch ($algorithm) { + case "md5": + break; - case "md5-sess": - $A1 = - $username.":".$fields["realm"].":".$password.":". - $fields['nonce'].":".$cnonce; - break; + case "md5-sess": + $A1 = + $username.":".$fields["realm"].":".$password.":". + $fields['nonce'].":".$cnonce; + break; - default: - return $this->_HttpError( - sprintf (_("digest Authorization: algorithm '%s' not implemented"), - $algorithm), - E_USER_WARNING); - return false; - break; - } - } - $A2 = "POST:".$this->arguments["RequestURI"]; - if (array_key_exists ("qop", $fields)) - { - $qop = strtolower ($fields["qop"]); - #$qop = split (" ", $qop); - $qop = preg_split ("# #", $qop); - if (in_array ("auth", $qop)) - { - $qop = "auth"; - } - else - { - self::_HttpError( - sprintf (_("digest Authorization: algorithm '%s' not implemented"), - $qop), - E_USER_WARNING); - return false; - } - } - $response = md5 (md5 ($A1).":".$fields["nonce"].":".md5 ($A2)); - if (isset ($qop) && ($qop == "auth")) - { - $response = - md5 (md5 ($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop. - ":".$A2); - } - $auth_scheme = - sprintf - ('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"', - $username, $fields["realm"], $fields['nonce'], - $this->arguments["RequestURI"], $response); - if (isset ($algorithm)) - { - $auth_scheme .= sprintf (', algorithm="%s"', $algorithm); - } - if (isset ($qop)) - { - $auth_scheme .= sprintf (', cnonce="%s"', $cnonce); - } - if (array_key_exists ("opaque", $fields)) - { - $auth_scheme .= sprintf (', opaque="%s"', $fields['opaque']); - } - if (isset ($qop)) - { - $auth_scheme .= sprintf (', qop="%s"', $qop); - } - $auth_scheme .= sprintf (', nc=%s', $nc); - $this->nc++; - return $auth_scheme; - } + default: + return $this->_HttpError( + sprintf(_("digest Authorization: algorithm '%s' not implemented"), + $algorithm), + E_USER_WARNING); + return false; + break; + } + } + $A2 = "POST:".$this->arguments["RequestURI"]; + if (array_key_exists("qop", $fields)) { + $qop = strtolower($fields["qop"]); + // $qop = split (" ", $qop); + $qop = preg_split("# #", $qop); + if (in_array("auth", $qop)) { + $qop = "auth"; + } else { + self::_HttpError( + sprintf(_("digest Authorization: algorithm '%s' not implemented"), + $qop), + E_USER_WARNING); + return false; + } + } + $response = md5(md5($A1).":".$fields["nonce"].":".md5($A2)); + if (isset($qop) && ($qop == "auth")) { + $response = + md5(md5($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop. + ":".$A2); + } + $auth_scheme = + sprintf('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"', + $username, $fields["realm"], $fields['nonce'], + $this->arguments["RequestURI"], $response); + if (isset($algorithm)) { + $auth_scheme .= sprintf(', algorithm="%s"', $algorithm); + } + if (isset($qop)) { + $auth_scheme .= sprintf(', cnonce="%s"', $cnonce); + } + if (array_key_exists("opaque", $fields)) { + $auth_scheme .= sprintf(', opaque="%s"', $fields['opaque']); + } + if (isset($qop)) { + $auth_scheme .= sprintf(', qop="%s"', $qop); + } + $auth_scheme .= sprintf(', nc=%s', $nc); + $this->nc++; + return $auth_scheme; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/AmqpCaster.php b/htdocs/includes/symfony/var-dumper/Caster/AmqpCaster.php index 4e9b351c181..4f1aa18a053 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/AmqpCaster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/AmqpCaster.php @@ -20,145 +20,191 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class AmqpCaster { - private static $flags = array( - AMQP_DURABLE => 'AMQP_DURABLE', - AMQP_PASSIVE => 'AMQP_PASSIVE', - AMQP_EXCLUSIVE => 'AMQP_EXCLUSIVE', - AMQP_AUTODELETE => 'AMQP_AUTODELETE', - AMQP_INTERNAL => 'AMQP_INTERNAL', - AMQP_NOLOCAL => 'AMQP_NOLOCAL', - AMQP_AUTOACK => 'AMQP_AUTOACK', - AMQP_IFEMPTY => 'AMQP_IFEMPTY', - AMQP_IFUNUSED => 'AMQP_IFUNUSED', - AMQP_MANDATORY => 'AMQP_MANDATORY', - AMQP_IMMEDIATE => 'AMQP_IMMEDIATE', - AMQP_MULTIPLE => 'AMQP_MULTIPLE', - AMQP_NOWAIT => 'AMQP_NOWAIT', - AMQP_REQUEUE => 'AMQP_REQUEUE', - ); + private static $flags = array( + AMQP_DURABLE => 'AMQP_DURABLE', + AMQP_PASSIVE => 'AMQP_PASSIVE', + AMQP_EXCLUSIVE => 'AMQP_EXCLUSIVE', + AMQP_AUTODELETE => 'AMQP_AUTODELETE', + AMQP_INTERNAL => 'AMQP_INTERNAL', + AMQP_NOLOCAL => 'AMQP_NOLOCAL', + AMQP_AUTOACK => 'AMQP_AUTOACK', + AMQP_IFEMPTY => 'AMQP_IFEMPTY', + AMQP_IFUNUSED => 'AMQP_IFUNUSED', + AMQP_MANDATORY => 'AMQP_MANDATORY', + AMQP_IMMEDIATE => 'AMQP_IMMEDIATE', + AMQP_MULTIPLE => 'AMQP_MULTIPLE', + AMQP_NOWAIT => 'AMQP_NOWAIT', + AMQP_REQUEUE => 'AMQP_REQUEUE', + ); - private static $exchangeTypes = array( - AMQP_EX_TYPE_DIRECT => 'AMQP_EX_TYPE_DIRECT', - AMQP_EX_TYPE_FANOUT => 'AMQP_EX_TYPE_FANOUT', - AMQP_EX_TYPE_TOPIC => 'AMQP_EX_TYPE_TOPIC', - AMQP_EX_TYPE_HEADERS => 'AMQP_EX_TYPE_HEADERS', - ); + private static $exchangeTypes = array( + AMQP_EX_TYPE_DIRECT => 'AMQP_EX_TYPE_DIRECT', + AMQP_EX_TYPE_FANOUT => 'AMQP_EX_TYPE_FANOUT', + AMQP_EX_TYPE_TOPIC => 'AMQP_EX_TYPE_TOPIC', + AMQP_EX_TYPE_HEADERS => 'AMQP_EX_TYPE_HEADERS', + ); - public static function castConnection(\AMQPConnection $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; + public static function castConnection(\AMQPConnection $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; - // BC layer in the ampq lib - if (method_exists($c, 'getReadTimeout')) { - $timeout = $c->getReadTimeout(); - } else { - $timeout = $c->getTimeout(); - } + $a += array( + $prefix.'is_connected' => $c->isConnected(), + ); - $a += array( - $prefix.'isConnected' => $c->isConnected(), - $prefix.'login' => $c->getLogin(), - $prefix.'password' => $c->getPassword(), - $prefix.'host' => $c->getHost(), - $prefix.'port' => $c->getPort(), - $prefix.'vhost' => $c->getVhost(), - $prefix.'readTimeout' => $timeout, - ); + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPConnection\x00login"])) { + return $a; + } - return $a; - } + // BC layer in the amqp lib + if (method_exists($c, 'getReadTimeout')) { + $timeout = $c->getReadTimeout(); + } else { + $timeout = $c->getTimeout(); + } - public static function castChannel(\AMQPChannel $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; + $a += array( + $prefix.'is_connected' => $c->isConnected(), + $prefix.'login' => $c->getLogin(), + $prefix.'password' => $c->getPassword(), + $prefix.'host' => $c->getHost(), + $prefix.'vhost' => $c->getVhost(), + $prefix.'port' => $c->getPort(), + $prefix.'read_timeout' => $timeout, + ); - $a += array( - $prefix.'isConnected' => $c->isConnected(), - $prefix.'channelId' => $c->getChannelId(), - $prefix.'prefetchSize' => $c->getPrefetchSize(), - $prefix.'prefetchCount' => $c->getPrefetchCount(), - $prefix.'connection' => $c->getConnection(), - ); + return $a; + } - return $a; - } + public static function castChannel(\AMQPChannel $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; - public static function castQueue(\AMQPQueue $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; + $a += array( + $prefix.'is_connected' => $c->isConnected(), + $prefix.'channel_id' => $c->getChannelId(), + ); - $a += array( - $prefix.'name' => $c->getName(), - $prefix.'flags' => self::extractFlags($c->getFlags()), - $prefix.'arguments' => $c->getArguments(), - $prefix.'connection' => $c->getConnection(), - $prefix.'channel' => $c->getChannel(), - ); + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPChannel\x00connection"])) { + return $a; + } - return $a; - } + $a += array( + $prefix.'connection' => $c->getConnection(), + $prefix.'prefetch_size' => $c->getPrefetchSize(), + $prefix.'prefetch_count' => $c->getPrefetchCount(), + ); - public static function castExchange(\AMQPExchange $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; + return $a; + } - $a += array( - $prefix.'name' => $c->getName(), - $prefix.'flags' => self::extractFlags($c->getFlags()), - $prefix.'type' => isset(self::$exchangeTypes[$c->getType()]) ? new ConstStub(self::$exchangeTypes[$c->getType()], $c->getType()) : $c->getType(), - $prefix.'arguments' => $c->getArguments(), - $prefix.'channel' => $c->getChannel(), - $prefix.'connection' => $c->getConnection(), - ); + public static function castQueue(\AMQPQueue $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; - return $a; - } + $a += array( + $prefix.'flags' => self::extractFlags($c->getFlags()), + ); - public static function castEnvelope(\AMQPEnvelope $c, array $a, Stub $stub, $isNested, $filter = 0) - { - $prefix = Caster::PREFIX_VIRTUAL; + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPQueue\x00name"])) { + return $a; + } - if (!($filter & Caster::EXCLUDE_VERBOSE)) { - $a += array($prefix.'body' => $c->getBody()); - } + $a += array( + $prefix.'connection' => $c->getConnection(), + $prefix.'channel' => $c->getChannel(), + $prefix.'name' => $c->getName(), + $prefix.'arguments' => $c->getArguments(), + ); - $a += array( - $prefix.'routingKey' => $c->getRoutingKey(), - $prefix.'deliveryTag' => $c->getDeliveryTag(), - $prefix.'deliveryMode' => new ConstStub($c->getDeliveryMode().(2 === $c->getDeliveryMode() ? ' (persistent)' : ' (non-persistent)'), $c->getDeliveryMode()), - $prefix.'exchangeName' => $c->getExchangeName(), - $prefix.'isRedelivery' => $c->isRedelivery(), - $prefix.'contentType' => $c->getContentType(), - $prefix.'contentEncoding' => $c->getContentEncoding(), - $prefix.'type' => $c->getType(), - $prefix.'timestamp' => $c->getTimestamp(), - $prefix.'priority' => $c->getPriority(), - $prefix.'expiration' => $c->getExpiration(), - $prefix.'userId' => $c->getUserId(), - $prefix.'appId' => $c->getAppId(), - $prefix.'messageId' => $c->getMessageId(), - $prefix.'replyTo' => $c->getReplyTo(), - $prefix.'correlationId' => $c->getCorrelationId(), - $prefix.'headers' => $c->getHeaders(), - ); + return $a; + } - return $a; - } + public static function castExchange(\AMQPExchange $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; - private static function extractFlags($flags) - { - $flagsArray = array(); + $a += array( + $prefix.'flags' => self::extractFlags($c->getFlags()), + ); - foreach (self::$flags as $value => $name) { - if ($flags & $value) { - $flagsArray[] = $name; - } - } + $type = isset(self::$exchangeTypes[$c->getType()]) ? new ConstStub(self::$exchangeTypes[$c->getType()], $c->getType()) : $c->getType(); - if (!$flagsArray) { - $flagsArray = array('AMQP_NOPARAM'); - } + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPExchange\x00name"])) { + $a["\x00AMQPExchange\x00type"] = $type; - return new ConstStub(implode('|', $flagsArray), $flags); - } + return $a; + } + + $a += array( + $prefix.'connection' => $c->getConnection(), + $prefix.'channel' => $c->getChannel(), + $prefix.'name' => $c->getName(), + $prefix.'type' => $type, + $prefix.'arguments' => $c->getArguments(), + ); + + return $a; + } + + public static function castEnvelope(\AMQPEnvelope $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $prefix = Caster::PREFIX_VIRTUAL; + + $deliveryMode = new ConstStub($c->getDeliveryMode().(2 === $c->getDeliveryMode() ? ' (persistent)' : ' (non-persistent)'), $c->getDeliveryMode()); + + // Recent version of the extension already expose private properties + if (isset($a["\x00AMQPEnvelope\x00body"])) { + $a["\0AMQPEnvelope\0delivery_mode"] = $deliveryMode; + + return $a; + } + + if (!($filter & Caster::EXCLUDE_VERBOSE)) { + $a += array($prefix.'body' => $c->getBody()); + } + + $a += array( + $prefix.'delivery_tag' => $c->getDeliveryTag(), + $prefix.'is_redelivery' => $c->isRedelivery(), + $prefix.'exchange_name' => $c->getExchangeName(), + $prefix.'routing_key' => $c->getRoutingKey(), + $prefix.'content_type' => $c->getContentType(), + $prefix.'content_encoding' => $c->getContentEncoding(), + $prefix.'headers' => $c->getHeaders(), + $prefix.'delivery_mode' => $deliveryMode, + $prefix.'priority' => $c->getPriority(), + $prefix.'correlation_id' => $c->getCorrelationId(), + $prefix.'reply_to' => $c->getReplyTo(), + $prefix.'expiration' => $c->getExpiration(), + $prefix.'message_id' => $c->getMessageId(), + $prefix.'timestamp' => $c->getTimeStamp(), + $prefix.'type' => $c->getType(), + $prefix.'user_id' => $c->getUserId(), + $prefix.'app_id' => $c->getAppId(), + ); + + return $a; + } + + private static function extractFlags($flags) + { + $flagsArray = array(); + + foreach (self::$flags as $value => $name) { + if ($flags & $value) { + $flagsArray[] = $name; + } + } + + if (!$flagsArray) { + $flagsArray = array('AMQP_NOPARAM'); + } + + return new ConstStub(implode('|', $flagsArray), $flags); + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/ArgsStub.php b/htdocs/includes/symfony/var-dumper/Caster/ArgsStub.php new file mode 100644 index 00000000000..0fa2e17fa5e --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Caster/ArgsStub.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Represents a list of function arguments. + * + * @author Nicolas Grekas + */ +class ArgsStub extends EnumStub +{ + private static $parameters = array(); + + public function __construct(array $args, $function, $class) + { + list($variadic, $params) = self::getParameters($function, $class); + + $values = array(); + foreach ($args as $k => $v) { + $values[$k] = !is_scalar($v) && !$v instanceof Stub ? new CutStub($v) : $v; + } + if (null === $params) { + parent::__construct($values, false); + + return; + } + if (count($values) < count($params)) { + $params = array_slice($params, 0, count($values)); + } elseif (count($values) > count($params)) { + $values[] = new EnumStub(array_splice($values, count($params)), false); + $params[] = $variadic; + } + if (array('...') === $params) { + $this->dumpKeys = false; + $this->value = $values[0]->value; + } else { + $this->value = array_combine($params, $values); + } + } + + private static function getParameters($function, $class) + { + if (isset(self::$parameters[$k = $class.'::'.$function])) { + return self::$parameters[$k]; + } + + try { + $r = null !== $class ? new \ReflectionMethod($class, $function) : new \ReflectionFunction($function); + } catch (\ReflectionException $e) { + return array(null, null); + } + + $variadic = '...'; + $params = array(); + foreach ($r->getParameters() as $v) { + $k = '$'.$v->name; + if ($v->isPassedByReference()) { + $k = '&'.$k; + } + if (method_exists($v, 'isVariadic') && $v->isVariadic()) { + $variadic .= $k; + } else { + $params[] = $k; + } + } + + return self::$parameters[$k] = array($variadic, $params); + } +} diff --git a/htdocs/includes/symfony/var-dumper/Caster/Caster.php b/htdocs/includes/symfony/var-dumper/Caster/Caster.php index 23e72e87701..701c83a599e 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/Caster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/Caster.php @@ -11,6 +11,8 @@ namespace Symfony\Component\VarDumper\Caster; +use Symfony\Component\VarDumper\Cloner\Stub; + /** * Helper for filtering out properties in casters. * @@ -18,99 +20,123 @@ namespace Symfony\Component\VarDumper\Caster; */ class Caster { - const EXCLUDE_VERBOSE = 1; - const EXCLUDE_VIRTUAL = 2; - const EXCLUDE_DYNAMIC = 4; - const EXCLUDE_PUBLIC = 8; - const EXCLUDE_PROTECTED = 16; - const EXCLUDE_PRIVATE = 32; - const EXCLUDE_NULL = 64; - const EXCLUDE_EMPTY = 128; - const EXCLUDE_NOT_IMPORTANT = 256; - const EXCLUDE_STRICT = 512; + const EXCLUDE_VERBOSE = 1; + const EXCLUDE_VIRTUAL = 2; + const EXCLUDE_DYNAMIC = 4; + const EXCLUDE_PUBLIC = 8; + const EXCLUDE_PROTECTED = 16; + const EXCLUDE_PRIVATE = 32; + const EXCLUDE_NULL = 64; + const EXCLUDE_EMPTY = 128; + const EXCLUDE_NOT_IMPORTANT = 256; + const EXCLUDE_STRICT = 512; - const PREFIX_VIRTUAL = "\0~\0"; - const PREFIX_DYNAMIC = "\0+\0"; - const PREFIX_PROTECTED = "\0*\0"; + const PREFIX_VIRTUAL = "\0~\0"; + const PREFIX_DYNAMIC = "\0+\0"; + const PREFIX_PROTECTED = "\0*\0"; - /** - * Casts objects to arrays and adds the dynamic property prefix. - * - * @param object $obj The object to cast. - * @param \ReflectionClass $reflector The class reflector to use for inspecting the object definition. - * - * @return array The array-cast of the object, with prefixed dynamic properties. - */ - public static function castObject($obj, \ReflectionClass $reflector) - { - if ($reflector->hasMethod('__debugInfo')) { - $a = $obj->__debugInfo(); - } else { - $a = (array) $obj; - } + /** + * Casts objects to arrays and adds the dynamic property prefix. + * + * @param object $obj The object to cast + * @param \ReflectionClass $reflector The class reflector to use for inspecting the object definition + * + * @return array The array-cast of the object, with prefixed dynamic properties + */ + public static function castObject($obj, \ReflectionClass $reflector) + { + if ($reflector->hasMethod('__debugInfo')) { + $a = $obj->__debugInfo(); + } elseif ($obj instanceof \Closure) { + $a = array(); + } else { + $a = (array) $obj; + } + if ($obj instanceof \__PHP_Incomplete_Class) { + return $a; + } - if ($a) { - $p = array_keys($a); - foreach ($p as $i => $k) { - if (!isset($k[0]) || ("\0" !== $k[0] && !$reflector->hasProperty($k))) { - $p[$i] = self::PREFIX_DYNAMIC.$k; - } elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) { - $p[$i] = "\0".$reflector->getParentClass().'@anonymous'.strrchr($k, "\0"); - } - } - $a = array_combine($p, $a); - } + if ($a) { + $combine = false; + $p = array_keys($a); + foreach ($p as $i => $k) { + if (isset($k[0]) ? "\0" !== $k[0] && !$reflector->hasProperty($k) : \PHP_VERSION_ID >= 70200) { + $combine = true; + $p[$i] = self::PREFIX_DYNAMIC.$k; + } elseif (isset($k[16]) && "\0" === $k[16] && 0 === strpos($k, "\0class@anonymous\0")) { + $combine = true; + $p[$i] = "\0".$reflector->getParentClass().'@anonymous'.strrchr($k, "\0"); + } + } + if ($combine) { + $a = array_combine($p, $a); + } + } - return $a; - } + return $a; + } - /** - * Filters out the specified properties. - * - * By default, a single match in the $filter bit field filters properties out, following an "or" logic. - * When EXCLUDE_STRICT is set, an "and" logic is applied: all bits must match for a property to be removed. - * - * @param array $a The array containing the properties to filter. - * @param int $filter A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out. - * @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set. - * - * @return array The filtered array - */ - public static function filter(array $a, $filter, array $listedProperties = array()) - { - foreach ($a as $k => $v) { - $type = self::EXCLUDE_STRICT & $filter; + /** + * Filters out the specified properties. + * + * By default, a single match in the $filter bit field filters properties out, following an "or" logic. + * When EXCLUDE_STRICT is set, an "and" logic is applied: all bits must match for a property to be removed. + * + * @param array $a The array containing the properties to filter + * @param int $filter A bit field of Caster::EXCLUDE_* constants specifying which properties to filter out + * @param string[] $listedProperties List of properties to exclude when Caster::EXCLUDE_VERBOSE is set, and to preserve when Caster::EXCLUDE_NOT_IMPORTANT is set + * @param int &$count Set to the number of removed properties + * + * @return array The filtered array + */ + public static function filter(array $a, $filter, array $listedProperties = array(), &$count = 0) + { + $count = 0; - if (null === $v) { - $type |= self::EXCLUDE_NULL & $filter; - } - if (empty($v)) { - $type |= self::EXCLUDE_EMPTY & $filter; - } - if ((self::EXCLUDE_NOT_IMPORTANT & $filter) && !in_array($k, $listedProperties, true)) { - $type |= self::EXCLUDE_NOT_IMPORTANT; - } - if ((self::EXCLUDE_VERBOSE & $filter) && in_array($k, $listedProperties, true)) { - $type |= self::EXCLUDE_VERBOSE; - } + foreach ($a as $k => $v) { + $type = self::EXCLUDE_STRICT & $filter; - if (!isset($k[1]) || "\0" !== $k[0]) { - $type |= self::EXCLUDE_PUBLIC & $filter; - } elseif ('~' === $k[1]) { - $type |= self::EXCLUDE_VIRTUAL & $filter; - } elseif ('+' === $k[1]) { - $type |= self::EXCLUDE_DYNAMIC & $filter; - } elseif ('*' === $k[1]) { - $type |= self::EXCLUDE_PROTECTED & $filter; - } else { - $type |= self::EXCLUDE_PRIVATE & $filter; - } + if (null === $v) { + $type |= self::EXCLUDE_NULL & $filter; + } + if (empty($v)) { + $type |= self::EXCLUDE_EMPTY & $filter; + } + if ((self::EXCLUDE_NOT_IMPORTANT & $filter) && !in_array($k, $listedProperties, true)) { + $type |= self::EXCLUDE_NOT_IMPORTANT; + } + if ((self::EXCLUDE_VERBOSE & $filter) && in_array($k, $listedProperties, true)) { + $type |= self::EXCLUDE_VERBOSE; + } - if ((self::EXCLUDE_STRICT & $filter) ? $type === $filter : $type) { - unset($a[$k]); - } - } + if (!isset($k[1]) || "\0" !== $k[0]) { + $type |= self::EXCLUDE_PUBLIC & $filter; + } elseif ('~' === $k[1]) { + $type |= self::EXCLUDE_VIRTUAL & $filter; + } elseif ('+' === $k[1]) { + $type |= self::EXCLUDE_DYNAMIC & $filter; + } elseif ('*' === $k[1]) { + $type |= self::EXCLUDE_PROTECTED & $filter; + } else { + $type |= self::EXCLUDE_PRIVATE & $filter; + } - return $a; - } + if ((self::EXCLUDE_STRICT & $filter) ? $type === $filter : $type) { + unset($a[$k]); + ++$count; + } + } + + return $a; + } + + public static function castPhpIncompleteClass(\__PHP_Incomplete_Class $c, array $a, Stub $stub, $isNested) + { + if (isset($a['__PHP_Incomplete_Class_Name'])) { + $stub->class .= '('.$a['__PHP_Incomplete_Class_Name'].')'; + unset($a['__PHP_Incomplete_Class_Name']); + } + + return $a; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/ClassStub.php b/htdocs/includes/symfony/var-dumper/Caster/ClassStub.php new file mode 100644 index 00000000000..6acb22d665c --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Caster/ClassStub.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +/** + * Represents a PHP class identifier. + * + * @author Nicolas Grekas + */ +class ClassStub extends ConstStub +{ + /** + * Constructor. + * + * @param string A PHP identifier, e.g. a class, method, interface, etc. name + * @param callable The callable targeted by the identifier when it is ambiguous or not a real PHP identifier + */ + public function __construct($identifier, $callable = null) + { + $this->value = $identifier; + + if (0 < $i = strrpos($identifier, '\\')) { + $this->attr['ellipsis'] = strlen($identifier) - $i; + } + + try { + if (null !== $callable) { + if ($callable instanceof \Closure) { + $r = new \ReflectionFunction($callable); + } elseif (is_object($callable)) { + $r = array($callable, '__invoke'); + } elseif (is_array($callable)) { + $r = $callable; + } elseif (false !== $i = strpos($callable, '::')) { + $r = array(substr($callable, 0, $i), substr($callable, 2 + $i)); + } else { + $r = new \ReflectionFunction($callable); + } + } elseif (false !== $i = strpos($identifier, '::')) { + $r = array(substr($identifier, 0, $i), substr($identifier, 2 + $i)); + } else { + $r = new \ReflectionClass($identifier); + } + + if (is_array($r)) { + try { + $r = new \ReflectionMethod($r[0], $r[1]); + } catch (\ReflectionException $e) { + $r = new \ReflectionClass($r[0]); + } + } + } catch (\ReflectionException $e) { + return; + } + + if ($f = $r->getFileName()) { + $this->attr['file'] = $f; + $this->attr['line'] = $r->getStartLine(); + } + } + + public static function wrapCallable($callable) + { + if (is_object($callable) || !is_callable($callable)) { + return $callable; + } + + if (!is_array($callable)) { + $callable = new static($callable); + } elseif (is_string($callable[0])) { + $callable[0] = new static($callable[0]); + } else { + $callable[1] = new static($callable[1], $callable); + } + + return $callable; + } +} diff --git a/htdocs/includes/symfony/var-dumper/Caster/ConstStub.php b/htdocs/includes/symfony/var-dumper/Caster/ConstStub.php index f20e03cdf0d..64766c3ba4f 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/ConstStub.php +++ b/htdocs/includes/symfony/var-dumper/Caster/ConstStub.php @@ -20,9 +20,14 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class ConstStub extends Stub { - public function __construct($name, $value) - { - $this->class = $name; - $this->value = $value; - } + public function __construct($name, $value) + { + $this->class = $name; + $this->value = $value; + } + + public function __toString() + { + return (string) $this->value; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/CutStub.php b/htdocs/includes/symfony/var-dumper/Caster/CutStub.php index 8781f5cf3c6..c8f51970abe 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/CutStub.php +++ b/htdocs/includes/symfony/var-dumper/Caster/CutStub.php @@ -20,37 +20,40 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class CutStub extends Stub { - public function __construct($value) - { - $this->value = $value; + public function __construct($value) + { + $this->value = $value; - switch (gettype($value)) { - case 'object': - $this->type = self::TYPE_OBJECT; - $this->class = get_class($value); - $this->cut = -1; - break; + switch (gettype($value)) { + case 'object': + $this->type = self::TYPE_OBJECT; + $this->class = get_class($value); + $this->cut = -1; + break; - case 'array': - $this->type = self::TYPE_ARRAY; - $this->class = self::ARRAY_ASSOC; - $this->cut = $this->value = count($value); - break; + case 'array': + $this->type = self::TYPE_ARRAY; + $this->class = self::ARRAY_ASSOC; + $this->cut = $this->value = count($value); + break; - case 'resource': - case 'unknown type': - $this->type = self::TYPE_RESOURCE; - $this->handle = (int) $value; - $this->class = @get_resource_type($value); - $this->cut = -1; - break; + case 'resource': + case 'unknown type': + case 'resource (closed)': + $this->type = self::TYPE_RESOURCE; + $this->handle = (int) $value; + if ('Unknown' === $this->class = @get_resource_type($value)) { + $this->class = 'Closed'; + } + $this->cut = -1; + break; - case 'string': - $this->type = self::TYPE_STRING; - $this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY; - $this->cut = self::STRING_BINARY === $this->class ? strlen($value) : mb_strlen($value, 'UTF-8'); - $this->value = ''; - break; - } - } + case 'string': + $this->type = self::TYPE_STRING; + $this->class = preg_match('//u', $value) ? self::STRING_UTF8 : self::STRING_BINARY; + $this->cut = self::STRING_BINARY === $this->class ? strlen($value) : mb_strlen($value, 'UTF-8'); + $this->value = ''; + break; + } + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/DOMCaster.php b/htdocs/includes/symfony/var-dumper/Caster/DOMCaster.php index e04cf9534b3..c35c1965b8d 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/DOMCaster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/DOMCaster.php @@ -20,283 +20,283 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class DOMCaster { - private static $errorCodes = array( - DOM_PHP_ERR => 'DOM_PHP_ERR', - DOM_INDEX_SIZE_ERR => 'DOM_INDEX_SIZE_ERR', - DOMSTRING_SIZE_ERR => 'DOMSTRING_SIZE_ERR', - DOM_HIERARCHY_REQUEST_ERR => 'DOM_HIERARCHY_REQUEST_ERR', - DOM_WRONG_DOCUMENT_ERR => 'DOM_WRONG_DOCUMENT_ERR', - DOM_INVALID_CHARACTER_ERR => 'DOM_INVALID_CHARACTER_ERR', - DOM_NO_DATA_ALLOWED_ERR => 'DOM_NO_DATA_ALLOWED_ERR', - DOM_NO_MODIFICATION_ALLOWED_ERR => 'DOM_NO_MODIFICATION_ALLOWED_ERR', - DOM_NOT_FOUND_ERR => 'DOM_NOT_FOUND_ERR', - DOM_NOT_SUPPORTED_ERR => 'DOM_NOT_SUPPORTED_ERR', - DOM_INUSE_ATTRIBUTE_ERR => 'DOM_INUSE_ATTRIBUTE_ERR', - DOM_INVALID_STATE_ERR => 'DOM_INVALID_STATE_ERR', - DOM_SYNTAX_ERR => 'DOM_SYNTAX_ERR', - DOM_INVALID_MODIFICATION_ERR => 'DOM_INVALID_MODIFICATION_ERR', - DOM_NAMESPACE_ERR => 'DOM_NAMESPACE_ERR', - DOM_INVALID_ACCESS_ERR => 'DOM_INVALID_ACCESS_ERR', - DOM_VALIDATION_ERR => 'DOM_VALIDATION_ERR', - ); + private static $errorCodes = array( + DOM_PHP_ERR => 'DOM_PHP_ERR', + DOM_INDEX_SIZE_ERR => 'DOM_INDEX_SIZE_ERR', + DOMSTRING_SIZE_ERR => 'DOMSTRING_SIZE_ERR', + DOM_HIERARCHY_REQUEST_ERR => 'DOM_HIERARCHY_REQUEST_ERR', + DOM_WRONG_DOCUMENT_ERR => 'DOM_WRONG_DOCUMENT_ERR', + DOM_INVALID_CHARACTER_ERR => 'DOM_INVALID_CHARACTER_ERR', + DOM_NO_DATA_ALLOWED_ERR => 'DOM_NO_DATA_ALLOWED_ERR', + DOM_NO_MODIFICATION_ALLOWED_ERR => 'DOM_NO_MODIFICATION_ALLOWED_ERR', + DOM_NOT_FOUND_ERR => 'DOM_NOT_FOUND_ERR', + DOM_NOT_SUPPORTED_ERR => 'DOM_NOT_SUPPORTED_ERR', + DOM_INUSE_ATTRIBUTE_ERR => 'DOM_INUSE_ATTRIBUTE_ERR', + DOM_INVALID_STATE_ERR => 'DOM_INVALID_STATE_ERR', + DOM_SYNTAX_ERR => 'DOM_SYNTAX_ERR', + DOM_INVALID_MODIFICATION_ERR => 'DOM_INVALID_MODIFICATION_ERR', + DOM_NAMESPACE_ERR => 'DOM_NAMESPACE_ERR', + DOM_INVALID_ACCESS_ERR => 'DOM_INVALID_ACCESS_ERR', + DOM_VALIDATION_ERR => 'DOM_VALIDATION_ERR', + ); - private static $nodeTypes = array( - XML_ELEMENT_NODE => 'XML_ELEMENT_NODE', - XML_ATTRIBUTE_NODE => 'XML_ATTRIBUTE_NODE', - XML_TEXT_NODE => 'XML_TEXT_NODE', - XML_CDATA_SECTION_NODE => 'XML_CDATA_SECTION_NODE', - XML_ENTITY_REF_NODE => 'XML_ENTITY_REF_NODE', - XML_ENTITY_NODE => 'XML_ENTITY_NODE', - XML_PI_NODE => 'XML_PI_NODE', - XML_COMMENT_NODE => 'XML_COMMENT_NODE', - XML_DOCUMENT_NODE => 'XML_DOCUMENT_NODE', - XML_DOCUMENT_TYPE_NODE => 'XML_DOCUMENT_TYPE_NODE', - XML_DOCUMENT_FRAG_NODE => 'XML_DOCUMENT_FRAG_NODE', - XML_NOTATION_NODE => 'XML_NOTATION_NODE', - XML_HTML_DOCUMENT_NODE => 'XML_HTML_DOCUMENT_NODE', - XML_DTD_NODE => 'XML_DTD_NODE', - XML_ELEMENT_DECL_NODE => 'XML_ELEMENT_DECL_NODE', - XML_ATTRIBUTE_DECL_NODE => 'XML_ATTRIBUTE_DECL_NODE', - XML_ENTITY_DECL_NODE => 'XML_ENTITY_DECL_NODE', - XML_NAMESPACE_DECL_NODE => 'XML_NAMESPACE_DECL_NODE', - ); + private static $nodeTypes = array( + XML_ELEMENT_NODE => 'XML_ELEMENT_NODE', + XML_ATTRIBUTE_NODE => 'XML_ATTRIBUTE_NODE', + XML_TEXT_NODE => 'XML_TEXT_NODE', + XML_CDATA_SECTION_NODE => 'XML_CDATA_SECTION_NODE', + XML_ENTITY_REF_NODE => 'XML_ENTITY_REF_NODE', + XML_ENTITY_NODE => 'XML_ENTITY_NODE', + XML_PI_NODE => 'XML_PI_NODE', + XML_COMMENT_NODE => 'XML_COMMENT_NODE', + XML_DOCUMENT_NODE => 'XML_DOCUMENT_NODE', + XML_DOCUMENT_TYPE_NODE => 'XML_DOCUMENT_TYPE_NODE', + XML_DOCUMENT_FRAG_NODE => 'XML_DOCUMENT_FRAG_NODE', + XML_NOTATION_NODE => 'XML_NOTATION_NODE', + XML_HTML_DOCUMENT_NODE => 'XML_HTML_DOCUMENT_NODE', + XML_DTD_NODE => 'XML_DTD_NODE', + XML_ELEMENT_DECL_NODE => 'XML_ELEMENT_DECL_NODE', + XML_ATTRIBUTE_DECL_NODE => 'XML_ATTRIBUTE_DECL_NODE', + XML_ENTITY_DECL_NODE => 'XML_ENTITY_DECL_NODE', + XML_NAMESPACE_DECL_NODE => 'XML_NAMESPACE_DECL_NODE', + ); - public static function castException(\DOMException $e, array $a, Stub $stub, $isNested) - { - $k = Caster::PREFIX_PROTECTED.'code'; - if (isset($a[$k], self::$errorCodes[$a[$k]])) { - $a[$k] = new ConstStub(self::$errorCodes[$a[$k]], $a[$k]); - } + public static function castException(\DOMException $e, array $a, Stub $stub, $isNested) + { + $k = Caster::PREFIX_PROTECTED.'code'; + if (isset($a[$k], self::$errorCodes[$a[$k]])) { + $a[$k] = new ConstStub(self::$errorCodes[$a[$k]], $a[$k]); + } - return $a; - } + return $a; + } - public static function castLength($dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'length' => $dom->length, - ); + public static function castLength($dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'length' => $dom->length, + ); - return $a; - } + return $a; + } - public static function castImplementation($dom, array $a, Stub $stub, $isNested) - { - $a += array( - Caster::PREFIX_VIRTUAL.'Core' => '1.0', - Caster::PREFIX_VIRTUAL.'XML' => '2.0', - ); + public static function castImplementation($dom, array $a, Stub $stub, $isNested) + { + $a += array( + Caster::PREFIX_VIRTUAL.'Core' => '1.0', + Caster::PREFIX_VIRTUAL.'XML' => '2.0', + ); - return $a; - } + return $a; + } - public static function castNode(\DOMNode $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'nodeName' => $dom->nodeName, - 'nodeValue' => new CutStub($dom->nodeValue), - 'nodeType' => new ConstStub(self::$nodeTypes[$dom->nodeType], $dom->nodeType), - 'parentNode' => new CutStub($dom->parentNode), - 'childNodes' => $dom->childNodes, - 'firstChild' => new CutStub($dom->firstChild), - 'lastChild' => new CutStub($dom->lastChild), - 'previousSibling' => new CutStub($dom->previousSibling), - 'nextSibling' => new CutStub($dom->nextSibling), - 'attributes' => $dom->attributes, - 'ownerDocument' => new CutStub($dom->ownerDocument), - 'namespaceURI' => $dom->namespaceURI, - 'prefix' => $dom->prefix, - 'localName' => $dom->localName, - 'baseURI' => $dom->baseURI, - 'textContent' => new CutStub($dom->textContent), - ); + public static function castNode(\DOMNode $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'nodeName' => $dom->nodeName, + 'nodeValue' => new CutStub($dom->nodeValue), + 'nodeType' => new ConstStub(self::$nodeTypes[$dom->nodeType], $dom->nodeType), + 'parentNode' => new CutStub($dom->parentNode), + 'childNodes' => $dom->childNodes, + 'firstChild' => new CutStub($dom->firstChild), + 'lastChild' => new CutStub($dom->lastChild), + 'previousSibling' => new CutStub($dom->previousSibling), + 'nextSibling' => new CutStub($dom->nextSibling), + 'attributes' => $dom->attributes, + 'ownerDocument' => new CutStub($dom->ownerDocument), + 'namespaceURI' => $dom->namespaceURI, + 'prefix' => $dom->prefix, + 'localName' => $dom->localName, + 'baseURI' => $dom->baseURI ? new LinkStub($dom->baseURI) : $dom->baseURI, + 'textContent' => new CutStub($dom->textContent), + ); - return $a; - } + return $a; + } - public static function castNameSpaceNode(\DOMNameSpaceNode $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'nodeName' => $dom->nodeName, - 'nodeValue' => new CutStub($dom->nodeValue), - 'nodeType' => new ConstStub(self::$nodeTypes[$dom->nodeType], $dom->nodeType), - 'prefix' => $dom->prefix, - 'localName' => $dom->localName, - 'namespaceURI' => $dom->namespaceURI, - 'ownerDocument' => new CutStub($dom->ownerDocument), - 'parentNode' => new CutStub($dom->parentNode), - ); + public static function castNameSpaceNode(\DOMNameSpaceNode $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'nodeName' => $dom->nodeName, + 'nodeValue' => new CutStub($dom->nodeValue), + 'nodeType' => new ConstStub(self::$nodeTypes[$dom->nodeType], $dom->nodeType), + 'prefix' => $dom->prefix, + 'localName' => $dom->localName, + 'namespaceURI' => $dom->namespaceURI, + 'ownerDocument' => new CutStub($dom->ownerDocument), + 'parentNode' => new CutStub($dom->parentNode), + ); - return $a; - } + return $a; + } - public static function castDocument(\DOMDocument $dom, array $a, Stub $stub, $isNested, $filter = 0) - { - $a += array( - 'doctype' => $dom->doctype, - 'implementation' => $dom->implementation, - 'documentElement' => new CutStub($dom->documentElement), - 'actualEncoding' => $dom->actualEncoding, - 'encoding' => $dom->encoding, - 'xmlEncoding' => $dom->xmlEncoding, - 'standalone' => $dom->standalone, - 'xmlStandalone' => $dom->xmlStandalone, - 'version' => $dom->version, - 'xmlVersion' => $dom->xmlVersion, - 'strictErrorChecking' => $dom->strictErrorChecking, - 'documentURI' => $dom->documentURI, - 'config' => $dom->config, - 'formatOutput' => $dom->formatOutput, - 'validateOnParse' => $dom->validateOnParse, - 'resolveExternals' => $dom->resolveExternals, - 'preserveWhiteSpace' => $dom->preserveWhiteSpace, - 'recover' => $dom->recover, - 'substituteEntities' => $dom->substituteEntities, - ); + public static function castDocument(\DOMDocument $dom, array $a, Stub $stub, $isNested, $filter = 0) + { + $a += array( + 'doctype' => $dom->doctype, + 'implementation' => $dom->implementation, + 'documentElement' => new CutStub($dom->documentElement), + 'actualEncoding' => $dom->actualEncoding, + 'encoding' => $dom->encoding, + 'xmlEncoding' => $dom->xmlEncoding, + 'standalone' => $dom->standalone, + 'xmlStandalone' => $dom->xmlStandalone, + 'version' => $dom->version, + 'xmlVersion' => $dom->xmlVersion, + 'strictErrorChecking' => $dom->strictErrorChecking, + 'documentURI' => $dom->documentURI ? new LinkStub($dom->documentURI) : $dom->documentURI, + 'config' => $dom->config, + 'formatOutput' => $dom->formatOutput, + 'validateOnParse' => $dom->validateOnParse, + 'resolveExternals' => $dom->resolveExternals, + 'preserveWhiteSpace' => $dom->preserveWhiteSpace, + 'recover' => $dom->recover, + 'substituteEntities' => $dom->substituteEntities, + ); - if (!($filter & Caster::EXCLUDE_VERBOSE)) { - $formatOutput = $dom->formatOutput; - $dom->formatOutput = true; - $a += array(Caster::PREFIX_VIRTUAL.'xml' => $dom->saveXML()); - $dom->formatOutput = $formatOutput; - } + if (!($filter & Caster::EXCLUDE_VERBOSE)) { + $formatOutput = $dom->formatOutput; + $dom->formatOutput = true; + $a += array(Caster::PREFIX_VIRTUAL.'xml' => $dom->saveXML()); + $dom->formatOutput = $formatOutput; + } - return $a; - } + return $a; + } - public static function castCharacterData(\DOMCharacterData $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'data' => $dom->data, - 'length' => $dom->length, - ); + public static function castCharacterData(\DOMCharacterData $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'data' => $dom->data, + 'length' => $dom->length, + ); - return $a; - } + return $a; + } - public static function castAttr(\DOMAttr $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'name' => $dom->name, - 'specified' => $dom->specified, - 'value' => $dom->value, - 'ownerElement' => $dom->ownerElement, - 'schemaTypeInfo' => $dom->schemaTypeInfo, - ); + public static function castAttr(\DOMAttr $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'name' => $dom->name, + 'specified' => $dom->specified, + 'value' => $dom->value, + 'ownerElement' => $dom->ownerElement, + 'schemaTypeInfo' => $dom->schemaTypeInfo, + ); - return $a; - } + return $a; + } - public static function castElement(\DOMElement $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'tagName' => $dom->tagName, - 'schemaTypeInfo' => $dom->schemaTypeInfo, - ); + public static function castElement(\DOMElement $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'tagName' => $dom->tagName, + 'schemaTypeInfo' => $dom->schemaTypeInfo, + ); - return $a; - } + return $a; + } - public static function castText(\DOMText $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'wholeText' => $dom->wholeText, - ); + public static function castText(\DOMText $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'wholeText' => $dom->wholeText, + ); - return $a; - } + return $a; + } - public static function castTypeinfo(\DOMTypeinfo $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'typeName' => $dom->typeName, - 'typeNamespace' => $dom->typeNamespace, - ); + public static function castTypeinfo(\DOMTypeinfo $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'typeName' => $dom->typeName, + 'typeNamespace' => $dom->typeNamespace, + ); - return $a; - } + return $a; + } - public static function castDomError(\DOMDomError $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'severity' => $dom->severity, - 'message' => $dom->message, - 'type' => $dom->type, - 'relatedException' => $dom->relatedException, - 'related_data' => $dom->related_data, - 'location' => $dom->location, - ); + public static function castDomError(\DOMDomError $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'severity' => $dom->severity, + 'message' => $dom->message, + 'type' => $dom->type, + 'relatedException' => $dom->relatedException, + 'related_data' => $dom->related_data, + 'location' => $dom->location, + ); - return $a; - } + return $a; + } - public static function castLocator(\DOMLocator $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'lineNumber' => $dom->lineNumber, - 'columnNumber' => $dom->columnNumber, - 'offset' => $dom->offset, - 'relatedNode' => $dom->relatedNode, - 'uri' => $dom->uri, - ); + public static function castLocator(\DOMLocator $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'lineNumber' => $dom->lineNumber, + 'columnNumber' => $dom->columnNumber, + 'offset' => $dom->offset, + 'relatedNode' => $dom->relatedNode, + 'uri' => $dom->uri ? new LinkStub($dom->uri, $dom->lineNumber) : $dom->uri, + ); - return $a; - } + return $a; + } - public static function castDocumentType(\DOMDocumentType $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'name' => $dom->name, - 'entities' => $dom->entities, - 'notations' => $dom->notations, - 'publicId' => $dom->publicId, - 'systemId' => $dom->systemId, - 'internalSubset' => $dom->internalSubset, - ); + public static function castDocumentType(\DOMDocumentType $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'name' => $dom->name, + 'entities' => $dom->entities, + 'notations' => $dom->notations, + 'publicId' => $dom->publicId, + 'systemId' => $dom->systemId, + 'internalSubset' => $dom->internalSubset, + ); - return $a; - } + return $a; + } - public static function castNotation(\DOMNotation $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'publicId' => $dom->publicId, - 'systemId' => $dom->systemId, - ); + public static function castNotation(\DOMNotation $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'publicId' => $dom->publicId, + 'systemId' => $dom->systemId, + ); - return $a; - } + return $a; + } - public static function castEntity(\DOMEntity $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'publicId' => $dom->publicId, - 'systemId' => $dom->systemId, - 'notationName' => $dom->notationName, - 'actualEncoding' => $dom->actualEncoding, - 'encoding' => $dom->encoding, - 'version' => $dom->version, - ); + public static function castEntity(\DOMEntity $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'publicId' => $dom->publicId, + 'systemId' => $dom->systemId, + 'notationName' => $dom->notationName, + 'actualEncoding' => $dom->actualEncoding, + 'encoding' => $dom->encoding, + 'version' => $dom->version, + ); - return $a; - } + return $a; + } - public static function castProcessingInstruction(\DOMProcessingInstruction $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'target' => $dom->target, - 'data' => $dom->data, - ); + public static function castProcessingInstruction(\DOMProcessingInstruction $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'target' => $dom->target, + 'data' => $dom->data, + ); - return $a; - } + return $a; + } - public static function castXPath(\DOMXPath $dom, array $a, Stub $stub, $isNested) - { - $a += array( - 'document' => $dom->document, - ); + public static function castXPath(\DOMXPath $dom, array $a, Stub $stub, $isNested) + { + $a += array( + 'document' => $dom->document, + ); - return $a; - } + return $a; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/EnumStub.php b/htdocs/includes/symfony/var-dumper/Caster/EnumStub.php index 67bb2e16390..66d8bc219de 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/EnumStub.php +++ b/htdocs/includes/symfony/var-dumper/Caster/EnumStub.php @@ -20,8 +20,11 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class EnumStub extends Stub { - public function __construct(array $values) - { - $this->value = $values; - } + public $dumpKeys = true; + + public function __construct(array $values, $dumpKeys = true) + { + $this->value = $values; + $this->dumpKeys = $dumpKeys; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/ExceptionCaster.php b/htdocs/includes/symfony/var-dumper/Caster/ExceptionCaster.php index a5a8773e859..daf7cebe83f 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/ExceptionCaster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/ExceptionCaster.php @@ -21,218 +21,278 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class ExceptionCaster { - public static $srcContext = 1; - public static $traceArgs = true; - public static $errorTypes = array( - E_DEPRECATED => 'E_DEPRECATED', - E_USER_DEPRECATED => 'E_USER_DEPRECATED', - E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', - E_ERROR => 'E_ERROR', - E_WARNING => 'E_WARNING', - E_PARSE => 'E_PARSE', - E_NOTICE => 'E_NOTICE', - E_CORE_ERROR => 'E_CORE_ERROR', - E_CORE_WARNING => 'E_CORE_WARNING', - E_COMPILE_ERROR => 'E_COMPILE_ERROR', - E_COMPILE_WARNING => 'E_COMPILE_WARNING', - E_USER_ERROR => 'E_USER_ERROR', - E_USER_WARNING => 'E_USER_WARNING', - E_USER_NOTICE => 'E_USER_NOTICE', - E_STRICT => 'E_STRICT', - ); + public static $srcContext = 1; + public static $traceArgs = true; + public static $errorTypes = array( + E_DEPRECATED => 'E_DEPRECATED', + E_USER_DEPRECATED => 'E_USER_DEPRECATED', + E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', + E_ERROR => 'E_ERROR', + E_WARNING => 'E_WARNING', + E_PARSE => 'E_PARSE', + E_NOTICE => 'E_NOTICE', + E_CORE_ERROR => 'E_CORE_ERROR', + E_CORE_WARNING => 'E_CORE_WARNING', + E_COMPILE_ERROR => 'E_COMPILE_ERROR', + E_COMPILE_WARNING => 'E_COMPILE_WARNING', + E_USER_ERROR => 'E_USER_ERROR', + E_USER_WARNING => 'E_USER_WARNING', + E_USER_NOTICE => 'E_USER_NOTICE', + E_STRICT => 'E_STRICT', + ); - public static function castError(\Error $e, array $a, Stub $stub, $isNested, $filter = 0) - { - return self::filterExceptionArray($stub->class, $a, "\0Error\0", $filter); - } + private static $framesCache = array(); - public static function castException(\Exception $e, array $a, Stub $stub, $isNested, $filter = 0) - { - return self::filterExceptionArray($stub->class, $a, "\0Exception\0", $filter); - } + public static function castError(\Error $e, array $a, Stub $stub, $isNested, $filter = 0) + { + return self::filterExceptionArray($stub->class, $a, "\0Error\0", $filter); + } - public static function castErrorException(\ErrorException $e, array $a, Stub $stub, $isNested) - { - if (isset($a[$s = Caster::PREFIX_PROTECTED.'severity'], self::$errorTypes[$a[$s]])) { - $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]); - } + public static function castException(\Exception $e, array $a, Stub $stub, $isNested, $filter = 0) + { + return self::filterExceptionArray($stub->class, $a, "\0Exception\0", $filter); + } - return $a; - } + public static function castErrorException(\ErrorException $e, array $a, Stub $stub, $isNested) + { + if (isset($a[$s = Caster::PREFIX_PROTECTED.'severity'], self::$errorTypes[$a[$s]])) { + $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]); + } - public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_PROTECTED; - $xPrefix = "\0Exception\0"; + return $a; + } - if (isset($a[$xPrefix.'previous'], $a[$xPrefix.'trace'])) { - $b = (array) $a[$xPrefix.'previous']; - array_unshift($b[$xPrefix.'trace'], array( - 'function' => 'new '.get_class($a[$xPrefix.'previous']), - 'file' => $b[$prefix.'file'], - 'line' => $b[$prefix.'line'], - )); - $a[$xPrefix.'trace'] = new TraceStub($b[$xPrefix.'trace'], false, 0, -1 - count($a[$xPrefix.'trace']->value)); - } + public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_PROTECTED; + $xPrefix = "\0Exception\0"; - unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']); + if (isset($a[$xPrefix.'previous'], $a[$xPrefix.'trace']) && $a[$xPrefix.'previous'] instanceof \Exception) { + $b = (array) $a[$xPrefix.'previous']; + self::traceUnshift($b[$xPrefix.'trace'], get_class($a[$xPrefix.'previous']), $b[$prefix.'file'], $b[$prefix.'line']); + $a[$xPrefix.'trace'] = new TraceStub($b[$xPrefix.'trace'], false, 0, -1 - count($a[$xPrefix.'trace']->value)); + } - return $a; - } + unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']); - public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $isNested) - { - if (!$isNested) { - return $a; - } - $stub->class = ''; - $stub->handle = 0; - $frames = $trace->value; + return $a; + } - $a = array(); - $j = count($frames); - if (0 > $i = $trace->sliceOffset) { - $i = max(0, $j + $i); - } - if (!isset($trace->value[$i])) { - return array(); - } - $lastCall = isset($frames[$i]['function']) ? ' ==> '.(isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : ''; + public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $isNested) + { + if (!$isNested) { + return $a; + } + $stub->class = ''; + $stub->handle = 0; + $frames = $trace->value; + $prefix = Caster::PREFIX_VIRTUAL; - for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) { - $call = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[$i]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '???'; + $a = array(); + $j = count($frames); + if (0 > $i = $trace->sliceOffset) { + $i = max(0, $j + $i); + } + if (!isset($trace->value[$i])) { + return array(); + } + $lastCall = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : ''; + $frames[] = array('function' => ''); - $a[Caster::PREFIX_VIRTUAL.$j.'. '.$call.$lastCall] = new FrameStub( - array( - 'object' => isset($frames[$i]['object']) ? $frames[$i]['object'] : null, - 'class' => isset($frames[$i]['class']) ? $frames[$i]['class'] : null, - 'type' => isset($frames[$i]['type']) ? $frames[$i]['type'] : null, - 'function' => isset($frames[$i]['function']) ? $frames[$i]['function'] : null, - ) + $frames[$i - 1], - $trace->keepArgs, - true - ); + for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) { + $f = $frames[$i]; + $call = isset($f['function']) ? (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'].'()' : '???'; - $lastCall = ' ==> '.$call; - } - $a[Caster::PREFIX_VIRTUAL.$j.'. {main}'.$lastCall] = new FrameStub( - array( - 'object' => null, - 'class' => null, - 'type' => null, - 'function' => '{main}', - ) + $frames[$i - 1], - $trace->keepArgs, - true - ); - if (null !== $trace->sliceLength) { - $a = array_slice($a, 0, $trace->sliceLength, true); - } + $label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$lastCall; + $frame = new FrameStub( + array( + 'object' => isset($f['object']) ? $f['object'] : null, + 'class' => isset($f['class']) ? $f['class'] : null, + 'type' => isset($f['type']) ? $f['type'] : null, + 'function' => isset($f['function']) ? $f['function'] : null, + ) + $frames[$i - 1], + false, + true + ); + $f = self::castFrameStub($frame, array(), $frame, true); + if (isset($f[$prefix.'src'])) { + foreach ($f[$prefix.'src']->value as $label => $frame) { + $label = substr_replace($label, "title=Stack level $j.&", 2, 0); + } + $f = $frames[$i - 1]; + if ($trace->keepArgs && !empty($f['args']) && $frame instanceof EnumStub) { + $frame->value['arguments'] = new ArgsStub($f['args'], isset($f['function']) ? $f['function'] : null, isset($f['class']) ? $f['class'] : null); + } + } + $a[$label] = $frame; - return $a; - } + $lastCall = $call; + } + if (null !== $trace->sliceLength) { + $a = array_slice($a, 0, $trace->sliceLength, true); + } - public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $isNested) - { - if (!$isNested) { - return $a; - } - $f = $frame->value; - $prefix = Caster::PREFIX_VIRTUAL; + return $a; + } - if (isset($f['file'], $f['line'])) { - if (preg_match('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\)\'d code|runtime-created function)$/', $f['file'], $match)) { - $f['file'] = substr($f['file'], 0, -strlen($match[0])); - $f['line'] = (int) $match[1]; - } - if (file_exists($f['file']) && 0 <= self::$srcContext) { - $src[$f['file'].':'.$f['line']] = self::extractSource(explode("\n", file_get_contents($f['file'])), $f['line'], self::$srcContext); + public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $isNested) + { + if (!$isNested) { + return $a; + } + $f = $frame->value; + $prefix = Caster::PREFIX_VIRTUAL; - if (!empty($f['class']) && is_subclass_of($f['class'], 'Twig_Template') && method_exists($f['class'], 'getDebugInfo')) { - $template = isset($f['object']) ? $f['object'] : new $f['class'](new \Twig_Environment(new \Twig_Loader_Filesystem())); + if (isset($f['file'], $f['line'])) { + $cacheKey = $f; + unset($cacheKey['object'], $cacheKey['args']); + $cacheKey[] = self::$srcContext; + $cacheKey = implode('-', $cacheKey); - try { - $templateName = $template->getTemplateName(); - $templateSrc = explode("\n", method_exists($template, 'getSource') ? $template->getSource() : $template->getEnvironment()->getLoader()->getSource($templateName)); - $templateInfo = $template->getDebugInfo(); - if (isset($templateInfo[$f['line']])) { - $src[$templateName.':'.$templateInfo[$f['line']]] = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext); - } - } catch (\Twig_Error_Loader $e) { - } - } - } else { - $src[$f['file']] = $f['line']; - } - $a[$prefix.'src'] = new EnumStub($src); - } + if (isset(self::$framesCache[$cacheKey])) { + $a[$prefix.'src'] = self::$framesCache[$cacheKey]; + } else { + if (preg_match('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\)\'d code|runtime-created function)$/', $f['file'], $match)) { + $f['file'] = substr($f['file'], 0, -strlen($match[0])); + $f['line'] = (int) $match[1]; + } + $caller = isset($f['function']) ? sprintf('in %s() on line %d', (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'], $f['line']) : null; + $src = $f['line']; + $srcKey = $f['file']; + $ellipsis = explode(DIRECTORY_SEPARATOR, $srcKey); + $ellipsis = 3 < count($ellipsis) ? 2 + strlen(implode(array_slice($ellipsis, -2))) : 0; - unset($a[$prefix.'args'], $a[$prefix.'line'], $a[$prefix.'file']); - if ($frame->inTraceStub) { - unset($a[$prefix.'class'], $a[$prefix.'type'], $a[$prefix.'function']); - } - foreach ($a as $k => $v) { - if (!$v) { - unset($a[$k]); - } - } - if ($frame->keepArgs && isset($f['args'])) { - $a[$prefix.'args'] = $f['args']; - } + if (file_exists($f['file']) && 0 <= self::$srcContext) { + if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) { + $template = isset($f['object']) ? $f['object'] : unserialize(sprintf('O:%d:"%s":0:{}', strlen($f['class']), $f['class'])); - return $a; - } + $ellipsis = 0; + $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : ''); + $templateInfo = $template->getDebugInfo(); + if (isset($templateInfo[$f['line']])) { + if (!method_exists($template, 'getSourceContext') || !file_exists($templatePath = $template->getSourceContext()->getPath())) { + $templatePath = null; + } + if ($templateSrc) { + $src = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext, $caller, 'twig', $templatePath); + $srcKey = ($templatePath ?: $template->getTemplateName()).':'.$templateInfo[$f['line']]; + } + } + } + if ($srcKey == $f['file']) { + $src = self::extractSource(file_get_contents($f['file']), $f['line'], self::$srcContext, $caller, 'php', $f['file']); + $srcKey .= ':'.$f['line']; + if ($ellipsis) { + $ellipsis += 1 + strlen($f['line']); + } + } + } + $srcAttr = $ellipsis ? 'ellipsis='.$ellipsis : ''; + self::$framesCache[$cacheKey] = $a[$prefix.'src'] = new EnumStub(array("\0~$srcAttr\0$srcKey" => $src)); + } + } - private static function filterExceptionArray($xClass, array $a, $xPrefix, $filter) - { - if (isset($a[$xPrefix.'trace'])) { - $trace = $a[$xPrefix.'trace']; - unset($a[$xPrefix.'trace']); // Ensures the trace is always last - } else { - $trace = array(); - } + unset($a[$prefix.'args'], $a[$prefix.'line'], $a[$prefix.'file']); + if ($frame->inTraceStub) { + unset($a[$prefix.'class'], $a[$prefix.'type'], $a[$prefix.'function']); + } + foreach ($a as $k => $v) { + if (!$v) { + unset($a[$k]); + } + } + if ($frame->keepArgs && !empty($f['args'])) { + $a[$prefix.'arguments'] = new ArgsStub($f['args'], $f['function'], $f['class']); + } - if (!($filter & Caster::EXCLUDE_VERBOSE)) { - array_unshift($trace, array( - 'function' => $xClass ? 'new '.$xClass : null, - 'file' => $a[Caster::PREFIX_PROTECTED.'file'], - 'line' => $a[Caster::PREFIX_PROTECTED.'line'], - )); - $a[$xPrefix.'trace'] = new TraceStub($trace); - } - if (empty($a[$xPrefix.'previous'])) { - unset($a[$xPrefix.'previous']); - } - unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message'], $a[Caster::PREFIX_DYNAMIC.'__destructorException']); + return $a; + } - return $a; - } + private static function filterExceptionArray($xClass, array $a, $xPrefix, $filter) + { + if (isset($a[$xPrefix.'trace'])) { + $trace = $a[$xPrefix.'trace']; + unset($a[$xPrefix.'trace']); // Ensures the trace is always last + } else { + $trace = array(); + } - private static function extractSource(array $srcArray, $line, $srcContext) - { - $src = array(); + if (!($filter & Caster::EXCLUDE_VERBOSE)) { + if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) { + self::traceUnshift($trace, $xClass, $a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']); + } + $a[$xPrefix.'trace'] = new TraceStub($trace, self::$traceArgs); + } + if (empty($a[$xPrefix.'previous'])) { + unset($a[$xPrefix.'previous']); + } + unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message'], $a[Caster::PREFIX_DYNAMIC.'__destructorException']); - for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) { - $src[] = (isset($srcArray[$i]) ? $srcArray[$i] : '')."\n"; - } + if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) { + $a[Caster::PREFIX_PROTECTED.'file'] = new LinkStub($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']); + } - $ltrim = 0; - while (' ' === $src[0][$ltrim] || "\t" === $src[0][$ltrim]) { - $i = $srcContext << 1; - while ($i > 0 && $src[0][$ltrim] === $src[$i][$ltrim]) { - --$i; - } - if ($i) { - break; - } - ++$ltrim; - } - if ($ltrim) { - foreach ($src as $i => $line) { - $src[$i] = substr($line, $ltrim); - } - } + return $a; + } - return implode('', $src); - } + private static function traceUnshift(&$trace, $class, $file, $line) + { + if (isset($trace[0]['file'], $trace[0]['line']) && $trace[0]['file'] === $file && $trace[0]['line'] === $line) { + return; + } + array_unshift($trace, array( + 'function' => $class ? 'new '.$class : null, + 'file' => $file, + 'line' => $line, + )); + } + + private static function extractSource($srcLines, $line, $srcContext, $title, $lang, $file = null) + { + $srcLines = explode("\n", $srcLines); + $src = array(); + + for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) { + $src[] = (isset($srcLines[$i]) ? $srcLines[$i] : '')."\n"; + } + + $srcLines = array(); + $ltrim = 0; + do { + $pad = null; + for ($i = $srcContext << 1; $i >= 0; --$i) { + if (isset($src[$i][$ltrim]) && "\r" !== ($c = $src[$i][$ltrim]) && "\n" !== $c) { + if (null === $pad) { + $pad = $c; + } + if ((' ' !== $c && "\t" !== $c) || $pad !== $c) { + break; + } + } + } + ++$ltrim; + } while (0 > $i && null !== $pad); + + --$ltrim; + + foreach ($src as $i => $c) { + if ($ltrim) { + $c = isset($c[$ltrim]) && "\r" !== $c[$ltrim] ? substr($c, $ltrim) : ltrim($c, " \t"); + } + $c = substr($c, 0, -1); + if ($i !== $srcContext) { + $c = new ConstStub('default', $c); + } else { + $c = new ConstStub($c, $title); + if (null !== $file) { + $c->attr['file'] = $file; + $c->attr['line'] = $line; + } + } + $c->attr['lang'] = $lang; + $srcLines[sprintf("\0~%d\0", $i + $line - $srcContext)] = $c; + } + + return new EnumStub($srcLines); + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/LinkStub.php b/htdocs/includes/symfony/var-dumper/Caster/LinkStub.php new file mode 100644 index 00000000000..d275379c2a9 --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Caster/LinkStub.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +/** + * Represents a file or a URL. + * + * @author Nicolas Grekas + */ +class LinkStub extends ConstStub +{ + public function __construct($label, $line = 0, $href = null) + { + $this->value = $label; + + if (null === $href) { + $href = $label; + } + if (is_string($href)) { + if (0 === strpos($href, 'file://')) { + if ($href === $label) { + $label = substr($label, 7); + } + $href = substr($href, 7); + } elseif (false !== strpos($href, '://')) { + $this->attr['href'] = $href; + + return; + } + if (file_exists($href)) { + if ($line) { + $this->attr['line'] = $line; + } + $this->attr['file'] = realpath($href) ?: $href; + + if ($this->attr['file'] === $label && 3 < count($ellipsis = explode(DIRECTORY_SEPARATOR, $href))) { + $this->attr['ellipsis'] = 2 + strlen(implode(array_slice($ellipsis, -2))); + } + } + } + } +} diff --git a/htdocs/includes/symfony/var-dumper/Caster/PdoCaster.php b/htdocs/includes/symfony/var-dumper/Caster/PdoCaster.php index e60b9275fd8..782101a90a7 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/PdoCaster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/PdoCaster.php @@ -20,95 +20,101 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class PdoCaster { - private static $pdoAttributes = array( - 'CASE' => array( - \PDO::CASE_LOWER => 'LOWER', - \PDO::CASE_NATURAL => 'NATURAL', - \PDO::CASE_UPPER => 'UPPER', - ), - 'ERRMODE' => array( - \PDO::ERRMODE_SILENT => 'SILENT', - \PDO::ERRMODE_WARNING => 'WARNING', - \PDO::ERRMODE_EXCEPTION => 'EXCEPTION', - ), - 'TIMEOUT', - 'PREFETCH', - 'AUTOCOMMIT', - 'PERSISTENT', - 'DRIVER_NAME', - 'SERVER_INFO', - 'ORACLE_NULLS' => array( - \PDO::NULL_NATURAL => 'NATURAL', - \PDO::NULL_EMPTY_STRING => 'EMPTY_STRING', - \PDO::NULL_TO_STRING => 'TO_STRING', - ), - 'CLIENT_VERSION', - 'SERVER_VERSION', - 'STATEMENT_CLASS', - 'EMULATE_PREPARES', - 'CONNECTION_STATUS', - 'STRINGIFY_FETCHES', - 'DEFAULT_FETCH_MODE' => array( - \PDO::FETCH_ASSOC => 'ASSOC', - \PDO::FETCH_BOTH => 'BOTH', - \PDO::FETCH_LAZY => 'LAZY', - \PDO::FETCH_NUM => 'NUM', - \PDO::FETCH_OBJ => 'OBJ', - ), - ); + private static $pdoAttributes = array( + 'CASE' => array( + \PDO::CASE_LOWER => 'LOWER', + \PDO::CASE_NATURAL => 'NATURAL', + \PDO::CASE_UPPER => 'UPPER', + ), + 'ERRMODE' => array( + \PDO::ERRMODE_SILENT => 'SILENT', + \PDO::ERRMODE_WARNING => 'WARNING', + \PDO::ERRMODE_EXCEPTION => 'EXCEPTION', + ), + 'TIMEOUT', + 'PREFETCH', + 'AUTOCOMMIT', + 'PERSISTENT', + 'DRIVER_NAME', + 'SERVER_INFO', + 'ORACLE_NULLS' => array( + \PDO::NULL_NATURAL => 'NATURAL', + \PDO::NULL_EMPTY_STRING => 'EMPTY_STRING', + \PDO::NULL_TO_STRING => 'TO_STRING', + ), + 'CLIENT_VERSION', + 'SERVER_VERSION', + 'STATEMENT_CLASS', + 'EMULATE_PREPARES', + 'CONNECTION_STATUS', + 'STRINGIFY_FETCHES', + 'DEFAULT_FETCH_MODE' => array( + \PDO::FETCH_ASSOC => 'ASSOC', + \PDO::FETCH_BOTH => 'BOTH', + \PDO::FETCH_LAZY => 'LAZY', + \PDO::FETCH_NUM => 'NUM', + \PDO::FETCH_OBJ => 'OBJ', + ), + ); - public static function castPdo(\PDO $c, array $a, Stub $stub, $isNested) - { - $attr = array(); - $errmode = $c->getAttribute(\PDO::ATTR_ERRMODE); - $c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + public static function castPdo(\PDO $c, array $a, Stub $stub, $isNested) + { + $attr = array(); + $errmode = $c->getAttribute(\PDO::ATTR_ERRMODE); + $c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - foreach (self::$pdoAttributes as $k => $v) { - if (!isset($k[0])) { - $k = $v; - $v = array(); - } + foreach (self::$pdoAttributes as $k => $v) { + if (!isset($k[0])) { + $k = $v; + $v = array(); + } - try { - $attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(constant('PDO::ATTR_'.$k)); - if ($v && isset($v[$attr[$k]])) { - $attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]); - } - } catch (\Exception $e) { - } - } + try { + $attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(constant('PDO::ATTR_'.$k)); + if ($v && isset($v[$attr[$k]])) { + $attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]); + } + } catch (\Exception $e) { + } + } + if (isset($attr[$k = 'STATEMENT_CLASS'][1])) { + if ($attr[$k][1]) { + $attr[$k][1] = new ArgsStub($attr[$k][1], '__construct', $attr[$k][0]); + } + $attr[$k][0] = new ClassStub($attr[$k][0]); + } - $prefix = Caster::PREFIX_VIRTUAL; - $a += array( - $prefix.'inTransaction' => method_exists($c, 'inTransaction'), - $prefix.'errorInfo' => $c->errorInfo(), - $prefix.'attributes' => new EnumStub($attr), - ); + $prefix = Caster::PREFIX_VIRTUAL; + $a += array( + $prefix.'inTransaction' => method_exists($c, 'inTransaction'), + $prefix.'errorInfo' => $c->errorInfo(), + $prefix.'attributes' => new EnumStub($attr), + ); - if ($a[$prefix.'inTransaction']) { - $a[$prefix.'inTransaction'] = $c->inTransaction(); - } else { - unset($a[$prefix.'inTransaction']); - } + if ($a[$prefix.'inTransaction']) { + $a[$prefix.'inTransaction'] = $c->inTransaction(); + } else { + unset($a[$prefix.'inTransaction']); + } - if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) { - unset($a[$prefix.'errorInfo']); - } + if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) { + unset($a[$prefix.'errorInfo']); + } - $c->setAttribute(\PDO::ATTR_ERRMODE, $errmode); + $c->setAttribute(\PDO::ATTR_ERRMODE, $errmode); - return $a; - } + return $a; + } - public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - $a[$prefix.'errorInfo'] = $c->errorInfo(); + public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + $a[$prefix.'errorInfo'] = $c->errorInfo(); - if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) { - unset($a[$prefix.'errorInfo']); - } + if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) { + unset($a[$prefix.'errorInfo']); + } - return $a; - } + return $a; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/RedisCaster.php b/htdocs/includes/symfony/var-dumper/Caster/RedisCaster.php new file mode 100644 index 00000000000..b0e567fcf96 --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Caster/RedisCaster.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts Redis class from ext-redis to array representation. + * + * @author Nicolas Grekas + */ +class RedisCaster +{ + private static $serializer = array( + \Redis::SERIALIZER_NONE => 'NONE', + \Redis::SERIALIZER_PHP => 'PHP', + 2 => 'IGBINARY', // Optional Redis::SERIALIZER_IGBINARY + ); + + public static function castRedis(\Redis $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + if (defined('HHVM_VERSION_ID')) { + if (isset($a[Caster::PREFIX_PROTECTED.'serializer'])) { + $ser = $a[Caster::PREFIX_PROTECTED.'serializer']; + $a[Caster::PREFIX_PROTECTED.'serializer'] = isset(self::$serializer[$ser]) ? new ConstStub(self::$serializer[$ser], $ser) : $ser; + } + + return $a; + } + + if (!$connected = $c->isConnected()) { + return $a + array( + $prefix.'isConnected' => $connected, + ); + } + + $ser = $c->getOption(\Redis::OPT_SERIALIZER); + $retry = defined('Redis::OPT_SCAN') ? $c->getOption(\Redis::OPT_SCAN) : 0; + + return $a + array( + $prefix.'isConnected' => $connected, + $prefix.'host' => $c->getHost(), + $prefix.'port' => $c->getPort(), + $prefix.'auth' => $c->getAuth(), + $prefix.'dbNum' => $c->getDbNum(), + $prefix.'timeout' => $c->getTimeout(), + $prefix.'persistentId' => $c->getPersistentID(), + $prefix.'options' => new EnumStub(array( + 'READ_TIMEOUT' => $c->getOption(\Redis::OPT_READ_TIMEOUT), + 'SERIALIZER' => isset(self::$serializer[$ser]) ? new ConstStub(self::$serializer[$ser], $ser) : $ser, + 'PREFIX' => $c->getOption(\Redis::OPT_PREFIX), + 'SCAN' => new ConstStub($retry ? 'RETRY' : 'NORETRY', $retry), + )), + ); + } + + public static function castRedisArray(\RedisArray $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + + return $a + array( + $prefix.'hosts' => $c->_hosts(), + $prefix.'function' => ClassStub::wrapCallable($c->_function()), + ); + } +} diff --git a/htdocs/includes/symfony/var-dumper/Caster/ReflectionCaster.php b/htdocs/includes/symfony/var-dumper/Caster/ReflectionCaster.php index 936e11982ee..6a53bd2b61b 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/ReflectionCaster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/ReflectionCaster.php @@ -20,291 +20,313 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class ReflectionCaster { - private static $extraMap = array( - 'docComment' => 'getDocComment', - 'extension' => 'getExtensionName', - 'isDisabled' => 'isDisabled', - 'isDeprecated' => 'isDeprecated', - 'isInternal' => 'isInternal', - 'isUserDefined' => 'isUserDefined', - 'isGenerator' => 'isGenerator', - 'isVariadic' => 'isVariadic', - ); + private static $extraMap = array( + 'docComment' => 'getDocComment', + 'extension' => 'getExtensionName', + 'isDisabled' => 'isDisabled', + 'isDeprecated' => 'isDeprecated', + 'isInternal' => 'isInternal', + 'isUserDefined' => 'isUserDefined', + 'isGenerator' => 'isGenerator', + 'isVariadic' => 'isVariadic', + ); - public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - $c = new \ReflectionFunction($c); + public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + $c = new \ReflectionFunction($c); - $stub->class = 'Closure'; // HHVM generates unique class names for closures - $a = static::castFunctionAbstract($c, $a, $stub, $isNested); + $stub->class = 'Closure'; // HHVM generates unique class names for closures + $a = static::castFunctionAbstract($c, $a, $stub, $isNested); - if (isset($a[$prefix.'parameters'])) { - foreach ($a[$prefix.'parameters']->value as &$v) { - $param = $v; - $v = new EnumStub(array()); - foreach (static::castParameter($param, array(), $stub, true) as $k => $param) { - if ("\0" === $k[0]) { - $v->value[substr($k, 3)] = $param; - } - } - unset($v->value['position'], $v->value['isVariadic'], $v->value['byReference'], $v); - } - } + if (isset($a[$prefix.'parameters'])) { + foreach ($a[$prefix.'parameters']->value as &$v) { + $param = $v; + $v = new EnumStub(array()); + foreach (static::castParameter($param, array(), $stub, true) as $k => $param) { + if ("\0" === $k[0]) { + $v->value[substr($k, 3)] = $param; + } + } + unset($v->value['position'], $v->value['isVariadic'], $v->value['byReference'], $v); + } + } - if ($f = $c->getFileName()) { - $a[$prefix.'file'] = $f; - $a[$prefix.'line'] = $c->getStartLine().' to '.$c->getEndLine(); - } + if ($f = $c->getFileName()) { + $a[$prefix.'file'] = new LinkStub($f, $c->getStartLine()); + $a[$prefix.'line'] = $c->getStartLine().' to '.$c->getEndLine(); + } - $prefix = Caster::PREFIX_DYNAMIC; - unset($a['name'], $a[$prefix.'0'], $a[$prefix.'this'], $a[$prefix.'parameter'], $a[Caster::PREFIX_VIRTUAL.'extra']); + $prefix = Caster::PREFIX_DYNAMIC; + unset($a['name'], $a[$prefix.'this'], $a[$prefix.'parameter'], $a[Caster::PREFIX_VIRTUAL.'extra']); - return $a; - } + return $a; + } - public static function castGenerator(\Generator $c, array $a, Stub $stub, $isNested) - { - return class_exists('ReflectionGenerator', false) ? self::castReflectionGenerator(new \ReflectionGenerator($c), $a, $stub, $isNested) : $a; - } + public static function castGenerator(\Generator $c, array $a, Stub $stub, $isNested) + { + if (!class_exists('ReflectionGenerator', false)) { + return $a; + } - public static function castType(\ReflectionType $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; + // Cannot create ReflectionGenerator based on a terminated Generator + try { + $reflectionGenerator = new \ReflectionGenerator($c); + } catch (\Exception $e) { + $a[Caster::PREFIX_VIRTUAL.'closed'] = true; - $a += array( - $prefix.'type' => $c->__toString(), - $prefix.'allowsNull' => $c->allowsNull(), - $prefix.'isBuiltin' => $c->isBuiltin(), - ); + return $a; + } - return $a; - } + return self::castReflectionGenerator($reflectionGenerator, $a, $stub, $isNested); + } - public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; + public static function castType(\ReflectionType $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; - if ($c->getThis()) { - $a[$prefix.'this'] = new CutStub($c->getThis()); - } - $x = $c->getFunction(); - $frame = array( - 'class' => isset($x->class) ? $x->class : null, - 'type' => isset($x->class) ? ($x->isStatic() ? '::' : '->') : null, - 'function' => $x->name, - 'file' => $c->getExecutingFile(), - 'line' => $c->getExecutingLine(), - ); - if ($trace = $c->getTrace(DEBUG_BACKTRACE_IGNORE_ARGS)) { - $x = new \ReflectionGenerator($c->getExecutingGenerator()); - array_unshift($trace, array( - 'function' => 'yield', - 'file' => $x->getExecutingFile(), - 'line' => $x->getExecutingLine() - 1, - )); - $trace[] = $frame; - $a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1); - } else { - $x = new FrameStub($frame, false, true); - $x = ExceptionCaster::castFrameStub($x, array(), $x, true); - $a[$prefix.'executing'] = new EnumStub(array( - $frame['class'].$frame['type'].$frame['function'].'()' => $x[$prefix.'src'], - )); - } + $a += array( + $prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : $c->__toString(), + $prefix.'allowsNull' => $c->allowsNull(), + $prefix.'isBuiltin' => $c->isBuiltin(), + ); - return $a; - } + return $a; + } - public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isNested, $filter = 0) - { - $prefix = Caster::PREFIX_VIRTUAL; + public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; - if ($n = \Reflection::getModifierNames($c->getModifiers())) { - $a[$prefix.'modifiers'] = implode(' ', $n); - } + if ($c->getThis()) { + $a[$prefix.'this'] = new CutStub($c->getThis()); + } + $function = $c->getFunction(); + $frame = array( + 'class' => isset($function->class) ? $function->class : null, + 'type' => isset($function->class) ? ($function->isStatic() ? '::' : '->') : null, + 'function' => $function->name, + 'file' => $c->getExecutingFile(), + 'line' => $c->getExecutingLine(), + ); + if ($trace = $c->getTrace(DEBUG_BACKTRACE_IGNORE_ARGS)) { + $function = new \ReflectionGenerator($c->getExecutingGenerator()); + array_unshift($trace, array( + 'function' => 'yield', + 'file' => $function->getExecutingFile(), + 'line' => $function->getExecutingLine() - 1, + )); + $trace[] = $frame; + $a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1); + } else { + $function = new FrameStub($frame, false, true); + $function = ExceptionCaster::castFrameStub($function, array(), $function, true); + $a[$prefix.'executing'] = new EnumStub(array( + $frame['class'].$frame['type'].$frame['function'].'()' => $function[$prefix.'src'], + )); + } - self::addMap($a, $c, array( - 'extends' => 'getParentClass', - 'implements' => 'getInterfaceNames', - 'constants' => 'getConstants', - )); + $a[Caster::PREFIX_VIRTUAL.'closed'] = false; - foreach ($c->getProperties() as $n) { - $a[$prefix.'properties'][$n->name] = $n; - } + return $a; + } - foreach ($c->getMethods() as $n) { - $a[$prefix.'methods'][$n->name] = $n; - } + public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $prefix = Caster::PREFIX_VIRTUAL; - if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) { - self::addExtra($a, $c); - } + if ($n = \Reflection::getModifierNames($c->getModifiers())) { + $a[$prefix.'modifiers'] = implode(' ', $n); + } - return $a; - } + self::addMap($a, $c, array( + 'extends' => 'getParentClass', + 'implements' => 'getInterfaceNames', + 'constants' => 'getConstants', + )); - public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, $isNested, $filter = 0) - { - $prefix = Caster::PREFIX_VIRTUAL; + foreach ($c->getProperties() as $n) { + $a[$prefix.'properties'][$n->name] = $n; + } - self::addMap($a, $c, array( - 'returnsReference' => 'returnsReference', - 'returnType' => 'getReturnType', - 'class' => 'getClosureScopeClass', - 'this' => 'getClosureThis', - )); + foreach ($c->getMethods() as $n) { + $a[$prefix.'methods'][$n->name] = $n; + } - if (isset($a[$prefix.'returnType'])) { - $a[$prefix.'returnType'] = (string) $a[$prefix.'returnType']; - } - if (isset($a[$prefix.'this'])) { - $a[$prefix.'this'] = new CutStub($a[$prefix.'this']); - } + if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) { + self::addExtra($a, $c); + } - foreach ($c->getParameters() as $v) { - $k = '$'.$v->name; - if ($v->isPassedByReference()) { - $k = '&'.$k; - } - if (method_exists($v, 'isVariadic') && $v->isVariadic()) { - $k = '...'.$k; - } - $a[$prefix.'parameters'][$k] = $v; - } - if (isset($a[$prefix.'parameters'])) { - $a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']); - } + return $a; + } - if ($v = $c->getStaticVariables()) { - foreach ($v as $k => &$v) { - $a[$prefix.'use']['$'.$k] = &$v; - } - unset($v); - $a[$prefix.'use'] = new EnumStub($a[$prefix.'use']); - } + public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, $isNested, $filter = 0) + { + $prefix = Caster::PREFIX_VIRTUAL; - if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) { - self::addExtra($a, $c); - } + self::addMap($a, $c, array( + 'returnsReference' => 'returnsReference', + 'returnType' => 'getReturnType', + 'class' => 'getClosureScopeClass', + 'this' => 'getClosureThis', + )); - // Added by HHVM - unset($a[Caster::PREFIX_DYNAMIC.'static']); + if (isset($a[$prefix.'returnType'])) { + $v = $a[$prefix.'returnType']; + $v = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); + $a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType']->allowsNull() ? '?'.$v : $v, array(class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '')); + } + if (isset($a[$prefix.'class'])) { + $a[$prefix.'class'] = new ClassStub($a[$prefix.'class']); + } + if (isset($a[$prefix.'this'])) { + $a[$prefix.'this'] = new CutStub($a[$prefix.'this']); + } - return $a; - } + foreach ($c->getParameters() as $v) { + $k = '$'.$v->name; + if (method_exists($v, 'isVariadic') && $v->isVariadic()) { + $k = '...'.$k; + } + if ($v->isPassedByReference()) { + $k = '&'.$k; + } + $a[$prefix.'parameters'][$k] = $v; + } + if (isset($a[$prefix.'parameters'])) { + $a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']); + } - public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); + if ($v = $c->getStaticVariables()) { + foreach ($v as $k => &$v) { + $a[$prefix.'use']['$'.$k] = &$v; + } + unset($v); + $a[$prefix.'use'] = new EnumStub($a[$prefix.'use']); + } - return $a; - } + if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) { + self::addExtra($a, $c); + } - public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; + // Added by HHVM + unset($a[Caster::PREFIX_DYNAMIC.'static']); - // Added by HHVM - unset($a['info']); + return $a; + } - self::addMap($a, $c, array( - 'position' => 'getPosition', - 'isVariadic' => 'isVariadic', - 'byReference' => 'isPassedByReference', - )); + public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, $isNested) + { + $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); - try { - if (method_exists($c, 'hasType')) { - if ($c->hasType()) { - $a[$prefix.'typeHint'] = $c->getType()->__toString(); - } - } elseif ($c->isArray()) { - $a[$prefix.'typeHint'] = 'array'; - } elseif (method_exists($c, 'isCallable') && $c->isCallable()) { - $a[$prefix.'typeHint'] = 'callable'; - } elseif ($v = $c->getClass()) { - $a[$prefix.'typeHint'] = $v->name; - } - } catch (\ReflectionException $e) { - if (preg_match('/^Class ([^ ]++) does not exist$/', $e->getMessage(), $m)) { - $a[$prefix.'typeHint'] = $m[1]; - } - } + return $a; + } - try { - $a[$prefix.'default'] = $v = $c->getDefaultValue(); - if (method_exists($c, 'isDefaultValueConstant') && $c->isDefaultValueConstant()) { - $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v); - } - } catch (\ReflectionException $e) { - if (isset($a[$prefix.'typeHint']) && $c->allowsNull()) { - $a[$prefix.'default'] = null; - } - } + public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; - return $a; - } + // Added by HHVM + unset($a['info']); - public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); - self::addExtra($a, $c); + self::addMap($a, $c, array( + 'position' => 'getPosition', + 'isVariadic' => 'isVariadic', + 'byReference' => 'isPassedByReference', + 'allowsNull' => 'allowsNull', + )); - return $a; - } + if (method_exists($c, 'getType')) { + if ($v = $c->getType()) { + $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString(); + } + } elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $c, $v)) { + $a[$prefix.'typeHint'] = $v[1]; + } - public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, $isNested) - { - self::addMap($a, $c, array( - 'version' => 'getVersion', - 'dependencies' => 'getDependencies', - 'iniEntries' => 'getIniEntries', - 'isPersistent' => 'isPersistent', - 'isTemporary' => 'isTemporary', - 'constants' => 'getConstants', - 'functions' => 'getFunctions', - 'classes' => 'getClasses', - )); + if (isset($a[$prefix.'typeHint'])) { + $v = $a[$prefix.'typeHint']; + $a[$prefix.'typeHint'] = new ClassStub($v, array(class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '')); + } else { + unset($a[$prefix.'allowsNull']); + } - return $a; - } + try { + $a[$prefix.'default'] = $v = $c->getDefaultValue(); + if (method_exists($c, 'isDefaultValueConstant') && $c->isDefaultValueConstant()) { + $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v); + } + if (null === $v) { + unset($a[$prefix.'allowsNull']); + } + } catch (\ReflectionException $e) { + if (isset($a[$prefix.'typeHint']) && $c->allowsNull() && !class_exists('ReflectionNamedType', false)) { + $a[$prefix.'default'] = null; + unset($a[$prefix.'allowsNull']); + } + } - public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, $isNested) - { - self::addMap($a, $c, array( - 'version' => 'getVersion', - 'author' => 'getAuthor', - 'copyright' => 'getCopyright', - 'url' => 'getURL', - )); + return $a; + } - return $a; - } + public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, $isNested) + { + $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers())); + self::addExtra($a, $c); - private static function addExtra(&$a, \Reflector $c) - { - $x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : array(); + return $a; + } - if (method_exists($c, 'getFileName') && $m = $c->getFileName()) { - $x['file'] = $m; - $x['line'] = $c->getStartLine().' to '.$c->getEndLine(); - } + public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, $isNested) + { + self::addMap($a, $c, array( + 'version' => 'getVersion', + 'dependencies' => 'getDependencies', + 'iniEntries' => 'getIniEntries', + 'isPersistent' => 'isPersistent', + 'isTemporary' => 'isTemporary', + 'constants' => 'getConstants', + 'functions' => 'getFunctions', + 'classes' => 'getClasses', + )); - self::addMap($x, $c, self::$extraMap, ''); + return $a; + } - if ($x) { - $a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x); - } - } + public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, $isNested) + { + self::addMap($a, $c, array( + 'version' => 'getVersion', + 'author' => 'getAuthor', + 'copyright' => 'getCopyright', + 'url' => 'getURL', + )); - private static function addMap(&$a, \Reflector $c, $map, $prefix = Caster::PREFIX_VIRTUAL) - { - foreach ($map as $k => $m) { - if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) { - $a[$prefix.$k] = $m instanceof \Reflector ? $m->name : $m; - } - } - } + return $a; + } + + private static function addExtra(&$a, \Reflector $c) + { + $x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : array(); + + if (method_exists($c, 'getFileName') && $m = $c->getFileName()) { + $x['file'] = new LinkStub($m, $c->getStartLine()); + $x['line'] = $c->getStartLine().' to '.$c->getEndLine(); + } + + self::addMap($x, $c, self::$extraMap, ''); + + if ($x) { + $a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x); + } + } + + private static function addMap(&$a, \Reflector $c, $map, $prefix = Caster::PREFIX_VIRTUAL) + { + foreach ($map as $k => $m) { + if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) { + $a[$prefix.$k] = $m instanceof \Reflector ? $m->name : $m; + } + } + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/ResourceCaster.php b/htdocs/includes/symfony/var-dumper/Caster/ResourceCaster.php index 903641f69c6..0b189d4d9b5 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/ResourceCaster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/ResourceCaster.php @@ -20,48 +20,53 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class ResourceCaster { - public static function castCurl($h, array $a, Stub $stub, $isNested) - { - return curl_getinfo($h); - } + public static function castCurl($h, array $a, Stub $stub, $isNested) + { + return curl_getinfo($h); + } - public static function castDba($dba, array $a, Stub $stub, $isNested) - { - $list = dba_list(); - $a['file'] = $list[(int) $dba]; + public static function castDba($dba, array $a, Stub $stub, $isNested) + { + $list = dba_list(); + $a['file'] = $list[(int) $dba]; - return $a; - } + return $a; + } - public static function castProcess($process, array $a, Stub $stub, $isNested) - { - return proc_get_status($process); - } + public static function castProcess($process, array $a, Stub $stub, $isNested) + { + return proc_get_status($process); + } - public static function castStream($stream, array $a, Stub $stub, $isNested) - { - return stream_get_meta_data($stream) + static::castStreamContext($stream, $a, $stub, $isNested); - } + public static function castStream($stream, array $a, Stub $stub, $isNested) + { + $a = stream_get_meta_data($stream) + static::castStreamContext($stream, $a, $stub, $isNested); + if (isset($a['uri'])) { + $a['uri'] = new LinkStub($a['uri']); + } - public static function castStreamContext($stream, array $a, Stub $stub, $isNested) - { - return stream_context_get_params($stream); - } + return $a; + } - public static function castGd($gd, array $a, Stub $stub, $isNested) - { - $a['size'] = imagesx($gd).'x'.imagesy($gd); - $a['trueColor'] = imageistruecolor($gd); + public static function castStreamContext($stream, array $a, Stub $stub, $isNested) + { + return @stream_context_get_params($stream) ?: $a; + } - return $a; - } + public static function castGd($gd, array $a, Stub $stub, $isNested) + { + $a['size'] = imagesx($gd).'x'.imagesy($gd); + $a['trueColor'] = imageistruecolor($gd); - public static function castMysqlLink($h, array $a, Stub $stub, $isNested) - { - $a['host'] = mysql_get_host_info($h); - $a['protocol'] = mysql_get_proto_info($h); - $a['server'] = mysql_get_server_info($h); + return $a; + } - return $a; - } + public static function castMysqlLink($h, array $a, Stub $stub, $isNested) + { + $a['host'] = mysql_get_host_info($h); + $a['protocol'] = mysql_get_proto_info($h); + $a['server'] = mysql_get_server_info($h); + + return $a; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/SplCaster.php b/htdocs/includes/symfony/var-dumper/Caster/SplCaster.php index 97f21463821..176e7f2ae48 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/SplCaster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/SplCaster.php @@ -20,184 +20,188 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class SplCaster { - private static $splFileObjectFlags = array( - \SplFileObject::DROP_NEW_LINE => 'DROP_NEW_LINE', - \SplFileObject::READ_AHEAD => 'READ_AHEAD', - \SplFileObject::SKIP_EMPTY => 'SKIP_EMPTY', - \SplFileObject::READ_CSV => 'READ_CSV', - ); + private static $splFileObjectFlags = array( + \SplFileObject::DROP_NEW_LINE => 'DROP_NEW_LINE', + \SplFileObject::READ_AHEAD => 'READ_AHEAD', + \SplFileObject::SKIP_EMPTY => 'SKIP_EMPTY', + \SplFileObject::READ_CSV => 'READ_CSV', + ); - public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - $class = $stub->class; - $flags = $c->getFlags(); + public static function castArrayObject(\ArrayObject $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + $class = $stub->class; + $flags = $c->getFlags(); - $b = array( - $prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST), - $prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS), - $prefix.'iteratorClass' => $c->getIteratorClass(), - $prefix.'storage' => $c->getArrayCopy(), - ); + $b = array( + $prefix.'flag::STD_PROP_LIST' => (bool) ($flags & \ArrayObject::STD_PROP_LIST), + $prefix.'flag::ARRAY_AS_PROPS' => (bool) ($flags & \ArrayObject::ARRAY_AS_PROPS), + $prefix.'iteratorClass' => new ClassStub($c->getIteratorClass()), + $prefix.'storage' => $c->getArrayCopy(), + ); - if ($class === 'ArrayObject') { - $a = $b; - } else { - if (!($flags & \ArrayObject::STD_PROP_LIST)) { - $c->setFlags(\ArrayObject::STD_PROP_LIST); - $a = Caster::castObject($c, new \ReflectionClass($class)); - $c->setFlags($flags); - } + if ($class === 'ArrayObject') { + $a = $b; + } else { + if (!($flags & \ArrayObject::STD_PROP_LIST)) { + $c->setFlags(\ArrayObject::STD_PROP_LIST); + $a = Caster::castObject($c, new \ReflectionClass($class)); + $c->setFlags($flags); + } - $a += $b; - } + $a += $b; + } - return $a; - } + return $a; + } - public static function castHeap(\Iterator $c, array $a, Stub $stub, $isNested) - { - $a += array( - Caster::PREFIX_VIRTUAL.'heap' => iterator_to_array(clone $c), - ); + public static function castHeap(\Iterator $c, array $a, Stub $stub, $isNested) + { + $a += array( + Caster::PREFIX_VIRTUAL.'heap' => iterator_to_array(clone $c), + ); - return $a; - } + return $a; + } - public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, Stub $stub, $isNested) - { - $prefix = Caster::PREFIX_VIRTUAL; - $mode = $c->getIteratorMode(); - $c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE); + public static function castDoublyLinkedList(\SplDoublyLinkedList $c, array $a, Stub $stub, $isNested) + { + $prefix = Caster::PREFIX_VIRTUAL; + $mode = $c->getIteratorMode(); + $c->setIteratorMode(\SplDoublyLinkedList::IT_MODE_KEEP | $mode & ~\SplDoublyLinkedList::IT_MODE_DELETE); - $a += array( - $prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_KEEP) ? 'IT_MODE_KEEP' : 'IT_MODE_DELETE'), $mode), - $prefix.'dllist' => iterator_to_array($c), - ); - $c->setIteratorMode($mode); + $a += array( + $prefix.'mode' => new ConstStub((($mode & \SplDoublyLinkedList::IT_MODE_LIFO) ? 'IT_MODE_LIFO' : 'IT_MODE_FIFO').' | '.(($mode & \SplDoublyLinkedList::IT_MODE_DELETE) ? 'IT_MODE_DELETE' : 'IT_MODE_KEEP'), $mode), + $prefix.'dllist' => iterator_to_array($c), + ); + $c->setIteratorMode($mode); - return $a; - } + return $a; + } - public static function castFileInfo(\SplFileInfo $c, array $a, Stub $stub, $isNested) - { - static $map = array( - 'path' => 'getPath', - 'filename' => 'getFilename', - 'basename' => 'getBasename', - 'pathname' => 'getPathname', - 'extension' => 'getExtension', - 'realPath' => 'getRealPath', - 'aTime' => 'getATime', - 'mTime' => 'getMTime', - 'cTime' => 'getCTime', - 'inode' => 'getInode', - 'size' => 'getSize', - 'perms' => 'getPerms', - 'owner' => 'getOwner', - 'group' => 'getGroup', - 'type' => 'getType', - 'writable' => 'isWritable', - 'readable' => 'isReadable', - 'executable' => 'isExecutable', - 'file' => 'isFile', - 'dir' => 'isDir', - 'link' => 'isLink', - 'linkTarget' => 'getLinkTarget', - ); + public static function castFileInfo(\SplFileInfo $c, array $a, Stub $stub, $isNested) + { + static $map = array( + 'path' => 'getPath', + 'filename' => 'getFilename', + 'basename' => 'getBasename', + 'pathname' => 'getPathname', + 'extension' => 'getExtension', + 'realPath' => 'getRealPath', + 'aTime' => 'getATime', + 'mTime' => 'getMTime', + 'cTime' => 'getCTime', + 'inode' => 'getInode', + 'size' => 'getSize', + 'perms' => 'getPerms', + 'owner' => 'getOwner', + 'group' => 'getGroup', + 'type' => 'getType', + 'writable' => 'isWritable', + 'readable' => 'isReadable', + 'executable' => 'isExecutable', + 'file' => 'isFile', + 'dir' => 'isDir', + 'link' => 'isLink', + 'linkTarget' => 'getLinkTarget', + ); - $prefix = Caster::PREFIX_VIRTUAL; + $prefix = Caster::PREFIX_VIRTUAL; - foreach ($map as $key => $accessor) { - try { - $a[$prefix.$key] = $c->$accessor(); - } catch (\Exception $e) { - } - } + foreach ($map as $key => $accessor) { + try { + $a[$prefix.$key] = $c->$accessor(); + } catch (\Exception $e) { + } + } - if (isset($a[$prefix.'perms'])) { - $a[$prefix.'perms'] = new ConstStub(sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']); - } + if (isset($a[$prefix.'realPath'])) { + $a[$prefix.'realPath'] = new LinkStub($a[$prefix.'realPath']); + } - static $mapDate = array('aTime', 'mTime', 'cTime'); - foreach ($mapDate as $key) { - if (isset($a[$prefix.$key])) { - $a[$prefix.$key] = new ConstStub(date('Y-m-d H:i:s', $a[$prefix.$key]), $a[$prefix.$key]); - } - } + if (isset($a[$prefix.'perms'])) { + $a[$prefix.'perms'] = new ConstStub(sprintf('0%o', $a[$prefix.'perms']), $a[$prefix.'perms']); + } - return $a; - } + static $mapDate = array('aTime', 'mTime', 'cTime'); + foreach ($mapDate as $key) { + if (isset($a[$prefix.$key])) { + $a[$prefix.$key] = new ConstStub(date('Y-m-d H:i:s', $a[$prefix.$key]), $a[$prefix.$key]); + } + } - public static function castFileObject(\SplFileObject $c, array $a, Stub $stub, $isNested) - { - static $map = array( - 'csvControl' => 'getCsvControl', - 'flags' => 'getFlags', - 'maxLineLen' => 'getMaxLineLen', - 'fstat' => 'fstat', - 'eof' => 'eof', - 'key' => 'key', - ); + return $a; + } - $prefix = Caster::PREFIX_VIRTUAL; + public static function castFileObject(\SplFileObject $c, array $a, Stub $stub, $isNested) + { + static $map = array( + 'csvControl' => 'getCsvControl', + 'flags' => 'getFlags', + 'maxLineLen' => 'getMaxLineLen', + 'fstat' => 'fstat', + 'eof' => 'eof', + 'key' => 'key', + ); - foreach ($map as $key => $accessor) { - try { - $a[$prefix.$key] = $c->$accessor(); - } catch (\Exception $e) { - } - } + $prefix = Caster::PREFIX_VIRTUAL; - if (isset($a[$prefix.'flags'])) { - $flagsArray = array(); - foreach (self::$splFileObjectFlags as $value => $name) { - if ($a[$prefix.'flags'] & $value) { - $flagsArray[] = $name; - } - } - $a[$prefix.'flags'] = new ConstStub(implode('|', $flagsArray), $a[$prefix.'flags']); - } + foreach ($map as $key => $accessor) { + try { + $a[$prefix.$key] = $c->$accessor(); + } catch (\Exception $e) { + } + } - if (isset($a[$prefix.'fstat'])) { - $a[$prefix.'fstat'] = new CutArrayStub($a[$prefix.'fstat'], array('dev', 'ino', 'nlink', 'rdev', 'blksize', 'blocks')); - } + if (isset($a[$prefix.'flags'])) { + $flagsArray = array(); + foreach (self::$splFileObjectFlags as $value => $name) { + if ($a[$prefix.'flags'] & $value) { + $flagsArray[] = $name; + } + } + $a[$prefix.'flags'] = new ConstStub(implode('|', $flagsArray), $a[$prefix.'flags']); + } - return $a; - } + if (isset($a[$prefix.'fstat'])) { + $a[$prefix.'fstat'] = new CutArrayStub($a[$prefix.'fstat'], array('dev', 'ino', 'nlink', 'rdev', 'blksize', 'blocks')); + } - public static function castFixedArray(\SplFixedArray $c, array $a, Stub $stub, $isNested) - { - $a += array( - Caster::PREFIX_VIRTUAL.'storage' => $c->toArray(), - ); + return $a; + } - return $a; - } + public static function castFixedArray(\SplFixedArray $c, array $a, Stub $stub, $isNested) + { + $a += array( + Caster::PREFIX_VIRTUAL.'storage' => $c->toArray(), + ); - public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $stub, $isNested) - { - $storage = array(); - unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967 + return $a; + } - foreach ($c as $obj) { - $storage[spl_object_hash($obj)] = array( - 'object' => $obj, - 'info' => $c->getInfo(), - ); - } + public static function castObjectStorage(\SplObjectStorage $c, array $a, Stub $stub, $isNested) + { + $storage = array(); + unset($a[Caster::PREFIX_DYNAMIC."\0gcdata"]); // Don't hit https://bugs.php.net/65967 - $a += array( - Caster::PREFIX_VIRTUAL.'storage' => $storage, - ); + foreach (clone $c as $obj) { + $storage[spl_object_hash($obj)] = array( + 'object' => $obj, + 'info' => $c->getInfo(), + ); + } - return $a; - } + $a += array( + Caster::PREFIX_VIRTUAL.'storage' => $storage, + ); - public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub, $isNested) - { - $a[Caster::PREFIX_VIRTUAL.'innerIterator'] = $c->getInnerIterator(); + return $a; + } - return $a; - } + public static function castOuterIterator(\OuterIterator $c, array $a, Stub $stub, $isNested) + { + $a[Caster::PREFIX_VIRTUAL.'innerIterator'] = $c->getInnerIterator(); + + return $a; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/StubCaster.php b/htdocs/includes/symfony/var-dumper/Caster/StubCaster.php index ebad5ba9844..83fde9eba3c 100644 --- a/htdocs/includes/symfony/var-dumper/Caster/StubCaster.php +++ b/htdocs/includes/symfony/var-dumper/Caster/StubCaster.php @@ -20,53 +20,63 @@ use Symfony\Component\VarDumper\Cloner\Stub; */ class StubCaster { - public static function castStub(Stub $c, array $a, Stub $stub, $isNested) - { - if ($isNested) { - $stub->type = $c->type; - $stub->class = $c->class; - $stub->value = $c->value; - $stub->handle = $c->handle; - $stub->cut = $c->cut; + public static function castStub(Stub $c, array $a, Stub $stub, $isNested) + { + if ($isNested) { + $stub->type = $c->type; + $stub->class = $c->class; + $stub->value = $c->value; + $stub->handle = $c->handle; + $stub->cut = $c->cut; + $stub->attr = $c->attr; - return array(); - } - } + if (Stub::TYPE_REF === $c->type && !$c->class && is_string($c->value) && !preg_match('//u', $c->value)) { + $stub->type = Stub::TYPE_STRING; + $stub->class = Stub::STRING_BINARY; + } - public static function castCutArray(CutArrayStub $c, array $a, Stub $stub, $isNested) - { - return $isNested ? $c->preservedSubset : $a; - } + $a = array(); + } - public static function cutInternals($obj, array $a, Stub $stub, $isNested) - { - if ($isNested) { - $stub->cut += count($a); + return $a; + } - return array(); - } + public static function castCutArray(CutArrayStub $c, array $a, Stub $stub, $isNested) + { + return $isNested ? $c->preservedSubset : $a; + } - return $a; - } + public static function cutInternals($obj, array $a, Stub $stub, $isNested) + { + if ($isNested) { + $stub->cut += count($a); - public static function castEnum(EnumStub $c, array $a, Stub $stub, $isNested) - { - if ($isNested) { - $stub->class = ''; - $stub->handle = 0; - $stub->value = null; + return array(); + } - $a = array(); + return $a; + } - if ($c->value) { - foreach (array_keys($c->value) as $k) { - $keys[] = Caster::PREFIX_VIRTUAL.$k; - } - // Preserve references with array_combine() - $a = array_combine($keys, $c->value); - } - } + public static function castEnum(EnumStub $c, array $a, Stub $stub, $isNested) + { + if ($isNested) { + $stub->class = $c->dumpKeys ? '' : null; + $stub->handle = 0; + $stub->value = null; + $stub->cut = $c->cut; + $stub->attr = $c->attr; - return $a; - } + $a = array(); + + if ($c->value) { + foreach (array_keys($c->value) as $k) { + $keys[] = !isset($k[0]) || "\0" !== $k[0] ? Caster::PREFIX_VIRTUAL.$k : $k; + } + // Preserve references with array_combine() + $a = array_combine($keys, $c->value); + } + } + + return $a; + } } diff --git a/htdocs/includes/symfony/var-dumper/Caster/XmlReaderCaster.php b/htdocs/includes/symfony/var-dumper/Caster/XmlReaderCaster.php new file mode 100644 index 00000000000..bbd4645c8e5 --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Caster/XmlReaderCaster.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Caster; + +use Symfony\Component\VarDumper\Cloner\Stub; + +/** + * Casts XmlReader class to array representation. + * + * @author Baptiste Clavié + */ +class XmlReaderCaster +{ + private static $nodeTypes = array( + \XmlReader::NONE => 'NONE', + \XmlReader::ELEMENT => 'ELEMENT', + \XmlReader::ATTRIBUTE => 'ATTRIBUTE', + \XmlReader::TEXT => 'TEXT', + \XmlReader::CDATA => 'CDATA', + \XmlReader::ENTITY_REF => 'ENTITY_REF', + \XmlReader::ENTITY => 'ENTITY', + \XmlReader::PI => 'PI (Processing Instruction)', + \XmlReader::COMMENT => 'COMMENT', + \XmlReader::DOC => 'DOC', + \XmlReader::DOC_TYPE => 'DOC_TYPE', + \XmlReader::DOC_FRAGMENT => 'DOC_FRAGMENT', + \XmlReader::NOTATION => 'NOTATION', + \XmlReader::WHITESPACE => 'WHITESPACE', + \XmlReader::SIGNIFICANT_WHITESPACE => 'SIGNIFICANT_WHITESPACE', + \XmlReader::END_ELEMENT => 'END_ELEMENT', + \XmlReader::END_ENTITY => 'END_ENTITY', + \XmlReader::XML_DECLARATION => 'XML_DECLARATION', + ); + + public static function castXmlReader(\XmlReader $reader, array $a, Stub $stub, $isNested) + { + $props = Caster::PREFIX_VIRTUAL.'parserProperties'; + $info = array( + 'localName' => $reader->localName, + 'prefix' => $reader->prefix, + 'nodeType' => new ConstStub(self::$nodeTypes[$reader->nodeType], $reader->nodeType), + 'depth' => $reader->depth, + 'isDefault' => $reader->isDefault, + 'isEmptyElement' => \XmlReader::NONE === $reader->nodeType ? null : $reader->isEmptyElement, + 'xmlLang' => $reader->xmlLang, + 'attributeCount' => $reader->attributeCount, + 'value' => $reader->value, + 'namespaceURI' => $reader->namespaceURI, + 'baseURI' => $reader->baseURI ? new LinkStub($reader->baseURI) : $reader->baseURI, + $props => array( + 'LOADDTD' => $reader->getParserProperty(\XmlReader::LOADDTD), + 'DEFAULTATTRS' => $reader->getParserProperty(\XmlReader::DEFAULTATTRS), + 'VALIDATE' => $reader->getParserProperty(\XmlReader::VALIDATE), + 'SUBST_ENTITIES' => $reader->getParserProperty(\XmlReader::SUBST_ENTITIES), + ), + ); + + if ($info[$props] = Caster::filter($info[$props], Caster::EXCLUDE_EMPTY, array(), $count)) { + $info[$props] = new EnumStub($info[$props]); + $info[$props]->cut = $count; + } + + $info = Caster::filter($info, Caster::EXCLUDE_EMPTY, array(), $count); + // +2 because hasValue and hasAttributes are always filtered + $stub->cut += $count + 2; + + return $a + $info; + } +} diff --git a/htdocs/includes/symfony/var-dumper/Cloner/AbstractCloner.php b/htdocs/includes/symfony/var-dumper/Cloner/AbstractCloner.php index 2807ceb935b..27bc47870ae 100644 --- a/htdocs/includes/symfony/var-dumper/Cloner/AbstractCloner.php +++ b/htdocs/includes/symfony/var-dumper/Cloner/AbstractCloner.php @@ -21,293 +21,302 @@ use Symfony\Component\VarDumper\Exception\ThrowingCasterException; */ abstract class AbstractCloner implements ClonerInterface { - public static $defaultCasters = array( - 'Symfony\Component\VarDumper\Caster\CutStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub', - 'Symfony\Component\VarDumper\Caster\CutArrayStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castCutArray', - 'Symfony\Component\VarDumper\Caster\ConstStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub', - 'Symfony\Component\VarDumper\Caster\EnumStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castEnum', + public static $defaultCasters = array( + '__PHP_Incomplete_Class' => 'Symfony\Component\VarDumper\Caster\Caster::castPhpIncompleteClass', - 'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure', - 'Generator' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castGenerator', - 'ReflectionType' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castType', - 'ReflectionGenerator' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflectionGenerator', - 'ReflectionClass' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClass', - 'ReflectionFunctionAbstract' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castFunctionAbstract', - 'ReflectionMethod' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castMethod', - 'ReflectionParameter' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castParameter', - 'ReflectionProperty' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castProperty', - 'ReflectionExtension' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castExtension', - 'ReflectionZendExtension' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castZendExtension', + 'Symfony\Component\VarDumper\Caster\CutStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub', + 'Symfony\Component\VarDumper\Caster\CutArrayStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castCutArray', + 'Symfony\Component\VarDumper\Caster\ConstStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub', + 'Symfony\Component\VarDumper\Caster\EnumStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castEnum', - 'Doctrine\Common\Persistence\ObjectManager' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', - 'Doctrine\Common\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castCommonProxy', - 'Doctrine\ORM\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castOrmProxy', - 'Doctrine\ORM\PersistentCollection' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castPersistentCollection', + 'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure', + 'Generator' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castGenerator', + 'ReflectionType' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castType', + 'ReflectionGenerator' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflectionGenerator', + 'ReflectionClass' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClass', + 'ReflectionFunctionAbstract' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castFunctionAbstract', + 'ReflectionMethod' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castMethod', + 'ReflectionParameter' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castParameter', + 'ReflectionProperty' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castProperty', + 'ReflectionExtension' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castExtension', + 'ReflectionZendExtension' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castZendExtension', - 'DOMException' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castException', - 'DOMStringList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', - 'DOMNameList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', - 'DOMImplementation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castImplementation', - 'DOMImplementationList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', - 'DOMNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNode', - 'DOMNameSpaceNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNameSpaceNode', - 'DOMDocument' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocument', - 'DOMNodeList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', - 'DOMNamedNodeMap' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', - 'DOMCharacterData' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castCharacterData', - 'DOMAttr' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castAttr', - 'DOMElement' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castElement', - 'DOMText' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castText', - 'DOMTypeinfo' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castTypeinfo', - 'DOMDomError' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDomError', - 'DOMLocator' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLocator', - 'DOMDocumentType' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocumentType', - 'DOMNotation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNotation', - 'DOMEntity' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castEntity', - 'DOMProcessingInstruction' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castProcessingInstruction', - 'DOMXPath' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castXPath', + 'Doctrine\Common\Persistence\ObjectManager' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', + 'Doctrine\Common\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castCommonProxy', + 'Doctrine\ORM\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castOrmProxy', + 'Doctrine\ORM\PersistentCollection' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castPersistentCollection', - 'ErrorException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castErrorException', - 'Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException', - 'Error' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castError', - 'Symfony\Component\DependencyInjection\ContainerInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', - 'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castThrowingCasterException', - 'Symfony\Component\VarDumper\Caster\TraceStub' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castTraceStub', - 'Symfony\Component\VarDumper\Caster\FrameStub' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castFrameStub', + 'DOMException' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castException', + 'DOMStringList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', + 'DOMNameList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', + 'DOMImplementation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castImplementation', + 'DOMImplementationList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', + 'DOMNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNode', + 'DOMNameSpaceNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNameSpaceNode', + 'DOMDocument' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocument', + 'DOMNodeList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', + 'DOMNamedNodeMap' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength', + 'DOMCharacterData' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castCharacterData', + 'DOMAttr' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castAttr', + 'DOMElement' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castElement', + 'DOMText' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castText', + 'DOMTypeinfo' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castTypeinfo', + 'DOMDomError' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDomError', + 'DOMLocator' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLocator', + 'DOMDocumentType' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocumentType', + 'DOMNotation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNotation', + 'DOMEntity' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castEntity', + 'DOMProcessingInstruction' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castProcessingInstruction', + 'DOMXPath' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castXPath', - 'PHPUnit_Framework_MockObject_MockObject' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', - 'Prophecy\Prophecy\ProphecySubjectInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', - 'Mockery\MockInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', + 'XmlReader' => 'Symfony\Component\VarDumper\Caster\XmlReaderCaster::castXmlReader', - 'PDO' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdo', - 'PDOStatement' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdoStatement', + 'ErrorException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castErrorException', + 'Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException', + 'Error' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castError', + 'Symfony\Component\DependencyInjection\ContainerInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', + 'Symfony\Component\VarDumper\Exception\ThrowingCasterException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castThrowingCasterException', + 'Symfony\Component\VarDumper\Caster\TraceStub' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castTraceStub', + 'Symfony\Component\VarDumper\Caster\FrameStub' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castFrameStub', - 'AMQPConnection' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castConnection', - 'AMQPChannel' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castChannel', - 'AMQPQueue' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castQueue', - 'AMQPExchange' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castExchange', - 'AMQPEnvelope' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castEnvelope', + 'PHPUnit_Framework_MockObject_MockObject' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', + 'Prophecy\Prophecy\ProphecySubjectInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', + 'Mockery\MockInterface' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals', - 'ArrayObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castArrayObject', - 'SplDoublyLinkedList' => 'Symfony\Component\VarDumper\Caster\SplCaster::castDoublyLinkedList', - 'SplFileInfo' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFileInfo', - 'SplFileObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFileObject', - 'SplFixedArray' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFixedArray', - 'SplHeap' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap', - 'SplObjectStorage' => 'Symfony\Component\VarDumper\Caster\SplCaster::castObjectStorage', - 'SplPriorityQueue' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap', - 'OuterIterator' => 'Symfony\Component\VarDumper\Caster\SplCaster::castOuterIterator', + 'PDO' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdo', + 'PDOStatement' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdoStatement', - 'MongoCursorInterface' => 'Symfony\Component\VarDumper\Caster\MongoCaster::castCursor', + 'AMQPConnection' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castConnection', + 'AMQPChannel' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castChannel', + 'AMQPQueue' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castQueue', + 'AMQPExchange' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castExchange', + 'AMQPEnvelope' => 'Symfony\Component\VarDumper\Caster\AmqpCaster::castEnvelope', - ':curl' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castCurl', - ':dba' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba', - ':dba persistent' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba', - ':gd' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castGd', - ':mysql link' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castMysqlLink', - ':pgsql large object' => 'Symfony\Component\VarDumper\Caster\PgSqlCaster::castLargeObject', - ':pgsql link' => 'Symfony\Component\VarDumper\Caster\PgSqlCaster::castLink', - ':pgsql link persistent' => 'Symfony\Component\VarDumper\Caster\PgSqlCaster::castLink', - ':pgsql result' => 'Symfony\Component\VarDumper\Caster\PgSqlCaster::castResult', - ':process' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castProcess', - ':stream' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStream', - ':stream-context' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStreamContext', - ':xml' => 'Symfony\Component\VarDumper\Caster\XmlResourceCaster::castXml', - ); + 'ArrayObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castArrayObject', + 'SplDoublyLinkedList' => 'Symfony\Component\VarDumper\Caster\SplCaster::castDoublyLinkedList', + 'SplFileInfo' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFileInfo', + 'SplFileObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFileObject', + 'SplFixedArray' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFixedArray', + 'SplHeap' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap', + 'SplObjectStorage' => 'Symfony\Component\VarDumper\Caster\SplCaster::castObjectStorage', + 'SplPriorityQueue' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap', + 'OuterIterator' => 'Symfony\Component\VarDumper\Caster\SplCaster::castOuterIterator', - protected $maxItems = 2500; - protected $maxString = -1; - protected $useExt; + 'MongoCursorInterface' => 'Symfony\Component\VarDumper\Caster\MongoCaster::castCursor', - private $casters = array(); - private $prevErrorHandler; - private $classInfo = array(); - private $filter = 0; + 'Redis' => 'Symfony\Component\VarDumper\Caster\RedisCaster::castRedis', + 'RedisArray' => 'Symfony\Component\VarDumper\Caster\RedisCaster::castRedisArray', - /** - * @param callable[]|null $casters A map of casters. - * - * @see addCasters - */ - public function __construct(array $casters = null) - { - if (null === $casters) { - $casters = static::$defaultCasters; - } - $this->addCasters($casters); - $this->useExt = extension_loaded('symfony_debug'); - } + ':curl' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castCurl', + ':dba' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba', + ':dba persistent' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba', + ':gd' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castGd', + ':mysql link' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castMysqlLink', + ':pgsql large object' => 'Symfony\Component\VarDumper\Caster\PgSqlCaster::castLargeObject', + ':pgsql link' => 'Symfony\Component\VarDumper\Caster\PgSqlCaster::castLink', + ':pgsql link persistent' => 'Symfony\Component\VarDumper\Caster\PgSqlCaster::castLink', + ':pgsql result' => 'Symfony\Component\VarDumper\Caster\PgSqlCaster::castResult', + ':process' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castProcess', + ':stream' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStream', + ':persistent stream' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStream', + ':stream-context' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStreamContext', + ':xml' => 'Symfony\Component\VarDumper\Caster\XmlResourceCaster::castXml', + ); - /** - * Adds casters for resources and objects. - * - * Maps resources or objects types to a callback. - * Types are in the key, with a callable caster for value. - * Resource types are to be prefixed with a `:`, - * see e.g. static::$defaultCasters. - * - * @param callable[] $casters A map of casters. - */ - public function addCasters(array $casters) - { - foreach ($casters as $type => $callback) { - $this->casters[strtolower($type)][] = $callback; - } - } + protected $maxItems = 2500; + protected $maxString = -1; + protected $useExt; - /** - * Sets the maximum number of items to clone past the first level in nested structures. - * - * @param int $maxItems - */ - public function setMaxItems($maxItems) - { - $this->maxItems = (int) $maxItems; - } + private $casters = array(); + private $prevErrorHandler; + private $classInfo = array(); + private $filter = 0; - /** - * Sets the maximum cloned length for strings. - * - * @param int $maxString - */ - public function setMaxString($maxString) - { - $this->maxString = (int) $maxString; - } + /** + * @param callable[]|null $casters A map of casters + * + * @see addCasters + */ + public function __construct(array $casters = null) + { + if (null === $casters) { + $casters = static::$defaultCasters; + } + $this->addCasters($casters); + $this->useExt = extension_loaded('symfony_debug'); + } - /** - * Clones a PHP variable. - * - * @param mixed $var Any PHP variable. - * @param int $filter A bit field of Caster::EXCLUDE_* constants. - * - * @return Data The cloned variable represented by a Data object. - */ - public function cloneVar($var, $filter = 0) - { - $this->prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context) { - if (E_RECOVERABLE_ERROR === $type || E_USER_ERROR === $type) { - // Cloner never dies - throw new \ErrorException($msg, 0, $type, $file, $line); - } + /** + * Adds casters for resources and objects. + * + * Maps resources or objects types to a callback. + * Types are in the key, with a callable caster for value. + * Resource types are to be prefixed with a `:`, + * see e.g. static::$defaultCasters. + * + * @param callable[] $casters A map of casters + */ + public function addCasters(array $casters) + { + foreach ($casters as $type => $callback) { + $this->casters[strtolower($type)][] = $callback; + } + } - if ($this->prevErrorHandler) { - return call_user_func($this->prevErrorHandler, $type, $msg, $file, $line, $context); - } + /** + * Sets the maximum number of items to clone past the first level in nested structures. + * + * @param int $maxItems + */ + public function setMaxItems($maxItems) + { + $this->maxItems = (int) $maxItems; + } - return false; - }); - $this->filter = $filter; + /** + * Sets the maximum cloned length for strings. + * + * @param int $maxString + */ + public function setMaxString($maxString) + { + $this->maxString = (int) $maxString; + } - try { - $data = $this->doClone($var); - } catch (\Exception $e) { - } - restore_error_handler(); - $this->prevErrorHandler = null; + /** + * Clones a PHP variable. + * + * @param mixed $var Any PHP variable + * @param int $filter A bit field of Caster::EXCLUDE_* constants + * + * @return Data The cloned variable represented by a Data object + */ + public function cloneVar($var, $filter = 0) + { + $this->prevErrorHandler = set_error_handler(function ($type, $msg, $file, $line, $context) { + if (E_RECOVERABLE_ERROR === $type || E_USER_ERROR === $type) { + // Cloner never dies + throw new \ErrorException($msg, 0, $type, $file, $line); + } - if (isset($e)) { - throw $e; - } + if ($this->prevErrorHandler) { + return call_user_func($this->prevErrorHandler, $type, $msg, $file, $line, $context); + } - return new Data($data); - } + return false; + }); + $this->filter = $filter; - /** - * Effectively clones the PHP variable. - * - * @param mixed $var Any PHP variable. - * - * @return array The cloned variable represented in an array. - */ - abstract protected function doClone($var); + try { + $data = $this->doClone($var); + } catch (\Exception $e) { + } + restore_error_handler(); + $this->prevErrorHandler = null; - /** - * Casts an object to an array representation. - * - * @param Stub $stub The Stub for the casted object. - * @param bool $isNested True if the object is nested in the dumped structure. - * - * @return array The object casted as array. - */ - protected function castObject(Stub $stub, $isNested) - { - $obj = $stub->value; - $class = $stub->class; + if (isset($e)) { + throw $e; + } - if (isset($class[15]) && "\0" === $class[15] && 0 === strpos($class, "class@anonymous\x00")) { - $stub->class = get_parent_class($class).'@anonymous'; - } - if (isset($this->classInfo[$class])) { - $classInfo = $this->classInfo[$class]; - } else { - $classInfo = array( - new \ReflectionClass($class), - array_reverse(array($class => $class) + class_parents($class) + class_implements($class) + array('*' => '*')), - ); + return new Data($data); + } - $this->classInfo[$class] = $classInfo; - } + /** + * Effectively clones the PHP variable. + * + * @param mixed $var Any PHP variable + * + * @return array The cloned variable represented in an array + */ + abstract protected function doClone($var); - $a = $this->callCaster('Symfony\Component\VarDumper\Caster\Caster::castObject', $obj, $classInfo[0], null, $isNested); + /** + * Casts an object to an array representation. + * + * @param Stub $stub The Stub for the casted object + * @param bool $isNested True if the object is nested in the dumped structure + * + * @return array The object casted as array + */ + protected function castObject(Stub $stub, $isNested) + { + $obj = $stub->value; + $class = $stub->class; - foreach ($classInfo[1] as $p) { - if (!empty($this->casters[$p = strtolower($p)])) { - foreach ($this->casters[$p] as $p) { - $a = $this->callCaster($p, $obj, $a, $stub, $isNested); - } - } - } + if (isset($class[15]) && "\0" === $class[15] && 0 === strpos($class, "class@anonymous\x00")) { + $stub->class = get_parent_class($class).'@anonymous'; + } + if (isset($this->classInfo[$class])) { + $classInfo = $this->classInfo[$class]; + } else { + $classInfo = array( + new \ReflectionClass($class), + array_reverse(array($class => $class) + class_parents($class) + class_implements($class) + array('*' => '*')), + ); + $classInfo[1] = array_map('strtolower', $classInfo[1]); - return $a; - } + $this->classInfo[$class] = $classInfo; + } - /** - * Casts a resource to an array representation. - * - * @param Stub $stub The Stub for the casted resource. - * @param bool $isNested True if the object is nested in the dumped structure. - * - * @return array The resource casted as array. - */ - protected function castResource(Stub $stub, $isNested) - { - $a = array(); - $res = $stub->value; - $type = $stub->class; + $a = Caster::castObject($obj, $classInfo[0]); - if (!empty($this->casters[':'.$type])) { - foreach ($this->casters[':'.$type] as $c) { - $a = $this->callCaster($c, $res, $a, $stub, $isNested); - } - } + foreach ($classInfo[1] as $p) { + if (!empty($this->casters[$p])) { + foreach ($this->casters[$p] as $p) { + $a = $this->callCaster($p, $obj, $a, $stub, $isNested); + } + } + } - return $a; - } + return $a; + } - /** - * Calls a custom caster. - * - * @param callable $callback The caster. - * @param object|resource $obj The object/resource being casted. - * @param array $a The result of the previous cast for chained casters. - * @param Stub $stub The Stub for the casted object/resource. - * @param bool $isNested True if $obj is nested in the dumped structure. - * - * @return array The casted object/resource. - */ - private function callCaster($callback, $obj, $a, $stub, $isNested) - { - try { - $cast = call_user_func($callback, $obj, $a, $stub, $isNested, $this->filter); + /** + * Casts a resource to an array representation. + * + * @param Stub $stub The Stub for the casted resource + * @param bool $isNested True if the object is nested in the dumped structure + * + * @return array The resource casted as array + */ + protected function castResource(Stub $stub, $isNested) + { + $a = array(); + $res = $stub->value; + $type = $stub->class; - if (is_array($cast)) { - $a = $cast; - } - } catch (\Exception $e) { - $a[(Stub::TYPE_OBJECT === $stub->type ? Caster::PREFIX_VIRTUAL : '').'⚠'] = new ThrowingCasterException($e); - } + if (!empty($this->casters[':'.$type])) { + foreach ($this->casters[':'.$type] as $c) { + $a = $this->callCaster($c, $res, $a, $stub, $isNested); + } + } - return $a; - } + return $a; + } + + /** + * Calls a custom caster. + * + * @param callable $callback The caster + * @param object|resource $obj The object/resource being casted + * @param array $a The result of the previous cast for chained casters + * @param Stub $stub The Stub for the casted object/resource + * @param bool $isNested True if $obj is nested in the dumped structure + * + * @return array The casted object/resource + */ + private function callCaster($callback, $obj, $a, $stub, $isNested) + { + try { + $cast = call_user_func($callback, $obj, $a, $stub, $isNested, $this->filter); + + if (is_array($cast)) { + $a = $cast; + } + } catch (\Exception $e) { + $a = array((Stub::TYPE_OBJECT === $stub->type ? Caster::PREFIX_VIRTUAL : '').'⚠' => new ThrowingCasterException($e)) + $a; + } + + return $a; + } } diff --git a/htdocs/includes/symfony/var-dumper/Cloner/ClonerInterface.php b/htdocs/includes/symfony/var-dumper/Cloner/ClonerInterface.php index c1df5933dbf..09d863e8e6f 100644 --- a/htdocs/includes/symfony/var-dumper/Cloner/ClonerInterface.php +++ b/htdocs/includes/symfony/var-dumper/Cloner/ClonerInterface.php @@ -16,12 +16,12 @@ namespace Symfony\Component\VarDumper\Cloner; */ interface ClonerInterface { - /** - * Clones a PHP variable. - * - * @param mixed $var Any PHP variable. - * - * @return Data The cloned variable represented by a Data object. - */ - public function cloneVar($var); + /** + * Clones a PHP variable. + * + * @param mixed $var Any PHP variable + * + * @return Data The cloned variable represented by a Data object + */ + public function cloneVar($var); } diff --git a/htdocs/includes/symfony/var-dumper/Cloner/Cursor.php b/htdocs/includes/symfony/var-dumper/Cloner/Cursor.php index 162f3293cf2..23fe80977c6 100644 --- a/htdocs/includes/symfony/var-dumper/Cloner/Cursor.php +++ b/htdocs/includes/symfony/var-dumper/Cloner/Cursor.php @@ -18,24 +18,25 @@ namespace Symfony\Component\VarDumper\Cloner; */ class Cursor { - const HASH_INDEXED = Stub::ARRAY_INDEXED; - const HASH_ASSOC = Stub::ARRAY_ASSOC; - const HASH_OBJECT = Stub::TYPE_OBJECT; - const HASH_RESOURCE = Stub::TYPE_RESOURCE; + const HASH_INDEXED = Stub::ARRAY_INDEXED; + const HASH_ASSOC = Stub::ARRAY_ASSOC; + const HASH_OBJECT = Stub::TYPE_OBJECT; + const HASH_RESOURCE = Stub::TYPE_RESOURCE; - public $depth = 0; - public $refIndex = 0; - public $softRefTo = 0; - public $softRefCount = 0; - public $softRefHandle = 0; - public $hardRefTo = 0; - public $hardRefCount = 0; - public $hardRefHandle = 0; - public $hashType; - public $hashKey; - public $hashKeyIsBinary; - public $hashIndex = 0; - public $hashLength = 0; - public $hashCut = 0; - public $stop = false; + public $depth = 0; + public $refIndex = 0; + public $softRefTo = 0; + public $softRefCount = 0; + public $softRefHandle = 0; + public $hardRefTo = 0; + public $hardRefCount = 0; + public $hardRefHandle = 0; + public $hashType; + public $hashKey; + public $hashKeyIsBinary; + public $hashIndex = 0; + public $hashLength = 0; + public $hashCut = 0; + public $stop = false; + public $attr = array(); } diff --git a/htdocs/includes/symfony/var-dumper/Cloner/Data.php b/htdocs/includes/symfony/var-dumper/Cloner/Data.php index 43a7b67971e..c770f06a928 100644 --- a/htdocs/includes/symfony/var-dumper/Cloner/Data.php +++ b/htdocs/includes/symfony/var-dumper/Cloner/Data.php @@ -11,208 +11,260 @@ namespace Symfony\Component\VarDumper\Cloner; +use Symfony\Component\VarDumper\Caster\Caster; + /** * @author Nicolas Grekas */ class Data { - private $data; - private $maxDepth = 20; - private $maxItemsPerDepth = -1; - private $useRefHandles = -1; + private $data; + private $position = 0; + private $key = 0; + private $maxDepth = 20; + private $maxItemsPerDepth = -1; + private $useRefHandles = -1; - /** - * @param array $data A array as returned by ClonerInterface::cloneVar(). - */ - public function __construct(array $data) - { - $this->data = $data; - } + /** + * @param array $data A array as returned by ClonerInterface::cloneVar() + */ + public function __construct(array $data) + { + $this->data = $data; + } - /** - * @return array The raw data structure. - */ - public function getRawData() - { - return $this->data; - } + /** + * @return array The raw data structure + */ + public function getRawData() + { + return $this->data; + } - /** - * Returns a depth limited clone of $this. - * - * @param int $maxDepth The max dumped depth level. - * - * @return self A clone of $this. - */ - public function withMaxDepth($maxDepth) - { - $data = clone $this; - $data->maxDepth = (int) $maxDepth; + /** + * Returns a depth limited clone of $this. + * + * @param int $maxDepth The max dumped depth level + * + * @return self A clone of $this + */ + public function withMaxDepth($maxDepth) + { + $data = clone $this; + $data->maxDepth = (int) $maxDepth; - return $data; - } + return $data; + } - /** - * Limits the numbers of elements per depth level. - * - * @param int $maxItemsPerDepth The max number of items dumped per depth level. - * - * @return self A clone of $this. - */ - public function withMaxItemsPerDepth($maxItemsPerDepth) - { - $data = clone $this; - $data->maxItemsPerDepth = (int) $maxItemsPerDepth; + /** + * Limits the number of elements per depth level. + * + * @param int $maxItemsPerDepth The max number of items dumped per depth level + * + * @return self A clone of $this + */ + public function withMaxItemsPerDepth($maxItemsPerDepth) + { + $data = clone $this; + $data->maxItemsPerDepth = (int) $maxItemsPerDepth; - return $data; - } + return $data; + } - /** - * Enables/disables objects' identifiers tracking. - * - * @param bool $useRefHandles False to hide global ref. handles. - * - * @return self A clone of $this. - */ - public function withRefHandles($useRefHandles) - { - $data = clone $this; - $data->useRefHandles = $useRefHandles ? -1 : 0; + /** + * Enables/disables objects' identifiers tracking. + * + * @param bool $useRefHandles False to hide global ref. handles + * + * @return self A clone of $this + */ + public function withRefHandles($useRefHandles) + { + $data = clone $this; + $data->useRefHandles = $useRefHandles ? -1 : 0; - return $data; - } + return $data; + } - /** - * Dumps data with a DumperInterface dumper. - */ - public function dump(DumperInterface $dumper) - { - $refs = array(0); - $this->dumpItem($dumper, new Cursor(), $refs, $this->data[0][0]); - } + /** + * Seeks to a specific key in nested data structures. + * + * @param string|int $key The key to seek to + * + * @return self|null A clone of $this of null if the key is not set + */ + public function seek($key) + { + $item = $this->data[$this->position][$this->key]; - /** - * Depth-first dumping of items. - * - * @param DumperInterface $dumper The dumper being used for dumping. - * @param Cursor $cursor A cursor used for tracking dumper state position. - * @param array &$refs A map of all references discovered while dumping. - * @param mixed $item A Stub object or the original value being dumped. - */ - private function dumpItem($dumper, $cursor, &$refs, $item) - { - $cursor->refIndex = 0; - $cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0; - $cursor->hardRefTo = $cursor->hardRefHandle = $cursor->hardRefCount = 0; - $firstSeen = true; + if (!$item instanceof Stub || !$item->position) { + return; + } + $keys = array($key); - if (!$item instanceof Stub) { - $type = gettype($item); - } elseif (Stub::TYPE_REF === $item->type) { - if ($item->handle) { - if (!isset($refs[$r = $item->handle - (PHP_INT_MAX >> 1)])) { - $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0]; - } else { - $firstSeen = false; - } - $cursor->hardRefTo = $refs[$r]; - $cursor->hardRefHandle = $this->useRefHandles & $item->handle; - $cursor->hardRefCount = $item->refCount; - } - $type = $item->class ?: gettype($item->value); - $item = $item->value; - } - if ($item instanceof Stub) { - if ($item->refCount) { - if (!isset($refs[$r = $item->handle])) { - $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0]; - } else { - $firstSeen = false; - } - $cursor->softRefTo = $refs[$r]; - } - $cursor->softRefHandle = $this->useRefHandles & $item->handle; - $cursor->softRefCount = $item->refCount; - $cut = $item->cut; + switch ($item->type) { + case Stub::TYPE_OBJECT: + $keys[] = Caster::PREFIX_DYNAMIC.$key; + $keys[] = Caster::PREFIX_PROTECTED.$key; + $keys[] = Caster::PREFIX_VIRTUAL.$key; + $keys[] = "\0$item->class\0$key"; + case Stub::TYPE_ARRAY: + case Stub::TYPE_RESOURCE: + break; + default: + return; + } - if ($item->position && $firstSeen) { - $children = $this->data[$item->position]; + $data = null; + $children = $this->data[$item->position]; - if ($cursor->stop) { - if ($cut >= 0) { - $cut += count($children); - } - $children = array(); - } - } else { - $children = array(); - } - switch ($item->type) { - case Stub::TYPE_STRING: - $dumper->dumpString($cursor, $item->value, Stub::STRING_BINARY === $item->class, $cut); - break; + foreach ($keys as $key) { + if (isset($children[$key]) || array_key_exists($key, $children)) { + $data = clone $this; + $data->key = $key; + $data->position = $item->position; + break; + } + } - case Stub::TYPE_ARRAY: - $item = clone $item; - $item->type = $item->class; - $item->class = $item->value; - // No break; - case Stub::TYPE_OBJECT: - case Stub::TYPE_RESOURCE: - $withChildren = $children && $cursor->depth !== $this->maxDepth && $this->maxItemsPerDepth; - $dumper->enterHash($cursor, $item->type, $item->class, $withChildren); - if ($withChildren) { - $cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type); - } elseif ($children && 0 <= $cut) { - $cut += count($children); - } - $dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut); - break; + return $data; + } - default: - throw new \RuntimeException(sprintf('Unexpected Stub type: %s', $item->type)); - } - } elseif ('array' === $type) { - $dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false); - $dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0); - } elseif ('string' === $type) { - $dumper->dumpString($cursor, $item, false, 0); - } else { - $dumper->dumpScalar($cursor, $type, $item); - } - } + /** + * Dumps data with a DumperInterface dumper. + */ + public function dump(DumperInterface $dumper) + { + $refs = array(0); + $this->dumpItem($dumper, new Cursor(), $refs, $this->data[$this->position][$this->key]); + } - /** - * Dumps children of hash structures. - * - * @param DumperInterface $dumper - * @param Cursor $parentCursor The cursor of the parent hash. - * @param array &$refs A map of all references discovered while dumping. - * @param array $children The children to dump. - * @param int $hashCut The number of items removed from the original hash. - * @param string $hashType A Cursor::HASH_* const. - * - * @return int The final number of removed items. - */ - private function dumpChildren($dumper, $parentCursor, &$refs, $children, $hashCut, $hashType) - { - $cursor = clone $parentCursor; - ++$cursor->depth; - $cursor->hashType = $hashType; - $cursor->hashIndex = 0; - $cursor->hashLength = count($children); - $cursor->hashCut = $hashCut; - foreach ($children as $key => $child) { - $cursor->hashKeyIsBinary = isset($key[0]) && !preg_match('//u', $key); - $cursor->hashKey = $key; - $this->dumpItem($dumper, $cursor, $refs, $child); - if (++$cursor->hashIndex === $this->maxItemsPerDepth || $cursor->stop) { - $parentCursor->stop = true; + /** + * Depth-first dumping of items. + * + * @param DumperInterface $dumper The dumper being used for dumping + * @param Cursor $cursor A cursor used for tracking dumper state position + * @param array &$refs A map of all references discovered while dumping + * @param mixed $item A Stub object or the original value being dumped + */ + private function dumpItem($dumper, $cursor, &$refs, $item) + { + $cursor->refIndex = 0; + $cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0; + $cursor->hardRefTo = $cursor->hardRefHandle = $cursor->hardRefCount = 0; + $firstSeen = true; - return $hashCut >= 0 ? $hashCut + $cursor->hashLength - $cursor->hashIndex : $hashCut; - } - } + if (!$item instanceof Stub) { + $cursor->attr = array(); + $type = gettype($item); + } elseif (Stub::TYPE_REF === $item->type) { + if ($item->handle) { + if (!isset($refs[$r = $item->handle - (PHP_INT_MAX >> 1)])) { + $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0]; + } else { + $firstSeen = false; + } + $cursor->hardRefTo = $refs[$r]; + $cursor->hardRefHandle = $this->useRefHandles & $item->handle; + $cursor->hardRefCount = $item->refCount; + } + $cursor->attr = $item->attr; + $type = $item->class ?: gettype($item->value); + $item = $item->value; + } + if ($item instanceof Stub) { + if ($item->refCount) { + if (!isset($refs[$r = $item->handle])) { + $cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0]; + } else { + $firstSeen = false; + } + $cursor->softRefTo = $refs[$r]; + } + $cursor->softRefHandle = $this->useRefHandles & $item->handle; + $cursor->softRefCount = $item->refCount; + $cursor->attr = $item->attr; + $cut = $item->cut; - return $hashCut; - } + if ($item->position && $firstSeen) { + $children = $this->data[$item->position]; + + if ($cursor->stop) { + if ($cut >= 0) { + $cut += count($children); + } + $children = array(); + } + } else { + $children = array(); + } + switch ($item->type) { + case Stub::TYPE_STRING: + $dumper->dumpString($cursor, $item->value, Stub::STRING_BINARY === $item->class, $cut); + break; + + case Stub::TYPE_ARRAY: + $item = clone $item; + $item->type = $item->class; + $item->class = $item->value; + // No break; + case Stub::TYPE_OBJECT: + case Stub::TYPE_RESOURCE: + $withChildren = $children && $cursor->depth !== $this->maxDepth && $this->maxItemsPerDepth; + $dumper->enterHash($cursor, $item->type, $item->class, $withChildren); + if ($withChildren) { + $cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type, null !== $item->class); + } elseif ($children && 0 <= $cut) { + $cut += count($children); + } + $dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut); + break; + + default: + throw new \RuntimeException(sprintf('Unexpected Stub type: %s', $item->type)); + } + } elseif ('array' === $type) { + $dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false); + $dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0); + } elseif ('string' === $type) { + $dumper->dumpString($cursor, $item, false, 0); + } else { + $dumper->dumpScalar($cursor, $type, $item); + } + } + + /** + * Dumps children of hash structures. + * + * @param DumperInterface $dumper + * @param Cursor $parentCursor The cursor of the parent hash + * @param array &$refs A map of all references discovered while dumping + * @param array $children The children to dump + * @param int $hashCut The number of items removed from the original hash + * @param string $hashType A Cursor::HASH_* const + * @param bool $dumpKeys Whether keys should be dumped or not + * + * @return int The final number of removed items + */ + private function dumpChildren($dumper, $parentCursor, &$refs, $children, $hashCut, $hashType, $dumpKeys) + { + $cursor = clone $parentCursor; + ++$cursor->depth; + $cursor->hashType = $hashType; + $cursor->hashIndex = 0; + $cursor->hashLength = count($children); + $cursor->hashCut = $hashCut; + foreach ($children as $key => $child) { + $cursor->hashKeyIsBinary = isset($key[0]) && !preg_match('//u', $key); + $cursor->hashKey = $dumpKeys ? $key : null; + $this->dumpItem($dumper, $cursor, $refs, $child); + if (++$cursor->hashIndex === $this->maxItemsPerDepth || $cursor->stop) { + $parentCursor->stop = true; + + return $hashCut >= 0 ? $hashCut + $cursor->hashLength - $cursor->hashIndex : $hashCut; + } + } + + return $hashCut; + } } diff --git a/htdocs/includes/symfony/var-dumper/Cloner/DumperInterface.php b/htdocs/includes/symfony/var-dumper/Cloner/DumperInterface.php index eba23d42297..8f647a7e5a7 100644 --- a/htdocs/includes/symfony/var-dumper/Cloner/DumperInterface.php +++ b/htdocs/includes/symfony/var-dumper/Cloner/DumperInterface.php @@ -18,43 +18,43 @@ namespace Symfony\Component\VarDumper\Cloner; */ interface DumperInterface { - /** - * Dumps a scalar value. - * - * @param Cursor $cursor The Cursor position in the dump. - * @param string $type The PHP type of the value being dumped. - * @param scalar $value The scalar value being dumped. - */ - public function dumpScalar(Cursor $cursor, $type, $value); + /** + * Dumps a scalar value. + * + * @param Cursor $cursor The Cursor position in the dump + * @param string $type The PHP type of the value being dumped + * @param scalar $value The scalar value being dumped + */ + public function dumpScalar(Cursor $cursor, $type, $value); - /** - * Dumps a string. - * - * @param Cursor $cursor The Cursor position in the dump. - * @param string $str The string being dumped. - * @param bool $bin Whether $str is UTF-8 or binary encoded. - * @param int $cut The number of characters $str has been cut by. - */ - public function dumpString(Cursor $cursor, $str, $bin, $cut); + /** + * Dumps a string. + * + * @param Cursor $cursor The Cursor position in the dump + * @param string $str The string being dumped + * @param bool $bin Whether $str is UTF-8 or binary encoded + * @param int $cut The number of characters $str has been cut by + */ + public function dumpString(Cursor $cursor, $str, $bin, $cut); - /** - * Dumps while entering an hash. - * - * @param Cursor $cursor The Cursor position in the dump. - * @param int $type A Cursor::HASH_* const for the type of hash. - * @param string $class The object class, resource type or array count. - * @param bool $hasChild When the dump of the hash has child item. - */ - public function enterHash(Cursor $cursor, $type, $class, $hasChild); + /** + * Dumps while entering an hash. + * + * @param Cursor $cursor The Cursor position in the dump + * @param int $type A Cursor::HASH_* const for the type of hash + * @param string $class The object class, resource type or array count + * @param bool $hasChild When the dump of the hash has child item + */ + public function enterHash(Cursor $cursor, $type, $class, $hasChild); - /** - * Dumps while leaving an hash. - * - * @param Cursor $cursor The Cursor position in the dump. - * @param int $type A Cursor::HASH_* const for the type of hash. - * @param string $class The object class, resource type or array count. - * @param bool $hasChild When the dump of the hash has child item. - * @param int $cut The number of items the hash has been cut by. - */ - public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut); + /** + * Dumps while leaving an hash. + * + * @param Cursor $cursor The Cursor position in the dump + * @param int $type A Cursor::HASH_* const for the type of hash + * @param string $class The object class, resource type or array count + * @param bool $hasChild When the dump of the hash has child item + * @param int $cut The number of items the hash has been cut by + */ + public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut); } diff --git a/htdocs/includes/symfony/var-dumper/Cloner/Stub.php b/htdocs/includes/symfony/var-dumper/Cloner/Stub.php index f58a57a7276..8ee0f23b75e 100644 --- a/htdocs/includes/symfony/var-dumper/Cloner/Stub.php +++ b/htdocs/includes/symfony/var-dumper/Cloner/Stub.php @@ -18,23 +18,24 @@ namespace Symfony\Component\VarDumper\Cloner; */ class Stub { - const TYPE_REF = 'ref'; - const TYPE_STRING = 'string'; - const TYPE_ARRAY = 'array'; - const TYPE_OBJECT = 'object'; - const TYPE_RESOURCE = 'resource'; + const TYPE_REF = 'ref'; + const TYPE_STRING = 'string'; + const TYPE_ARRAY = 'array'; + const TYPE_OBJECT = 'object'; + const TYPE_RESOURCE = 'resource'; - const STRING_BINARY = 'bin'; - const STRING_UTF8 = 'utf8'; + const STRING_BINARY = 'bin'; + const STRING_UTF8 = 'utf8'; - const ARRAY_ASSOC = 'assoc'; - const ARRAY_INDEXED = 'indexed'; + const ARRAY_ASSOC = 'assoc'; + const ARRAY_INDEXED = 'indexed'; - public $type = self::TYPE_REF; - public $class = ''; - public $value; - public $cut = 0; - public $handle = 0; - public $refCount = 0; - public $position = 0; + public $type = self::TYPE_REF; + public $class = ''; + public $value; + public $cut = 0; + public $handle = 0; + public $refCount = 0; + public $position = 0; + public $attr = array(); } diff --git a/htdocs/includes/symfony/var-dumper/Cloner/VarCloner.php b/htdocs/includes/symfony/var-dumper/Cloner/VarCloner.php index 98d6e9e51c1..caadfe05e7d 100644 --- a/htdocs/includes/symfony/var-dumper/Cloner/VarCloner.php +++ b/htdocs/includes/symfony/var-dumper/Cloner/VarCloner.php @@ -16,285 +16,311 @@ namespace Symfony\Component\VarDumper\Cloner; */ class VarCloner extends AbstractCloner { - private static $hashMask = 0; - private static $hashOffset = 0; + private static $hashMask = 0; + private static $hashOffset = 0; - /** - * {@inheritdoc} - */ - protected function doClone($var) - { - $useExt = $this->useExt; - $i = 0; // Current iteration position in $queue - $len = 1; // Length of $queue - $pos = 0; // Number of cloned items past the first level - $refs = 0; // Hard references counter - $queue = array(array($var)); // This breadth-first queue is the return value - $arrayRefs = array(); // Map of queue indexes to stub array objects - $hardRefs = array(); // Map of original zval hashes to stub objects - $objRefs = array(); // Map of original object handles to their stub object couterpart - $resRefs = array(); // Map of original resource handles to their stub object couterpart - $values = array(); // Map of stub objects' hashes to original values - $maxItems = $this->maxItems; - $maxString = $this->maxString; - $cookie = (object) array(); // Unique object used to detect hard references - $gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable - $a = null; // Array cast for nested structures - $stub = null; // Stub capturing the main properties of an original item value - // or null if the original value is used directly - $zval = array( // Main properties of the current value - 'type' => null, - 'zval_isref' => null, - 'zval_hash' => null, - 'array_count' => null, - 'object_class' => null, - 'object_handle' => null, - 'resource_type' => null, - ); - if (!self::$hashMask) { - self::initHashMask(); - } - $hashMask = self::$hashMask; - $hashOffset = self::$hashOffset; + /** + * {@inheritdoc} + */ + protected function doClone($var) + { + $useExt = $this->useExt; + $len = 1; // Length of $queue + $pos = 0; // Number of cloned items past the first level + $refsCounter = 0; // Hard references counter + $queue = array(array($var)); // This breadth-first queue is the return value + $arrayRefs = array(); // Map of queue indexes to stub array objects + $hardRefs = array(); // Map of original zval hashes to stub objects + $objRefs = array(); // Map of original object handles to their stub object couterpart + $resRefs = array(); // Map of original resource handles to their stub object couterpart + $values = array(); // Map of stub objects' hashes to original values + $maxItems = $this->maxItems; + $maxString = $this->maxString; + $cookie = (object) array(); // Unique object used to detect hard references + $gid = uniqid(mt_rand(), true); // Unique string used to detect the special $GLOBALS variable + $a = null; // Array cast for nested structures + $stub = null; // Stub capturing the main properties of an original item value + // or null if the original value is used directly + $zval = array( // Main properties of the current value + 'type' => null, + 'zval_isref' => null, + 'zval_hash' => null, + 'array_count' => null, + 'object_class' => null, + 'object_handle' => null, + 'resource_type' => null, + ); + if (!self::$hashMask) { + self::initHashMask(); + } + $hashMask = self::$hashMask; + $hashOffset = self::$hashOffset; - for ($i = 0; $i < $len; ++$i) { - $indexed = true; // Whether the currently iterated array is numerically indexed or not - $j = -1; // Position in the currently iterated array - $step = $queue[$i]; // Copy of the currently iterated array used for hard references detection - foreach ($step as $k => $v) { - // $k is the original key - // $v is the original value or a stub object in case of hard references - if ($indexed && $k !== ++$j) { - $indexed = false; - } - if ($useExt) { - $zval = symfony_zval_info($k, $step); - } else { - $step[$k] = $cookie; - if ($zval['zval_isref'] = $queue[$i][$k] === $cookie) { - $zval['zval_hash'] = $v instanceof Stub ? spl_object_hash($v) : null; - } - $zval['type'] = gettype($v); - } - if ($zval['zval_isref']) { - $queue[$i][$k] = &$stub; // Break hard references to make $queue completely - unset($stub); // independent from the original structure - if (isset($hardRefs[$zval['zval_hash']])) { - $queue[$i][$k] = $useExt ? ($v = $hardRefs[$zval['zval_hash']]) : ($step[$k] = $v); - if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) { - ++$v->value->refCount; - } - ++$v->refCount; - continue; - } - } - // Create $stub when the original value $v can not be used directly - // If $v is a nested structure, put that structure in array $a - switch ($zval['type']) { - case 'string': - if (isset($v[0]) && !preg_match('//u', $v)) { - $stub = new Stub(); - $stub->type = Stub::TYPE_STRING; - $stub->class = Stub::STRING_BINARY; - if (0 <= $maxString && 0 < $cut = strlen($v) - $maxString) { - $stub->cut = $cut; - $stub->value = substr($v, 0, -$cut); - } else { - $stub->value = $v; - } - } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = iconv_strlen($v, 'UTF-8') - $maxString) { - $stub = new Stub(); - $stub->type = Stub::TYPE_STRING; - $stub->class = Stub::STRING_UTF8; - $stub->cut = $cut; - $stub->value = iconv_substr($v, 0, $maxString, 'UTF-8'); - } - break; + for ($i = 0; $i < $len; ++$i) { + $indexed = true; // Whether the currently iterated array is numerically indexed or not + $j = -1; // Position in the currently iterated array + $fromObjCast = array_keys($queue[$i]); + $fromObjCast = array_keys(array_flip($fromObjCast)) !== $fromObjCast; + $refs = $vals = $fromObjCast ? array_values($queue[$i]) : $queue[$i]; + foreach ($queue[$i] as $k => $v) { + // $k is the original key + // $v is the original value or a stub object in case of hard references + if ($k !== ++$j) { + $indexed = false; + } + if ($fromObjCast) { + $k = $j; + } + if ($useExt) { + $zval = symfony_zval_info($k, $refs); + } else { + $refs[$k] = $cookie; + if ($zval['zval_isref'] = $vals[$k] === $cookie) { + $zval['zval_hash'] = $v instanceof Stub ? spl_object_hash($v) : null; + } + $zval['type'] = gettype($v); + } + if ($zval['zval_isref']) { + $vals[$k] = &$stub; // Break hard references to make $queue completely + unset($stub); // independent from the original structure + if (isset($hardRefs[$zval['zval_hash']])) { + $vals[$k] = $useExt ? ($v = $hardRefs[$zval['zval_hash']]) : ($refs[$k] = $v); + if ($v->value instanceof Stub && (Stub::TYPE_OBJECT === $v->value->type || Stub::TYPE_RESOURCE === $v->value->type)) { + ++$v->value->refCount; + } + ++$v->refCount; + continue; + } + } + // Create $stub when the original value $v can not be used directly + // If $v is a nested structure, put that structure in array $a + switch ($zval['type']) { + case 'string': + if (isset($v[0]) && !preg_match('//u', $v)) { + $stub = new Stub(); + $stub->type = Stub::TYPE_STRING; + $stub->class = Stub::STRING_BINARY; + if (0 <= $maxString && 0 < $cut = strlen($v) - $maxString) { + $stub->cut = $cut; + $stub->value = substr($v, 0, -$cut); + } else { + $stub->value = $v; + } + } elseif (0 <= $maxString && isset($v[1 + ($maxString >> 2)]) && 0 < $cut = mb_strlen($v, 'UTF-8') - $maxString) { + $stub = new Stub(); + $stub->type = Stub::TYPE_STRING; + $stub->class = Stub::STRING_UTF8; + $stub->cut = $cut; + $stub->value = mb_substr($v, 0, $maxString, 'UTF-8'); + } + break; - case 'integer': - break; + case 'integer': + break; - case 'array': - if ($v) { - $stub = $arrayRefs[$len] = new Stub(); - $stub->type = Stub::TYPE_ARRAY; - $stub->class = Stub::ARRAY_ASSOC; + case 'array': + if ($v) { + $stub = $arrayRefs[$len] = new Stub(); + $stub->type = Stub::TYPE_ARRAY; + $stub->class = Stub::ARRAY_ASSOC; - // Copies of $GLOBALS have very strange behavior, - // let's detect them with some black magic - $a = $v; - $a[$gid] = true; + // Copies of $GLOBALS have very strange behavior, + // let's detect them with some black magic + $a = $v; + $a[$gid] = true; - // Happens with copies of $GLOBALS - if (isset($v[$gid])) { - unset($v[$gid]); - $a = array(); - foreach ($v as $gk => &$gv) { - $a[$gk] = &$gv; - } - } else { - $a = $v; - } + // Happens with copies of $GLOBALS + if (isset($v[$gid])) { + unset($v[$gid]); + $a = array(); + foreach ($v as $gk => &$gv) { + $a[$gk] = &$gv; + } + } else { + $a = $v; + } - $stub->value = $zval['array_count'] ?: count($a); - } - break; + $stub->value = $zval['array_count'] ?: count($a); + } + break; - case 'object': - if (empty($objRefs[$h = $zval['object_handle'] ?: ($hashMask ^ hexdec(substr(spl_object_hash($v), $hashOffset, PHP_INT_SIZE)))])) { - $stub = new Stub(); - $stub->type = Stub::TYPE_OBJECT; - $stub->class = $zval['object_class'] ?: get_class($v); - $stub->value = $v; - $stub->handle = $h; - $a = $this->castObject($stub, 0 < $i); - if ($v !== $stub->value) { - if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) { - break; - } - if ($useExt) { - $zval['type'] = $stub->value; - $zval = symfony_zval_info('type', $zval); - $h = $zval['object_handle']; - } else { - $h = $hashMask ^ hexdec(substr(spl_object_hash($stub->value), $hashOffset, PHP_INT_SIZE)); - } - $stub->handle = $h; - } - $stub->value = null; - if (0 <= $maxItems && $maxItems <= $pos) { - $stub->cut = count($a); - $a = null; - } - } - if (empty($objRefs[$h])) { - $objRefs[$h] = $stub; - } else { - $stub = $objRefs[$h]; - ++$stub->refCount; - $a = null; - } - break; + case 'object': + if (empty($objRefs[$h = $zval['object_handle'] ?: ($hashMask ^ hexdec(substr(spl_object_hash($v), $hashOffset, PHP_INT_SIZE)))])) { + $stub = new Stub(); + $stub->type = Stub::TYPE_OBJECT; + $stub->class = $zval['object_class'] ?: get_class($v); + $stub->value = $v; + $stub->handle = $h; + $a = $this->castObject($stub, 0 < $i); + if ($v !== $stub->value) { + if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) { + break; + } + if ($useExt) { + $zval['type'] = $stub->value; + $zval = symfony_zval_info('type', $zval); + $h = $zval['object_handle']; + } else { + $h = $hashMask ^ hexdec(substr(spl_object_hash($stub->value), $hashOffset, PHP_INT_SIZE)); + } + $stub->handle = $h; + } + $stub->value = null; + if (0 <= $maxItems && $maxItems <= $pos) { + $stub->cut = count($a); + $a = null; + } + } + if (empty($objRefs[$h])) { + $objRefs[$h] = $stub; + } else { + $stub = $objRefs[$h]; + ++$stub->refCount; + $a = null; + } + break; - case 'resource': - case 'unknown type': - if (empty($resRefs[$h = (int) $v])) { - $stub = new Stub(); - $stub->type = Stub::TYPE_RESOURCE; - $stub->class = $zval['resource_type'] ?: get_resource_type($v); - $stub->value = $v; - $stub->handle = $h; - $a = $this->castResource($stub, 0 < $i); - $stub->value = null; - if (0 <= $maxItems && $maxItems <= $pos) { - $stub->cut = count($a); - $a = null; - } - } - if (empty($resRefs[$h])) { - $resRefs[$h] = $stub; - } else { - $stub = $resRefs[$h]; - ++$stub->refCount; - $a = null; - } - break; - } + case 'resource': + case 'unknown type': + case 'resource (closed)': + if (empty($resRefs[$h = (int) $v])) { + $stub = new Stub(); + $stub->type = Stub::TYPE_RESOURCE; + if ('Unknown' === $stub->class = $zval['resource_type'] ?: @get_resource_type($v)) { + $stub->class = 'Closed'; + } + $stub->value = $v; + $stub->handle = $h; + $a = $this->castResource($stub, 0 < $i); + $stub->value = null; + if (0 <= $maxItems && $maxItems <= $pos) { + $stub->cut = count($a); + $a = null; + } + } + if (empty($resRefs[$h])) { + $resRefs[$h] = $stub; + } else { + $stub = $resRefs[$h]; + ++$stub->refCount; + $a = null; + } + break; + } - if (isset($stub)) { - if ($zval['zval_isref']) { - if ($useExt) { - $queue[$i][$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub(); - $v->value = $stub; - } else { - $step[$k] = new Stub(); - $step[$k]->value = $stub; - $h = spl_object_hash($step[$k]); - $queue[$i][$k] = $hardRefs[$h] = &$step[$k]; - $values[$h] = $v; - } - $queue[$i][$k]->handle = ++$refs; - } else { - $queue[$i][$k] = $stub; - } + if (isset($stub)) { + if ($zval['zval_isref']) { + if ($useExt) { + $vals[$k] = $hardRefs[$zval['zval_hash']] = $v = new Stub(); + $v->value = $stub; + } else { + $refs[$k] = new Stub(); + $refs[$k]->value = $stub; + $h = spl_object_hash($refs[$k]); + $vals[$k] = $hardRefs[$h] = &$refs[$k]; + $values[$h] = $v; + } + $vals[$k]->handle = ++$refsCounter; + } else { + $vals[$k] = $stub; + } - if ($a) { - if ($i && 0 <= $maxItems) { - $k = count($a); - if ($pos < $maxItems) { - if ($maxItems < $pos += $k) { - $a = array_slice($a, 0, $maxItems - $pos); - if ($stub->cut >= 0) { - $stub->cut += $pos - $maxItems; - } - } - } else { - if ($stub->cut >= 0) { - $stub->cut += $k; - } - $stub = $a = null; - unset($arrayRefs[$len]); - continue; - } - } - $queue[$len] = $a; - $stub->position = $len++; - } - $stub = $a = null; - } elseif ($zval['zval_isref']) { - if ($useExt) { - $queue[$i][$k] = $hardRefs[$zval['zval_hash']] = new Stub(); - $queue[$i][$k]->value = $v; - } else { - $step[$k] = $queue[$i][$k] = new Stub(); - $step[$k]->value = $v; - $h = spl_object_hash($step[$k]); - $hardRefs[$h] = &$step[$k]; - $values[$h] = $v; - } - $queue[$i][$k]->handle = ++$refs; - } - } + if ($a) { + if ($i && 0 <= $maxItems) { + $k = count($a); + if ($pos < $maxItems) { + if ($maxItems < $pos += $k) { + $a = array_slice($a, 0, $maxItems - $pos); + if ($stub->cut >= 0) { + $stub->cut += $pos - $maxItems; + } + } + } else { + if ($stub->cut >= 0) { + $stub->cut += $k; + } + $stub = $a = null; + unset($arrayRefs[$len]); + continue; + } + } + $queue[$len] = $a; + $stub->position = $len++; + } + $stub = $a = null; + } elseif ($zval['zval_isref']) { + if ($useExt) { + $vals[$k] = $hardRefs[$zval['zval_hash']] = new Stub(); + $vals[$k]->value = $v; + } else { + $refs[$k] = $vals[$k] = new Stub(); + $refs[$k]->value = $v; + $h = spl_object_hash($refs[$k]); + $hardRefs[$h] = &$refs[$k]; + $values[$h] = $v; + } + $vals[$k]->handle = ++$refsCounter; + } + } - if (isset($arrayRefs[$i])) { - if ($indexed) { - $arrayRefs[$i]->class = Stub::ARRAY_INDEXED; - } - unset($arrayRefs[$i]); - } - } + if ($fromObjCast) { + $refs = $vals; + $vals = array(); + $j = -1; + foreach ($queue[$i] as $k => $v) { + foreach (array($k => $v) as $a => $v) { + } + if ($a !== $k) { + $vals = (object) $vals; + $vals->{$k} = $refs[++$j]; + $vals = (array) $vals; + } else { + $vals[$k] = $refs[++$j]; + } + } + } - foreach ($values as $h => $v) { - $hardRefs[$h] = $v; - } + $queue[$i] = $vals; - return $queue; - } + if (isset($arrayRefs[$i])) { + if ($indexed) { + $arrayRefs[$i]->class = Stub::ARRAY_INDEXED; + } + unset($arrayRefs[$i]); + } + } - private static function initHashMask() - { - $obj = (object) array(); - self::$hashOffset = 16 - PHP_INT_SIZE; - self::$hashMask = -1; + foreach ($values as $h => $v) { + $hardRefs[$h] = $v; + } - if (defined('HHVM_VERSION')) { - self::$hashOffset += 16; - } else { - // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below - $obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'); - foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) { - if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && in_array($frame['function'], $obFuncs)) { - $frame['line'] = 0; - break; - } - } - if (!empty($frame['line'])) { - ob_start(); - debug_zval_dump($obj); - self::$hashMask = substr(ob_get_clean(), 17); - } - } + return $queue; + } - self::$hashMask ^= hexdec(substr(spl_object_hash($obj), self::$hashOffset, PHP_INT_SIZE)); - } + private static function initHashMask() + { + $obj = (object) array(); + self::$hashOffset = 16 - PHP_INT_SIZE; + self::$hashMask = -1; + + if (defined('HHVM_VERSION')) { + self::$hashOffset += 16; + } else { + // check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below + $obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'); + foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) { + if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && in_array($frame['function'], $obFuncs)) { + $frame['line'] = 0; + break; + } + } + if (!empty($frame['line'])) { + ob_start(); + debug_zval_dump($obj); + self::$hashMask = (int) substr(ob_get_clean(), 17); + } + } + + self::$hashMask ^= hexdec(substr(spl_object_hash($obj), self::$hashOffset, PHP_INT_SIZE)); + } } diff --git a/htdocs/includes/symfony/var-dumper/Dumper/AbstractDumper.php b/htdocs/includes/symfony/var-dumper/Dumper/AbstractDumper.php index f8b9c107779..fb68a8908c4 100644 --- a/htdocs/includes/symfony/var-dumper/Dumper/AbstractDumper.php +++ b/htdocs/includes/symfony/var-dumper/Dumper/AbstractDumper.php @@ -21,156 +21,181 @@ use Symfony\Component\VarDumper\Cloner\DumperInterface; */ abstract class AbstractDumper implements DataDumperInterface, DumperInterface { - public static $defaultOutput = 'php://output'; + const DUMP_LIGHT_ARRAY = 1; + const DUMP_STRING_LENGTH = 2; - protected $line = ''; - protected $lineDumper; - protected $outputStream; - protected $decimalPoint; // This is locale dependent - protected $indentPad = ' '; + public static $defaultOutput = 'php://output'; - private $charset; + protected $line = ''; + protected $lineDumper; + protected $outputStream; + protected $decimalPoint; // This is locale dependent + protected $indentPad = ' '; + protected $flags; - /** - * @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput. - * @param string $charset The default character encoding to use for non-UTF8 strings. - */ - public function __construct($output = null, $charset = null) - { - $this->setCharset($charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8'); - $this->decimalPoint = (string) 0.5; - $this->decimalPoint = $this->decimalPoint[1]; - $this->setOutput($output ?: static::$defaultOutput); - if (!$output && is_string(static::$defaultOutput)) { - static::$defaultOutput = $this->outputStream; - } - } + private $charset; - /** - * Sets the output destination of the dumps. - * - * @param callable|resource|string $output A line dumper callable, an opened stream or an output path. - * - * @return callable|resource|string The previous output destination. - */ - public function setOutput($output) - { - $prev = null !== $this->outputStream ? $this->outputStream : $this->lineDumper; + /** + * @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path, defaults to static::$defaultOutput + * @param string $charset The default character encoding to use for non-UTF8 strings + * @param int $flags A bit field of static::DUMP_* constants to fine tune dumps representation + */ + public function __construct($output = null, $charset = null, $flags = 0) + { + $this->flags = (int) $flags; + $this->setCharset($charset ?: ini_get('php.output_encoding') ?: ini_get('default_charset') ?: 'UTF-8'); + $this->decimalPoint = localeconv(); + $this->decimalPoint = $this->decimalPoint['decimal_point']; + $this->setOutput($output ?: static::$defaultOutput); + if (!$output && is_string(static::$defaultOutput)) { + static::$defaultOutput = $this->outputStream; + } + } - if (is_callable($output)) { - $this->outputStream = null; - $this->lineDumper = $output; - } else { - if (is_string($output)) { - $output = fopen($output, 'wb'); - } - $this->outputStream = $output; - $this->lineDumper = array($this, 'echoLine'); - } + /** + * Sets the output destination of the dumps. + * + * @param callable|resource|string $output A line dumper callable, an opened stream or an output path + * + * @return callable|resource|string The previous output destination + */ + public function setOutput($output) + { + $prev = null !== $this->outputStream ? $this->outputStream : $this->lineDumper; - return $prev; - } + if (is_callable($output)) { + $this->outputStream = null; + $this->lineDumper = $output; + } else { + if (is_string($output)) { + $output = fopen($output, 'wb'); + } + $this->outputStream = $output; + $this->lineDumper = array($this, 'echoLine'); + } - /** - * Sets the default character encoding to use for non-UTF8 strings. - * - * @param string $charset The default character encoding to use for non-UTF8 strings. - * - * @return string The previous charset. - */ - public function setCharset($charset) - { - $prev = $this->charset; + return $prev; + } - $charset = strtoupper($charset); - $charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset; + /** + * Sets the default character encoding to use for non-UTF8 strings. + * + * @param string $charset The default character encoding to use for non-UTF8 strings + * + * @return string The previous charset + */ + public function setCharset($charset) + { + $prev = $this->charset; - $this->charset = $charset; + $charset = strtoupper($charset); + $charset = null === $charset || 'UTF-8' === $charset || 'UTF8' === $charset ? 'CP1252' : $charset; - return $prev; - } + $this->charset = $charset; - /** - * Sets the indentation pad string. - * - * @param string $pad A string the will be prepended to dumped lines, repeated by nesting level. - * - * @return string The indent pad. - */ - public function setIndentPad($pad) - { - $prev = $this->indentPad; - $this->indentPad = $pad; + return $prev; + } - return $prev; - } + /** + * Sets the indentation pad string. + * + * @param string $pad A string the will be prepended to dumped lines, repeated by nesting level + * + * @return string The indent pad + */ + public function setIndentPad($pad) + { + $prev = $this->indentPad; + $this->indentPad = $pad; - /** - * Dumps a Data object. - * - * @param Data $data A Data object. - * @param callable|resource|string|null $output A line dumper callable, an opened stream or an output path. - */ - public function dump(Data $data, $output = null) - { - $exception = null; - if ($output) { - $prevOutput = $this->setOutput($output); - } - try { - $data->dump($this); - $this->dumpLine(-1); - } catch (\Exception $exception) { - // Re-thrown below - } - if ($output) { - $this->setOutput($prevOutput); - } - if (null !== $exception) { - throw $exception; - } - } + return $prev; + } - /** - * Dumps the current line. - * - * @param int $depth The recursive depth in the dumped structure for the line being dumped. - */ - protected function dumpLine($depth) - { - call_user_func($this->lineDumper, $this->line, $depth, $this->indentPad); - $this->line = ''; - } + /** + * Dumps a Data object. + * + * @param Data $data A Data object + * @param callable|resource|string|true|null $output A line dumper callable, an opened stream, an output path or true to return the dump + * + * @return string|null The dump as string when $output is true + */ + public function dump(Data $data, $output = null) + { + $this->decimalPoint = localeconv(); + $this->decimalPoint = $this->decimalPoint['decimal_point']; - /** - * Generic line dumper callback. - * - * @param string $line The line to write. - * @param int $depth The recursive depth in the dumped structure. - */ - protected function echoLine($line, $depth, $indentPad) - { - if (-1 !== $depth) { - fwrite($this->outputStream, str_repeat($indentPad, $depth).$line."\n"); - } - } + if ($returnDump = true === $output) { + $output = fopen('php://memory', 'r+b'); + } + if ($output) { + $prevOutput = $this->setOutput($output); + } + try { + $data->dump($this); + $this->dumpLine(-1); - /** - * Converts a non-UTF-8 string to UTF-8. - * - * @param string $s The non-UTF-8 string to convert. - * - * @return string The string converted to UTF-8. - */ - protected function utf8Encode($s) - { - if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) { - return $c; - } - if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) { - return $c; - } + if ($returnDump) { + $result = stream_get_contents($output, -1, 0); + fclose($output); - return iconv('CP850', 'UTF-8', $s); - } + return $result; + } + } finally { + if ($output) { + $this->setOutput($prevOutput); + } + } + } + + /** + * Dumps the current line. + * + * @param int $depth The recursive depth in the dumped structure for the line being dumped + */ + protected function dumpLine($depth) + { + call_user_func($this->lineDumper, $this->line, $depth, $this->indentPad); + $this->line = ''; + } + + /** + * Generic line dumper callback. + * + * @param string $line The line to write + * @param int $depth The recursive depth in the dumped structure + * @param string $indentPad The line indent pad + */ + protected function echoLine($line, $depth, $indentPad) + { + if (-1 !== $depth) { + fwrite($this->outputStream, str_repeat($indentPad, $depth).$line."\n"); + } + } + + /** + * Converts a non-UTF-8 string to UTF-8. + * + * @param string $s The non-UTF-8 string to convert + * + * @return string The string converted to UTF-8 + */ + protected function utf8Encode($s) + { + if (preg_match('//u', $s)) { + return $s; + } + + if (!function_exists('iconv')) { + throw new \RuntimeException('Unable to convert a non-UTF-8 string to UTF-8: required function iconv() does not exist. You should install ext-iconv or symfony/polyfill-iconv.'); + } + + if (false !== $c = @iconv($this->charset, 'UTF-8', $s)) { + return $c; + } + if ('CP1252' !== $this->charset && false !== $c = @iconv('CP1252', 'UTF-8', $s)) { + return $c; + } + + return iconv('CP850', 'UTF-8', $s); + } } diff --git a/htdocs/includes/symfony/var-dumper/Dumper/CliDumper.php b/htdocs/includes/symfony/var-dumper/Dumper/CliDumper.php index bca2abcb3d0..95304b92817 100644 --- a/htdocs/includes/symfony/var-dumper/Dumper/CliDumper.php +++ b/htdocs/includes/symfony/var-dumper/Dumper/CliDumper.php @@ -20,452 +20,470 @@ use Symfony\Component\VarDumper\Cloner\Cursor; */ class CliDumper extends AbstractDumper { - public static $defaultColors; - public static $defaultOutput = 'php://stdout'; + public static $defaultColors; + public static $defaultOutput = 'php://stdout'; - protected $colors; - protected $maxStringWidth = 0; - protected $styles = array( - // See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics - 'default' => '38;5;208', - 'num' => '1;38;5;38', - 'const' => '1;38;5;208', - 'str' => '1;38;5;113', - 'note' => '38;5;38', - 'ref' => '38;5;247', - 'public' => '', - 'protected' => '', - 'private' => '', - 'meta' => '38;5;170', - 'key' => '38;5;113', - 'index' => '38;5;38', - ); + protected $colors; + protected $maxStringWidth = 0; + protected $styles = array( + // See http://en.wikipedia.org/wiki/ANSI_escape_code#graphics + 'default' => '38;5;208', + 'num' => '1;38;5;38', + 'const' => '1;38;5;208', + 'str' => '1;38;5;113', + 'note' => '38;5;38', + 'ref' => '38;5;247', + 'public' => '', + 'protected' => '', + 'private' => '', + 'meta' => '38;5;170', + 'key' => '38;5;113', + 'index' => '38;5;38', + ); - protected static $controlCharsRx = '/[\x00-\x1F\x7F]+/'; - protected static $controlCharsMap = array( - "\t" => '\t', - "\n" => '\n', - "\v" => '\v', - "\f" => '\f', - "\r" => '\r', - "\033" => '\e', - ); + protected static $controlCharsRx = '/[\x00-\x1F\x7F]+/'; + protected static $controlCharsMap = array( + "\t" => '\t', + "\n" => '\n', + "\v" => '\v', + "\f" => '\f', + "\r" => '\r', + "\033" => '\e', + ); - /** - * {@inheritdoc} - */ - public function __construct($output = null, $charset = null) - { - parent::__construct($output, $charset); + /** + * {@inheritdoc} + */ + public function __construct($output = null, $charset = null, $flags = 0) + { + parent::__construct($output, $charset, $flags); - if ('\\' === DIRECTORY_SEPARATOR && false !== @getenv('ANSICON')) { - // Use only the base 16 xterm colors when using ANSICON - $this->setStyles(array( - 'default' => '31', - 'num' => '1;34', - 'const' => '1;31', - 'str' => '1;32', - 'note' => '34', - 'ref' => '1;30', - 'meta' => '35', - 'key' => '32', - 'index' => '34', - )); - } - } + if ('\\' === DIRECTORY_SEPARATOR && 'ON' !== @getenv('ConEmuANSI') && 'xterm' !== @getenv('TERM')) { + // Use only the base 16 xterm colors when using ANSICON or standard Windows 10 CLI + $this->setStyles(array( + 'default' => '31', + 'num' => '1;34', + 'const' => '1;31', + 'str' => '1;32', + 'note' => '34', + 'ref' => '1;30', + 'meta' => '35', + 'key' => '32', + 'index' => '34', + )); + } + } - /** - * Enables/disables colored output. - * - * @param bool $colors - */ - public function setColors($colors) - { - $this->colors = (bool) $colors; - } + /** + * Enables/disables colored output. + * + * @param bool $colors + */ + public function setColors($colors) + { + $this->colors = (bool) $colors; + } - /** - * Sets the maximum number of characters per line for dumped strings. - * - * @param int $maxStringWidth - */ - public function setMaxStringWidth($maxStringWidth) - { - $this->maxStringWidth = (int) $maxStringWidth; - } + /** + * Sets the maximum number of characters per line for dumped strings. + * + * @param int $maxStringWidth + */ + public function setMaxStringWidth($maxStringWidth) + { + $this->maxStringWidth = (int) $maxStringWidth; + } - /** - * Configures styles. - * - * @param array $styles A map of style names to style definitions. - */ - public function setStyles(array $styles) - { - $this->styles = $styles + $this->styles; - } + /** + * Configures styles. + * + * @param array $styles A map of style names to style definitions + */ + public function setStyles(array $styles) + { + $this->styles = $styles + $this->styles; + } - /** - * {@inheritdoc} - */ - public function dumpScalar(Cursor $cursor, $type, $value) - { - $this->dumpKey($cursor); + /** + * {@inheritdoc} + */ + public function dumpScalar(Cursor $cursor, $type, $value) + { + $this->dumpKey($cursor); - $style = 'const'; - $attr = array(); + $style = 'const'; + $attr = $cursor->attr; - switch ($type) { - case 'integer': - $style = 'num'; - break; + switch ($type) { + case 'default': + $style = 'default'; + break; - case 'double': - $style = 'num'; + case 'integer': + $style = 'num'; + break; - switch (true) { - case INF === $value: $value = 'INF'; break; - case -INF === $value: $value = '-INF'; break; - case is_nan($value): $value = 'NAN'; break; - default: - $value = (string) $value; - if (false === strpos($value, $this->decimalPoint)) { - $value .= $this->decimalPoint.'0'; - } - break; - } - break; + case 'double': + $style = 'num'; - case 'NULL': - $value = 'null'; - break; + switch (true) { + case INF === $value: $value = 'INF'; break; + case -INF === $value: $value = '-INF'; break; + case is_nan($value): $value = 'NAN'; break; + default: + $value = (string) $value; + if (false === strpos($value, $this->decimalPoint)) { + $value .= $this->decimalPoint.'0'; + } + break; + } + break; - case 'boolean': - $value = $value ? 'true' : 'false'; - break; + case 'NULL': + $value = 'null'; + break; - default: - $attr['value'] = isset($value[0]) && !preg_match('//u', $value) ? $this->utf8Encode($value) : $value; - $value = isset($type[0]) && !preg_match('//u', $type) ? $this->utf8Encode($type) : $type; - break; - } + case 'boolean': + $value = $value ? 'true' : 'false'; + break; - $this->line .= $this->style($style, $value, $attr); + default: + $attr += array('value' => $this->utf8Encode($value)); + $value = $this->utf8Encode($type); + break; + } - $this->dumpLine($cursor->depth, true); - } + $this->line .= $this->style($style, $value, $attr); - /** - * {@inheritdoc} - */ - public function dumpString(Cursor $cursor, $str, $bin, $cut) - { - $this->dumpKey($cursor); + $this->dumpLine($cursor->depth, true); + } - if ($bin) { - $str = $this->utf8Encode($str); - } - if ('' === $str) { - $this->line .= '""'; - $this->dumpLine($cursor->depth, true); - } else { - $attr = array( - 'length' => 0 <= $cut ? iconv_strlen($str, 'UTF-8') + $cut : 0, - 'binary' => $bin, - ); - $str = explode("\n", $str); - if (isset($str[1]) && !isset($str[2]) && !isset($str[1][0])) { - unset($str[1]); - $str[0] .= "\n"; - } - $m = count($str) - 1; - $i = $lineCut = 0; + /** + * {@inheritdoc} + */ + public function dumpString(Cursor $cursor, $str, $bin, $cut) + { + $this->dumpKey($cursor); + $attr = $cursor->attr; - if ($bin) { - $this->line .= 'b'; - } + if ($bin) { + $str = $this->utf8Encode($str); + } + if ('' === $str) { + $this->line .= '""'; + $this->dumpLine($cursor->depth, true); + } else { + $attr += array( + 'length' => 0 <= $cut ? mb_strlen($str, 'UTF-8') + $cut : 0, + 'binary' => $bin, + ); + $str = explode("\n", $str); + if (isset($str[1]) && !isset($str[2]) && !isset($str[1][0])) { + unset($str[1]); + $str[0] .= "\n"; + } + $m = count($str) - 1; + $i = $lineCut = 0; - if ($m) { - $this->line .= '"""'; - $this->dumpLine($cursor->depth); - } else { - $this->line .= '"'; - } + if (self::DUMP_STRING_LENGTH & $this->flags) { + $this->line .= '('.$attr['length'].') '; + } + if ($bin) { + $this->line .= 'b'; + } - foreach ($str as $str) { - if ($i < $m) { - $str .= "\n"; - } - if (0 < $this->maxStringWidth && $this->maxStringWidth < $len = iconv_strlen($str, 'UTF-8')) { - $str = iconv_substr($str, 0, $this->maxStringWidth, 'UTF-8'); - $lineCut = $len - $this->maxStringWidth; - } - if ($m && 0 < $cursor->depth) { - $this->line .= $this->indentPad; - } - if ('' !== $str) { - $this->line .= $this->style('str', $str, $attr); - } - if ($i++ == $m) { - if ($m) { - if ('' !== $str) { - $this->dumpLine($cursor->depth); - if (0 < $cursor->depth) { - $this->line .= $this->indentPad; - } - } - $this->line .= '"""'; - } else { - $this->line .= '"'; - } - if ($cut < 0) { - $this->line .= '…'; - $lineCut = 0; - } elseif ($cut) { - $lineCut += $cut; - } - } - if ($lineCut) { - $this->line .= '…'.$lineCut; - $lineCut = 0; - } + if ($m) { + $this->line .= '"""'; + $this->dumpLine($cursor->depth); + } else { + $this->line .= '"'; + } - $this->dumpLine($cursor->depth, $i > $m); - } - } - } + foreach ($str as $str) { + if ($i < $m) { + $str .= "\n"; + } + if (0 < $this->maxStringWidth && $this->maxStringWidth < $len = mb_strlen($str, 'UTF-8')) { + $str = mb_substr($str, 0, $this->maxStringWidth, 'UTF-8'); + $lineCut = $len - $this->maxStringWidth; + } + if ($m && 0 < $cursor->depth) { + $this->line .= $this->indentPad; + } + if ('' !== $str) { + $this->line .= $this->style('str', $str, $attr); + } + if ($i++ == $m) { + if ($m) { + if ('' !== $str) { + $this->dumpLine($cursor->depth); + if (0 < $cursor->depth) { + $this->line .= $this->indentPad; + } + } + $this->line .= '"""'; + } else { + $this->line .= '"'; + } + if ($cut < 0) { + $this->line .= '…'; + $lineCut = 0; + } elseif ($cut) { + $lineCut += $cut; + } + } + if ($lineCut) { + $this->line .= '…'.$lineCut; + $lineCut = 0; + } - /** - * {@inheritdoc} - */ - public function enterHash(Cursor $cursor, $type, $class, $hasChild) - { - $this->dumpKey($cursor); + $this->dumpLine($cursor->depth, $i > $m); + } + } + } - if (!preg_match('//u', $class)) { - $class = $this->utf8Encode($class); - } - if (Cursor::HASH_OBJECT === $type) { - $prefix = $class && 'stdClass' !== $class ? $this->style('note', $class).' {' : '{'; - } elseif (Cursor::HASH_RESOURCE === $type) { - $prefix = $this->style('note', $class.' resource').($hasChild ? ' {' : ' '); - } else { - $prefix = $class ? $this->style('note', 'array:'.$class).' [' : '['; - } + /** + * {@inheritdoc} + */ + public function enterHash(Cursor $cursor, $type, $class, $hasChild) + { + $this->dumpKey($cursor); - if ($cursor->softRefCount || 0 < $cursor->softRefHandle) { - $prefix .= $this->style('ref', (Cursor::HASH_RESOURCE === $type ? '@' : '#').(0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->softRefTo), array('count' => $cursor->softRefCount)); - } elseif ($cursor->hardRefTo && !$cursor->refIndex && $class) { - $prefix .= $this->style('ref', '&'.$cursor->hardRefTo, array('count' => $cursor->hardRefCount)); - } elseif (!$hasChild && Cursor::HASH_RESOURCE === $type) { - $prefix = substr($prefix, 0, -1); - } + $class = $this->utf8Encode($class); + if (Cursor::HASH_OBJECT === $type) { + $prefix = $class && 'stdClass' !== $class ? $this->style('note', $class).' {' : '{'; + } elseif (Cursor::HASH_RESOURCE === $type) { + $prefix = $this->style('note', $class.' resource').($hasChild ? ' {' : ' '); + } else { + $prefix = $class && !(self::DUMP_LIGHT_ARRAY & $this->flags) ? $this->style('note', 'array:'.$class).' [' : '['; + } - $this->line .= $prefix; + if ($cursor->softRefCount || 0 < $cursor->softRefHandle) { + $prefix .= $this->style('ref', (Cursor::HASH_RESOURCE === $type ? '@' : '#').(0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->softRefTo), array('count' => $cursor->softRefCount)); + } elseif ($cursor->hardRefTo && !$cursor->refIndex && $class) { + $prefix .= $this->style('ref', '&'.$cursor->hardRefTo, array('count' => $cursor->hardRefCount)); + } elseif (!$hasChild && Cursor::HASH_RESOURCE === $type) { + $prefix = substr($prefix, 0, -1); + } - if ($hasChild) { - $this->dumpLine($cursor->depth); - } - } + $this->line .= $prefix; - /** - * {@inheritdoc} - */ - public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut) - { - $this->dumpEllipsis($cursor, $hasChild, $cut); - $this->line .= Cursor::HASH_OBJECT === $type ? '}' : (Cursor::HASH_RESOURCE !== $type ? ']' : ($hasChild ? '}' : '')); - $this->dumpLine($cursor->depth, true); - } + if ($hasChild) { + $this->dumpLine($cursor->depth); + } + } - /** - * Dumps an ellipsis for cut children. - * - * @param Cursor $cursor The Cursor position in the dump. - * @param bool $hasChild When the dump of the hash has child item. - * @param int $cut The number of items the hash has been cut by. - */ - protected function dumpEllipsis(Cursor $cursor, $hasChild, $cut) - { - if ($cut) { - $this->line .= ' …'; - if (0 < $cut) { - $this->line .= $cut; - } - if ($hasChild) { - $this->dumpLine($cursor->depth + 1); - } - } - } + /** + * {@inheritdoc} + */ + public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut) + { + $this->dumpEllipsis($cursor, $hasChild, $cut); + $this->line .= Cursor::HASH_OBJECT === $type ? '}' : (Cursor::HASH_RESOURCE !== $type ? ']' : ($hasChild ? '}' : '')); + $this->dumpLine($cursor->depth, true); + } - /** - * Dumps a key in a hash structure. - * - * @param Cursor $cursor The Cursor position in the dump. - */ - protected function dumpKey(Cursor $cursor) - { - if (null !== $key = $cursor->hashKey) { - if ($cursor->hashKeyIsBinary) { - $key = $this->utf8Encode($key); - } - $attr = array('binary' => $cursor->hashKeyIsBinary); - $bin = $cursor->hashKeyIsBinary ? 'b' : ''; - $style = 'key'; - switch ($cursor->hashType) { - default: - case Cursor::HASH_INDEXED: - $style = 'index'; - case Cursor::HASH_ASSOC: - if (is_int($key)) { - $this->line .= $this->style($style, $key).' => '; - } else { - $this->line .= $bin.'"'.$this->style($style, $key).'" => '; - } - break; + /** + * Dumps an ellipsis for cut children. + * + * @param Cursor $cursor The Cursor position in the dump + * @param bool $hasChild When the dump of the hash has child item + * @param int $cut The number of items the hash has been cut by + */ + protected function dumpEllipsis(Cursor $cursor, $hasChild, $cut) + { + if ($cut) { + $this->line .= ' …'; + if (0 < $cut) { + $this->line .= $cut; + } + if ($hasChild) { + $this->dumpLine($cursor->depth + 1); + } + } + } - case Cursor::HASH_RESOURCE: - $key = "\0~\0".$key; - // No break; - case Cursor::HASH_OBJECT: - if (!isset($key[0]) || "\0" !== $key[0]) { - $this->line .= '+'.$bin.$this->style('public', $key).': '; - } elseif (0 < strpos($key, "\0", 1)) { - $key = explode("\0", substr($key, 1), 2); + /** + * Dumps a key in a hash structure. + * + * @param Cursor $cursor The Cursor position in the dump + */ + protected function dumpKey(Cursor $cursor) + { + if (null !== $key = $cursor->hashKey) { + if ($cursor->hashKeyIsBinary) { + $key = $this->utf8Encode($key); + } + $attr = array('binary' => $cursor->hashKeyIsBinary); + $bin = $cursor->hashKeyIsBinary ? 'b' : ''; + $style = 'key'; + switch ($cursor->hashType) { + default: + case Cursor::HASH_INDEXED: + if (self::DUMP_LIGHT_ARRAY & $this->flags) { + break; + } + $style = 'index'; + case Cursor::HASH_ASSOC: + if (is_int($key)) { + $this->line .= $this->style($style, $key).' => '; + } else { + $this->line .= $bin.'"'.$this->style($style, $key).'" => '; + } + break; - switch ($key[0]) { - case '+': // User inserted keys - $attr['dynamic'] = true; - $this->line .= '+'.$bin.'"'.$this->style('public', $key[1], $attr).'": '; - break 2; - case '~': - $style = 'meta'; - break; - case '*': - $style = 'protected'; - $bin = '#'.$bin; - break; - default: - $attr['class'] = $key[0]; - $style = 'private'; - $bin = '-'.$bin; - break; - } + case Cursor::HASH_RESOURCE: + $key = "\0~\0".$key; + // No break; + case Cursor::HASH_OBJECT: + if (!isset($key[0]) || "\0" !== $key[0]) { + $this->line .= '+'.$bin.$this->style('public', $key).': '; + } elseif (0 < strpos($key, "\0", 1)) { + $key = explode("\0", substr($key, 1), 2); - $this->line .= $bin.$this->style($style, $key[1], $attr).': '; - } else { - // This case should not happen - $this->line .= '-'.$bin.'"'.$this->style('private', $key, array('class' => '')).'": '; - } - break; - } + switch ($key[0][0]) { + case '+': // User inserted keys + $attr['dynamic'] = true; + $this->line .= '+'.$bin.'"'.$this->style('public', $key[1], $attr).'": '; + break 2; + case '~': + $style = 'meta'; + if (isset($key[0][1])) { + parse_str(substr($key[0], 1), $attr); + $attr += array('binary' => $cursor->hashKeyIsBinary); + } + break; + case '*': + $style = 'protected'; + $bin = '#'.$bin; + break; + default: + $attr['class'] = $key[0]; + $style = 'private'; + $bin = '-'.$bin; + break; + } - if ($cursor->hardRefTo) { - $this->line .= $this->style('ref', '&'.($cursor->hardRefCount ? $cursor->hardRefTo : ''), array('count' => $cursor->hardRefCount)).' '; - } - } - } + $this->line .= $bin.$this->style($style, $key[1], $attr).': '; + } else { + // This case should not happen + $this->line .= '-'.$bin.'"'.$this->style('private', $key, array('class' => '')).'": '; + } + break; + } - /** - * Decorates a value with some style. - * - * @param string $style The type of style being applied. - * @param string $value The value being styled. - * @param array $attr Optional context information. - * - * @return string The value with style decoration. - */ - protected function style($style, $value, $attr = array()) - { - if (null === $this->colors) { - $this->colors = $this->supportsColors(); - } + if ($cursor->hardRefTo) { + $this->line .= $this->style('ref', '&'.($cursor->hardRefCount ? $cursor->hardRefTo : ''), array('count' => $cursor->hardRefCount)).' '; + } + } + } - $style = $this->styles[$style]; + /** + * Decorates a value with some style. + * + * @param string $style The type of style being applied + * @param string $value The value being styled + * @param array $attr Optional context information + * + * @return string The value with style decoration + */ + protected function style($style, $value, $attr = array()) + { + if (null === $this->colors) { + $this->colors = $this->supportsColors(); + } - $map = static::$controlCharsMap; - $startCchr = $this->colors ? "\033[m\033[{$this->styles['default']}m" : ''; - $endCchr = $this->colors ? "\033[m\033[{$style}m" : ''; - $value = preg_replace_callback(static::$controlCharsRx, function ($c) use ($map, $startCchr, $endCchr) { - $s = $startCchr; - $c = $c[$i = 0]; - do { - $s .= isset($map[$c[$i]]) ? $map[$c[$i]] : sprintf('\x%02X', ord($c[$i])); - } while (isset($c[++$i])); + $style = $this->styles[$style]; - return $s.$endCchr; - }, $value, -1, $cchrCount); + $map = static::$controlCharsMap; + $startCchr = $this->colors ? "\033[m\033[{$this->styles['default']}m" : ''; + $endCchr = $this->colors ? "\033[m\033[{$style}m" : ''; + $value = preg_replace_callback(static::$controlCharsRx, function ($c) use ($map, $startCchr, $endCchr) { + $s = $startCchr; + $c = $c[$i = 0]; + do { + $s .= isset($map[$c[$i]]) ? $map[$c[$i]] : sprintf('\x%02X', ord($c[$i])); + } while (isset($c[++$i])); - if ($this->colors) { - if ($cchrCount && "\033" === $value[0]) { - $value = substr($value, strlen($startCchr)); - } else { - $value = "\033[{$style}m".$value; - } - if ($cchrCount && $endCchr === substr($value, -strlen($endCchr))) { - $value = substr($value, 0, -strlen($endCchr)); - } else { - $value .= "\033[{$this->styles['default']}m"; - } - } + return $s.$endCchr; + }, $value, -1, $cchrCount); - return $value; - } + if ($this->colors) { + if ($cchrCount && "\033" === $value[0]) { + $value = substr($value, strlen($startCchr)); + } else { + $value = "\033[{$style}m".$value; + } + if ($cchrCount && $endCchr === substr($value, -strlen($endCchr))) { + $value = substr($value, 0, -strlen($endCchr)); + } else { + $value .= "\033[{$this->styles['default']}m"; + } + } - /** - * @return bool Tells if the current output stream supports ANSI colors or not. - */ - protected function supportsColors() - { - if ($this->outputStream !== static::$defaultOutput) { - return @(is_resource($this->outputStream) && function_exists('posix_isatty') && posix_isatty($this->outputStream)); - } - if (null !== static::$defaultColors) { - return static::$defaultColors; - } - if (isset($_SERVER['argv'][1])) { - $colors = $_SERVER['argv']; - $i = count($colors); - while (--$i > 0) { - if (isset($colors[$i][5])) { - switch ($colors[$i]) { - case '--ansi': - case '--color': - case '--color=yes': - case '--color=force': - case '--color=always': - return static::$defaultColors = true; + return $value; + } - case '--no-ansi': - case '--color=no': - case '--color=none': - case '--color=never': - return static::$defaultColors = false; - } - } - } - } + /** + * @return bool Tells if the current output stream supports ANSI colors or not + */ + protected function supportsColors() + { + if ($this->outputStream !== static::$defaultOutput) { + return @(is_resource($this->outputStream) && function_exists('posix_isatty') && posix_isatty($this->outputStream)); + } + if (null !== static::$defaultColors) { + return static::$defaultColors; + } + if (isset($_SERVER['argv'][1])) { + $colors = $_SERVER['argv']; + $i = count($colors); + while (--$i > 0) { + if (isset($colors[$i][5])) { + switch ($colors[$i]) { + case '--ansi': + case '--color': + case '--color=yes': + case '--color=force': + case '--color=always': + return static::$defaultColors = true; - if ('\\' === DIRECTORY_SEPARATOR) { - static::$defaultColors = @(false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI') || 'xterm' === getenv('TERM')); - } elseif (function_exists('posix_isatty')) { - $h = stream_get_meta_data($this->outputStream) + array('wrapper_type' => null); - $h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'wb') : $this->outputStream; - static::$defaultColors = @posix_isatty($h); - } else { - static::$defaultColors = false; - } + case '--no-ansi': + case '--color=no': + case '--color=none': + case '--color=never': + return static::$defaultColors = false; + } + } + } + } - return static::$defaultColors; - } + if ('\\' === DIRECTORY_SEPARATOR) { + static::$defaultColors = @( + '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR.'.'.PHP_WINDOWS_VERSION_MINOR.'.'.PHP_WINDOWS_VERSION_BUILD + || false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM') + ); + } elseif (function_exists('posix_isatty')) { + $h = stream_get_meta_data($this->outputStream) + array('wrapper_type' => null); + $h = 'Output' === $h['stream_type'] && 'PHP' === $h['wrapper_type'] ? fopen('php://stdout', 'wb') : $this->outputStream; + static::$defaultColors = @posix_isatty($h); + } else { + static::$defaultColors = false; + } - /** - * {@inheritdoc} - */ - protected function dumpLine($depth, $endOfValue = false) - { - if ($this->colors) { - $this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line); - } - parent::dumpLine($depth); - } + return static::$defaultColors; + } + + /** + * {@inheritdoc} + */ + protected function dumpLine($depth, $endOfValue = false) + { + if ($this->colors) { + $this->line = sprintf("\033[%sm%s\033[m", $this->styles['default'], $this->line); + } + parent::dumpLine($depth); + } } diff --git a/htdocs/includes/symfony/var-dumper/Dumper/DataDumperInterface.php b/htdocs/includes/symfony/var-dumper/Dumper/DataDumperInterface.php index ee6060cebf6..abaa85c19bd 100644 --- a/htdocs/includes/symfony/var-dumper/Dumper/DataDumperInterface.php +++ b/htdocs/includes/symfony/var-dumper/Dumper/DataDumperInterface.php @@ -20,10 +20,10 @@ use Symfony\Component\VarDumper\Cloner\Data; */ interface DataDumperInterface { - /** - * Dumps a Data object. - * - * @param Data $data A Data object. - */ - public function dump(Data $data); + /** + * Dumps a Data object. + * + * @param Data $data A Data object + */ + public function dump(Data $data); } diff --git a/htdocs/includes/symfony/var-dumper/Dumper/HtmlDumper.php b/htdocs/includes/symfony/var-dumper/Dumper/HtmlDumper.php index 28af8e4cb22..10a3ffa41c0 100644 --- a/htdocs/includes/symfony/var-dumper/Dumper/HtmlDumper.php +++ b/htdocs/includes/symfony/var-dumper/Dumper/HtmlDumper.php @@ -21,103 +21,114 @@ use Symfony\Component\VarDumper\Cloner\Data; */ class HtmlDumper extends CliDumper { - public static $defaultOutput = 'php://output'; + public static $defaultOutput = 'php://output'; - protected $dumpHeader; - protected $dumpPrefix = '
    ';
    -    protected $dumpSuffix = '
    '; - protected $dumpId = 'sf-dump'; - protected $colors = true; - protected $headerIsDumped = false; - protected $lastDepth = -1; - protected $styles = array( - 'default' => 'background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:100000; word-break: normal', - 'num' => 'font-weight:bold; color:#1299DA', - 'const' => 'font-weight:bold', - 'str' => 'font-weight:bold; color:#56DB3A', - 'note' => 'color:#1299DA', - 'ref' => 'color:#A0A0A0', - 'public' => 'color:#FFFFFF', - 'protected' => 'color:#FFFFFF', - 'private' => 'color:#FFFFFF', - 'meta' => 'color:#B729D9', - 'key' => 'color:#56DB3A', - 'index' => 'color:#1299DA', - ); + protected $dumpHeader; + protected $dumpPrefix = '
    ';
    +	protected $dumpSuffix = '
    '; + protected $dumpId = 'sf-dump'; + protected $colors = true; + protected $headerIsDumped = false; + protected $lastDepth = -1; + protected $styles = array( + 'default' => 'background-color:#18171B; color:#FF8400; line-height:1.2em; font:12px Menlo, Monaco, Consolas, monospace; word-wrap: break-word; white-space: pre-wrap; position:relative; z-index:99999; word-break: normal', + 'num' => 'font-weight:bold; color:#1299DA', + 'const' => 'font-weight:bold', + 'str' => 'font-weight:bold; color:#56DB3A', + 'note' => 'color:#1299DA', + 'ref' => 'color:#A0A0A0', + 'public' => 'color:#FFFFFF', + 'protected' => 'color:#FFFFFF', + 'private' => 'color:#FFFFFF', + 'meta' => 'color:#B729D9', + 'key' => 'color:#56DB3A', + 'index' => 'color:#1299DA', + 'ellipsis' => 'color:#FF8400', + ); - /** - * {@inheritdoc} - */ - public function __construct($output = null, $charset = null) - { - AbstractDumper::__construct($output, $charset); - $this->dumpId = 'sf-dump-'.mt_rand(); - } + private $displayOptions = array( + 'maxDepth' => 1, + 'maxStringLength' => 160, + 'fileLinkFormat' => null, + ); + private $extraDisplayOptions = array(); - /** - * {@inheritdoc} - */ - public function setOutput($output) - { - if ($output !== $prev = parent::setOutput($output)) { - $this->headerIsDumped = false; - } + /** + * {@inheritdoc} + */ + public function __construct($output = null, $charset = null, $flags = 0) + { + AbstractDumper::__construct($output, $charset, $flags); + $this->dumpId = 'sf-dump-'.mt_rand(); + $this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); + } - return $prev; - } + /** + * {@inheritdoc} + */ + public function setStyles(array $styles) + { + $this->headerIsDumped = false; + $this->styles = $styles + $this->styles; + } - /** - * {@inheritdoc} - */ - public function setStyles(array $styles) - { - $this->headerIsDumped = false; - $this->styles = $styles + $this->styles; - } + /** + * Configures display options. + * + * @param array $displayOptions A map of display options to customize the behavior + */ + public function setDisplayOptions(array $displayOptions) + { + $this->headerIsDumped = false; + $this->displayOptions = $displayOptions + $this->displayOptions; + } - /** - * Sets an HTML header that will be dumped once in the output stream. - * - * @param string $header An HTML string. - */ - public function setDumpHeader($header) - { - $this->dumpHeader = $header; - } + /** + * Sets an HTML header that will be dumped once in the output stream. + * + * @param string $header An HTML string + */ + public function setDumpHeader($header) + { + $this->dumpHeader = $header; + } - /** - * Sets an HTML prefix and suffix that will encapse every single dump. - * - * @param string $prefix The prepended HTML string. - * @param string $suffix The appended HTML string. - */ - public function setDumpBoundaries($prefix, $suffix) - { - $this->dumpPrefix = $prefix; - $this->dumpSuffix = $suffix; - } + /** + * Sets an HTML prefix and suffix that will encapse every single dump. + * + * @param string $prefix The prepended HTML string + * @param string $suffix The appended HTML string + */ + public function setDumpBoundaries($prefix, $suffix) + { + $this->dumpPrefix = $prefix; + $this->dumpSuffix = $suffix; + } - /** - * {@inheritdoc} - */ - public function dump(Data $data, $output = null) - { - parent::dump($data, $output); - $this->dumpId = 'sf-dump-'.mt_rand(); - } + /** + * {@inheritdoc} + */ + public function dump(Data $data, $output = null, array $extraDisplayOptions = array()) + { + $this->extraDisplayOptions = $extraDisplayOptions; + $result = parent::dump($data, $output); + $this->dumpId = 'sf-dump-'.mt_rand(); - /** - * Dumps the HTML header. - */ - protected function getDumpHeader() - { - $this->headerIsDumped = true; + return $result; + } - if (null !== $this->dumpHeader) { - return $this->dumpHeader; - } + /** + * Dumps the HTML header. + */ + protected function getDumpHeader() + { + $this->headerIsDumped = null !== $this->outputStream ? $this->outputStream : $this->lineDumper; - $line = <<<'EOHTML' + if (null !== $this->dumpHeader) { + return $this->dumpHeader; + } + + $line = str_replace('{$options}', json_encode($this->displayOptions, JSON_FORCE_OBJECT), <<<'EOHTML' -'.$this->dumpHeader; - } - - /** - * {@inheritdoc} - */ - public function enterHash(Cursor $cursor, $type, $class, $hasChild) - { - parent::enterHash($cursor, $type, $class, false); - - if ($hasChild) { - if ($cursor->refIndex) { - $r = Cursor::HASH_OBJECT !== $type ? 1 - (Cursor::HASH_RESOURCE !== $type) : 2; - $r .= $r && 0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->refIndex; - - $this->line .= sprintf('', $this->dumpId, $r); - } else { - $this->line .= ''; - } - $this->dumpLine($cursor->depth); - } - } - - /** - * {@inheritdoc} - */ - public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut) - { - $this->dumpEllipsis($cursor, $hasChild, $cut); - if ($hasChild) { - $this->line .= ''; - } - parent::leaveHash($cursor, $type, $class, $hasChild, 0); - } - - /** - * {@inheritdoc} - */ - protected function style($style, $value, $attr = array()) - { - if ('' === $value) { - return ''; - } - - $v = htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); - - if ('ref' === $style) { - if (empty($attr['count'])) { - return sprintf('%s', $v); - } - $r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1); - - return sprintf('%s', $this->dumpId, $r, 1 + $attr['count'], $v); - } - - if ('const' === $style && array_key_exists('value', $attr)) { - $style .= sprintf(' title="%s"', htmlspecialchars(json_encode($attr['value']), ENT_QUOTES, 'UTF-8')); - } elseif ('public' === $style) { - $style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property'); - } elseif ('str' === $style && 1 < $attr['length']) { - $style .= sprintf(' title="%s%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : ''); - } elseif ('note' === $style && false !== $c = strrpos($v, '\\')) { - return sprintf('%s', $v, $style, substr($v, $c + 1)); - } elseif ('protected' === $style) { - $style .= ' title="Protected property"'; - } elseif ('private' === $style) { - $style .= sprintf(' title="Private property defined in class: `%s`"', $attr['class']); - } - - $map = static::$controlCharsMap; - $style = ""; - $v = preg_replace_callback(static::$controlCharsRx, function ($c) use ($map, $style) { - $s = ''; - $c = $c[$i = 0]; - do { - $s .= isset($map[$c[$i]]) ? $map[$c[$i]] : sprintf('\x%02X', ord($c[$i])); - } while (isset($c[++$i])); - - return $s.$style; - }, $v, -1, $cchrCount); - - if ($cchrCount && '<' === $v[0]) { - $v = substr($v, 7); - } else { - $v = $style.$v; - } - if ($cchrCount && '>' === substr($v, -1)) { - $v = substr($v, 0, -strlen($style)); - } else { - $v .= ''; - } - - return $v; - } - - /** - * {@inheritdoc} - */ - protected function dumpLine($depth, $endOfValue = false) - { - if (-1 === $this->lastDepth) { - $this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line; - } - if (!$this->headerIsDumped) { - $this->line = $this->getDumpHeader().$this->line; - } - - if (-1 === $depth) { - $this->line .= sprintf($this->dumpSuffix, $this->dumpId); - } - $this->lastDepth = $depth; - - $this->line = mb_convert_encoding($this->line, 'HTML-ENTITIES', 'UTF-8'); - - if (-1 === $depth) { - AbstractDumper::dumpLine(0); - } - AbstractDumper::dumpLine($depth); - } +pre.sf-dump .sf-dump-ellipsis { + display: inline-block; + overflow: visible; + text-overflow: ellipsis; + max-width: 5em; + white-space: nowrap; + overflow: hidden; + vertical-align: top; +} +pre.sf-dump code { + display:inline; + padding:0; + background:none; +} +.sf-dump-str-collapse .sf-dump-str-collapse { + display: none; +} +.sf-dump-str-expand .sf-dump-str-expand { + display: none; +} +EOHTML + ); + + foreach ($this->styles as $class => $style) { + $line .= 'pre.sf-dump'.('default' === $class ? ', pre.sf-dump' : '').' .sf-dump-'.$class.'{'.$style.'}'; + } + + return $this->dumpHeader = preg_replace('/\s+/', ' ', $line).''.$this->dumpHeader; + } + + /** + * {@inheritdoc} + */ + public function enterHash(Cursor $cursor, $type, $class, $hasChild) + { + parent::enterHash($cursor, $type, $class, false); + + if ($hasChild) { + if ($cursor->refIndex) { + $r = Cursor::HASH_OBJECT !== $type ? 1 - (Cursor::HASH_RESOURCE !== $type) : 2; + $r .= $r && 0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->refIndex; + + $this->line .= sprintf('', $this->dumpId, $r); + } else { + $this->line .= ''; + } + $this->dumpLine($cursor->depth); + } + } + + /** + * {@inheritdoc} + */ + public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut) + { + $this->dumpEllipsis($cursor, $hasChild, $cut); + if ($hasChild) { + $this->line .= ''; + } + parent::leaveHash($cursor, $type, $class, $hasChild, 0); + } + + /** + * {@inheritdoc} + */ + protected function style($style, $value, $attr = array()) + { + if ('' === $value) { + return ''; + } + + $v = esc($value); + + if ('ref' === $style) { + if (empty($attr['count'])) { + return sprintf('%s', $v); + } + $r = ('#' !== $v[0] ? 1 - ('@' !== $v[0]) : 2).substr($value, 1); + + return sprintf('%s', $this->dumpId, $r, 1 + $attr['count'], $v); + } + + if ('const' === $style && isset($attr['value'])) { + $style .= sprintf(' title="%s"', esc(is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value']))); + } elseif ('public' === $style) { + $style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property'); + } elseif ('str' === $style && 1 < $attr['length']) { + $style .= sprintf(' title="%d%s characters"', $attr['length'], $attr['binary'] ? ' binary or non-UTF-8' : ''); + } elseif ('note' === $style && false !== $c = strrpos($v, '\\')) { + return sprintf('%s', $v, $style, substr($v, $c + 1)); + } elseif ('protected' === $style) { + $style .= ' title="Protected property"'; + } elseif ('meta' === $style && isset($attr['title'])) { + $style .= sprintf(' title="%s"', esc($this->utf8Encode($attr['title']))); + } elseif ('private' === $style) { + $style .= sprintf(' title="Private property defined in class: `%s`"', esc($this->utf8Encode($attr['class']))); + } + $map = static::$controlCharsMap; + + if (isset($attr['ellipsis'])) { + $label = esc(substr($value, -$attr['ellipsis'])); + $style = str_replace(' title="', " title=\"$v\n", $style); + $v = sprintf('%s%s', substr($v, 0, -strlen($label)), $label); + } + + $v = "".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) { + $s = ''; + $c = $c[$i = 0]; + do { + $s .= isset($map[$c[$i]]) ? $map[$c[$i]] : sprintf('\x%02X', ord($c[$i])); + } while (isset($c[++$i])); + + return $s.''; + }, $v).''; + + if (isset($attr['file']) && $href = $this->getSourceLink($attr['file'], isset($attr['line']) ? $attr['line'] : 0)) { + $attr['href'] = $href; + } + if (isset($attr['href'])) { + $v = sprintf('%s', esc($this->utf8Encode($attr['href'])), $v); + } + if (isset($attr['lang'])) { + $v = sprintf('%s', esc($attr['lang']), $v); + } + + return $v; + } + + /** + * {@inheritdoc} + */ + protected function dumpLine($depth, $endOfValue = false) + { + if (-1 === $this->lastDepth) { + $this->line = sprintf($this->dumpPrefix, $this->dumpId, $this->indentPad).$this->line; + } + if ($this->headerIsDumped !== (null !== $this->outputStream ? $this->outputStream : $this->lineDumper)) { + $this->line = $this->getDumpHeader().$this->line; + } + + if (-1 === $depth) { + $args = array('"'.$this->dumpId.'"'); + if ($this->extraDisplayOptions) { + $args[] = json_encode($this->extraDisplayOptions, JSON_FORCE_OBJECT); + } + // Replace is for BC + $this->line .= sprintf(str_replace('"%s"', '%s', $this->dumpSuffix), implode(', ', $args)); + } + $this->lastDepth = $depth; + + $this->line = mb_convert_encoding($this->line, 'HTML-ENTITIES', 'UTF-8'); + + if (-1 === $depth) { + AbstractDumper::dumpLine(0); + } + AbstractDumper::dumpLine($depth); + } + + private function getSourceLink($file, $line) + { + $options = $this->extraDisplayOptions + $this->displayOptions; + + if ($fmt = $options['fileLinkFormat']) { + return is_string($fmt) ? strtr($fmt, array('%f' => $file, '%l' => $line)) : $fmt->format($file, $line); + } + + return false; + } +} + +function esc($str) +{ + return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); } diff --git a/htdocs/includes/symfony/var-dumper/LICENSE b/htdocs/includes/symfony/var-dumper/LICENSE index ef1cde91a61..207646a052d 100644 --- a/htdocs/includes/symfony/var-dumper/LICENSE +++ b/htdocs/includes/symfony/var-dumper/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2015 Fabien Potencier +Copyright (c) 2014-2017 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/htdocs/includes/symfony/var-dumper/README.md b/htdocs/includes/symfony/var-dumper/README.md index 71bff335a70..3b5d55f5f5b 100644 --- a/htdocs/includes/symfony/var-dumper/README.md +++ b/htdocs/includes/symfony/var-dumper/README.md @@ -1,14 +1,15 @@ -Symfony mechanism for exploring and dumping PHP variables -========================================================= +VarDumper Component +=================== -This component provides a mechanism that allows exploring then dumping -any PHP variable. +The VarDumper component provides mechanisms for walking through any arbitrary +PHP variable. Built on top, it provides a better `dump()` function that you +can use instead of `var_dump`. -It handles scalars, objects and resources properly, taking hard and soft -references into account. More than being immune to infinite recursion -problems, it allows dumping where references link to each other. -It explores recursive structures using a breadth-first algorithm. +Resources +--------- -The component exposes all the parts involved in the different steps of -cloning then dumping a PHP variable, while applying size limits and having -specialized output formats and methods. + * [Documentation](https://symfony.com/doc/current/components/var_dumper/introduction.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) diff --git a/htdocs/includes/symfony/var-dumper/Test/VarDumperTestTrait.php b/htdocs/includes/symfony/var-dumper/Test/VarDumperTestTrait.php index e5f6bf5b98e..b05e272d23b 100644 --- a/htdocs/includes/symfony/var-dumper/Test/VarDumperTestTrait.php +++ b/htdocs/includes/symfony/var-dumper/Test/VarDumperTestTrait.php @@ -19,27 +19,30 @@ use Symfony\Component\VarDumper\Dumper\CliDumper; */ trait VarDumperTestTrait { - public function assertDumpEquals($dump, $data, $message = '') - { - $this->assertSame(rtrim($dump), $this->getDump($data), $message); - } + public function assertDumpEquals($dump, $data, $message = '') + { + $this->assertSame(rtrim($dump), $this->getDump($data), $message); + } - public function assertDumpMatchesFormat($dump, $data, $message = '') - { - $this->assertStringMatchesFormat(rtrim($dump), $this->getDump($data), $message); - } + public function assertDumpMatchesFormat($dump, $data, $message = '') + { + $this->assertStringMatchesFormat(rtrim($dump), $this->getDump($data), $message); + } - protected function getDump($data) - { - $h = fopen('php://memory', 'r+b'); - $cloner = new VarCloner(); - $cloner->setMaxItems(-1); - $dumper = new CliDumper($h); - $dumper->setColors(false); - $dumper->dump($cloner->cloneVar($data)->withRefHandles(false)); - $data = stream_get_contents($h, -1, 0); - fclose($h); + protected function getDump($data, $key = null) + { + $flags = getenv('DUMP_LIGHT_ARRAY') ? CliDumper::DUMP_LIGHT_ARRAY : 0; + $flags |= getenv('DUMP_STRING_LENGTH') ? CliDumper::DUMP_STRING_LENGTH : 0; - return rtrim($data); - } + $cloner = new VarCloner(); + $cloner->setMaxItems(-1); + $dumper = new CliDumper(null, null, $flags); + $dumper->setColors(false); + $data = $cloner->cloneVar($data)->withRefHandles(false); + if (null !== $key && null === $data = $data->seek($key)) { + return; + } + + return rtrim($dumper->dump($data, true)); + } } diff --git a/htdocs/includes/symfony/var-dumper/Tests/Caster/CasterTest.php b/htdocs/includes/symfony/var-dumper/Tests/Caster/CasterTest.php index 43d389ce1c0..d1f09841ea3 100644 --- a/htdocs/includes/symfony/var-dumper/Tests/Caster/CasterTest.php +++ b/htdocs/includes/symfony/var-dumper/Tests/Caster/CasterTest.php @@ -11,170 +11,171 @@ namespace Symfony\Component\VarDumper\Tests\Caster; +use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Caster\Caster; use Symfony\Component\VarDumper\Test\VarDumperTestTrait; /** * @author Nicolas Grekas */ -class CasterTest extends \PHPUnit_Framework_TestCase +class CasterTest extends TestCase { - use VarDumperTestTrait; + use VarDumperTestTrait; - private $referenceArray = array( - 'null' => null, - 'empty' => false, - 'public' => 'pub', - "\0~\0virtual" => 'virt', - "\0+\0dynamic" => 'dyn', - "\0*\0protected" => 'prot', - "\0Foo\0private" => 'priv', - ); + private $referenceArray = array( + 'null' => null, + 'empty' => false, + 'public' => 'pub', + "\0~\0virtual" => 'virt', + "\0+\0dynamic" => 'dyn', + "\0*\0protected" => 'prot', + "\0Foo\0private" => 'priv', + ); - /** - * @dataProvider provideFilter - */ - public function testFilter($filter, $expectedDiff, $listedProperties = null) - { - if (null === $listedProperties) { - $filteredArray = Caster::filter($this->referenceArray, $filter); - } else { - $filteredArray = Caster::filter($this->referenceArray, $filter, $listedProperties); - } + /** + * @dataProvider provideFilter + */ + public function testFilter($filter, $expectedDiff, $listedProperties = null) + { + if (null === $listedProperties) { + $filteredArray = Caster::filter($this->referenceArray, $filter); + } else { + $filteredArray = Caster::filter($this->referenceArray, $filter, $listedProperties); + } - $this->assertSame($expectedDiff, array_diff_assoc($this->referenceArray, $filteredArray)); - } + $this->assertSame($expectedDiff, array_diff_assoc($this->referenceArray, $filteredArray)); + } - public function provideFilter() - { - return array( - array( - 0, - array(), - ), - array( - Caster::EXCLUDE_PUBLIC, - array( - 'null' => null, - 'empty' => false, - 'public' => 'pub', - ), - ), - array( - Caster::EXCLUDE_NULL, - array( - 'null' => null, - ), - ), - array( - Caster::EXCLUDE_EMPTY, - array( - 'null' => null, - 'empty' => false, - ), - ), - array( - Caster::EXCLUDE_VIRTUAL, - array( - "\0~\0virtual" => 'virt', - ), - ), - array( - Caster::EXCLUDE_DYNAMIC, - array( - "\0+\0dynamic" => 'dyn', - ), - ), - array( - Caster::EXCLUDE_PROTECTED, - array( - "\0*\0protected" => 'prot', - ), - ), - array( - Caster::EXCLUDE_PRIVATE, - array( - "\0Foo\0private" => 'priv', - ), - ), - array( - Caster::EXCLUDE_VERBOSE, - array( - 'public' => 'pub', - "\0*\0protected" => 'prot', - ), - array('public', "\0*\0protected"), - ), - array( - Caster::EXCLUDE_NOT_IMPORTANT, - array( - 'null' => null, - 'empty' => false, - "\0~\0virtual" => 'virt', - "\0+\0dynamic" => 'dyn', - "\0Foo\0private" => 'priv', - ), - array('public', "\0*\0protected"), - ), - array( - Caster::EXCLUDE_VIRTUAL | Caster::EXCLUDE_DYNAMIC, - array( - "\0~\0virtual" => 'virt', - "\0+\0dynamic" => 'dyn', - ), - ), - array( - Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_VERBOSE, - $this->referenceArray, - array('public', "\0*\0protected"), - ), - array( - Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_EMPTY, - array( - 'null' => null, - 'empty' => false, - "\0~\0virtual" => 'virt', - "\0+\0dynamic" => 'dyn', - "\0*\0protected" => 'prot', - "\0Foo\0private" => 'priv', - ), - array('public', 'empty'), - ), - array( - Caster::EXCLUDE_VERBOSE | Caster::EXCLUDE_EMPTY | Caster::EXCLUDE_STRICT, - array( - 'empty' => false, - ), - array('public', 'empty'), - ), - ); - } + public function provideFilter() + { + return array( + array( + 0, + array(), + ), + array( + Caster::EXCLUDE_PUBLIC, + array( + 'null' => null, + 'empty' => false, + 'public' => 'pub', + ), + ), + array( + Caster::EXCLUDE_NULL, + array( + 'null' => null, + ), + ), + array( + Caster::EXCLUDE_EMPTY, + array( + 'null' => null, + 'empty' => false, + ), + ), + array( + Caster::EXCLUDE_VIRTUAL, + array( + "\0~\0virtual" => 'virt', + ), + ), + array( + Caster::EXCLUDE_DYNAMIC, + array( + "\0+\0dynamic" => 'dyn', + ), + ), + array( + Caster::EXCLUDE_PROTECTED, + array( + "\0*\0protected" => 'prot', + ), + ), + array( + Caster::EXCLUDE_PRIVATE, + array( + "\0Foo\0private" => 'priv', + ), + ), + array( + Caster::EXCLUDE_VERBOSE, + array( + 'public' => 'pub', + "\0*\0protected" => 'prot', + ), + array('public', "\0*\0protected"), + ), + array( + Caster::EXCLUDE_NOT_IMPORTANT, + array( + 'null' => null, + 'empty' => false, + "\0~\0virtual" => 'virt', + "\0+\0dynamic" => 'dyn', + "\0Foo\0private" => 'priv', + ), + array('public', "\0*\0protected"), + ), + array( + Caster::EXCLUDE_VIRTUAL | Caster::EXCLUDE_DYNAMIC, + array( + "\0~\0virtual" => 'virt', + "\0+\0dynamic" => 'dyn', + ), + ), + array( + Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_VERBOSE, + $this->referenceArray, + array('public', "\0*\0protected"), + ), + array( + Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_EMPTY, + array( + 'null' => null, + 'empty' => false, + "\0~\0virtual" => 'virt', + "\0+\0dynamic" => 'dyn', + "\0*\0protected" => 'prot', + "\0Foo\0private" => 'priv', + ), + array('public', 'empty'), + ), + array( + Caster::EXCLUDE_VERBOSE | Caster::EXCLUDE_EMPTY | Caster::EXCLUDE_STRICT, + array( + 'empty' => false, + ), + array('public', 'empty'), + ), + ); + } - /** - * @requires PHP 7.0 - */ - public function testAnonymousClass() - { - $c = eval('return new class extends stdClass { private $foo = "foo"; };'); + /** + * @requires PHP 7.0 + */ + public function testAnonymousClass() + { + $c = eval('return new class extends stdClass { private $foo = "foo"; };'); - $this->assertDumpMatchesFormat( - <<<'EOTXT' + $this->assertDumpMatchesFormat( + <<<'EOTXT' stdClass@anonymous { -foo: "foo" } EOTXT - , $c - ); + , $c + ); - $c = eval('return new class { private $foo = "foo"; };'); + $c = eval('return new class { private $foo = "foo"; };'); - $this->assertDumpMatchesFormat( - <<<'EOTXT' + $this->assertDumpMatchesFormat( + <<<'EOTXT' @anonymous { -foo: "foo" } EOTXT - , $c - ); - } + , $c + ); + } } diff --git a/htdocs/includes/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php b/htdocs/includes/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php new file mode 100644 index 00000000000..2e348040f31 --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Tests/Caster/ExceptionCasterTest.php @@ -0,0 +1,225 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\ExceptionCaster; +use Symfony\Component\VarDumper\Caster\FrameStub; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +class ExceptionCasterTest extends TestCase +{ + use VarDumperTestTrait; + + private function getTestException($msg, &$ref = null) + { + return new \Exception(''.$msg); + } + + protected function tearDown() + { + ExceptionCaster::$srcContext = 1; + ExceptionCaster::$traceArgs = true; + } + + public function testDefaultSettings() + { + $ref = array('foo'); + $e = $this->getTestException('foo', $ref); + + $expectedDump = <<<'EODUMP' +Exception { + #message: "foo" + #code: 0 + #file: "%sExceptionCasterTest.php" + #line: 27 + -trace: { + %sExceptionCasterTest.php:27: { + : { + : return new \Exception(''.$msg); + : } + } + %sExceptionCasterTest.php:%d: { + : $ref = array('foo'); + : $e = $this->getTestException('foo', $ref); + : + arguments: { + $msg: "foo" + &$ref: array:1 [ …1] + } + } +%A +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $e); + $this->assertSame(array('foo'), $ref); + } + + public function testSeek() + { + $e = $this->getTestException(2); + + $expectedDump = <<<'EODUMP' +{ + %sExceptionCasterTest.php:27: { + : { + : return new \Exception(''.$msg); + : } + } + %sExceptionCasterTest.php:%d: { + : { + : $e = $this->getTestException(2); + : + arguments: { + $msg: 2 + } + } +%A +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $this->getDump($e, 'trace')); + } + + public function testNoArgs() + { + $e = $this->getTestException(1); + ExceptionCaster::$traceArgs = false; + + $expectedDump = <<<'EODUMP' +Exception { + #message: "1" + #code: 0 + #file: "%sExceptionCasterTest.php" + #line: 27 + -trace: { + %sExceptionCasterTest.php:27: { + : { + : return new \Exception(''.$msg); + : } + } + %sExceptionCasterTest.php:%d: { + : { + : $e = $this->getTestException(1); + : ExceptionCaster::$traceArgs = false; + } +%A +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $e); + } + + public function testNoSrcContext() + { + $e = $this->getTestException(1); + ExceptionCaster::$srcContext = -1; + + $expectedDump = <<<'EODUMP' +Exception { + #message: "1" + #code: 0 + #file: "%sExceptionCasterTest.php" + #line: 27 + -trace: { + %sExceptionCasterTest.php: 27 + %sExceptionCasterTest.php: %d +%A +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $e); + } + + public function testHtmlDump() + { + $e = $this->getTestException(1); + ExceptionCaster::$srcContext = -1; + + $cloner = new VarCloner(); + $cloner->setMaxItems(1); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($e)->withRefHandles(false), true); + + $expectedDump = <<<'EODUMP' +Exception { + #message: "1" + #code: 0 + #file: "%sTests%eCaster%eExceptionCasterTest.php" + #line: 27 + -trace: { + %sVarDumper%eTests%eCaster%eExceptionCasterTest.php: 27 + …%d + } +} + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + /** + * @requires function Twig\Template::getSourceContext + */ + public function testFrameWithTwig() + { + require_once dirname(__DIR__).'/Fixtures/Twig.php'; + + $f = array( + new FrameStub(array( + 'file' => dirname(__DIR__).'/Fixtures/Twig.php', + 'line' => 20, + 'class' => '__TwigTemplate_VarDumperFixture_u75a09', + )), + new FrameStub(array( + 'file' => dirname(__DIR__).'/Fixtures/Twig.php', + 'line' => 21, + 'class' => '__TwigTemplate_VarDumperFixture_u75a09', + 'object' => new \__TwigTemplate_VarDumperFixture_u75a09(null, __FILE__), + )), + ); + + $expectedDump = <<<'EODUMP' +array:2 [ + 0 => { + class: "__TwigTemplate_VarDumperFixture_u75a09" + src: { + %sTwig.php:1: { + : + : foo bar + : twig source + } + } + } + 1 => { + class: "__TwigTemplate_VarDumperFixture_u75a09" + object: __TwigTemplate_VarDumperFixture_u75a09 { + %A + } + src: { + %sExceptionCasterTest.php:2: { + : foo bar + : twig source + : + } + } + } +] + +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $f); + } +} diff --git a/htdocs/includes/symfony/var-dumper/Tests/Caster/PdoCasterTest.php b/htdocs/includes/symfony/var-dumper/Tests/Caster/PdoCasterTest.php index faa65341170..31bfac7e2da 100644 --- a/htdocs/includes/symfony/var-dumper/Tests/Caster/PdoCasterTest.php +++ b/htdocs/includes/symfony/var-dumper/Tests/Caster/PdoCasterTest.php @@ -11,47 +11,54 @@ namespace Symfony\Component\VarDumper\Tests\Caster; +use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Caster\PdoCaster; use Symfony\Component\VarDumper\Cloner\Stub; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; /** * @author Nicolas Grekas */ -class PdoCasterTest extends \PHPUnit_Framework_TestCase +class PdoCasterTest extends TestCase { - /** - * @requires extension pdo_sqlite - */ - public function testCastPdo() - { - $pdo = new \PDO('sqlite::memory:'); - $pdo->setAttribute(\PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array($pdo))); + use VarDumperTestTrait; - $cast = PdoCaster::castPdo($pdo, array(), new Stub(), false); + /** + * @requires extension pdo_sqlite + */ + public function testCastPdo() + { + $pdo = new \PDO('sqlite::memory:'); + $pdo->setAttribute(\PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array($pdo))); - $this->assertInstanceOf('Symfony\Component\VarDumper\Caster\EnumStub', $cast["\0~\0attributes"]); + $cast = PdoCaster::castPdo($pdo, array(), new Stub(), false); - $attr = $cast["\0~\0attributes"] = $cast["\0~\0attributes"]->value; - $this->assertInstanceOf('Symfony\Component\VarDumper\Caster\ConstStub', $attr['CASE']); - $this->assertSame('NATURAL', $attr['CASE']->class); - $this->assertSame('BOTH', $attr['DEFAULT_FETCH_MODE']->class); + $this->assertInstanceOf('Symfony\Component\VarDumper\Caster\EnumStub', $cast["\0~\0attributes"]); - $xCast = array( - "\0~\0inTransaction" => $pdo->inTransaction(), - "\0~\0attributes" => array( - 'CASE' => $attr['CASE'], - 'ERRMODE' => $attr['ERRMODE'], - 'PERSISTENT' => false, - 'DRIVER_NAME' => 'sqlite', - 'ORACLE_NULLS' => $attr['ORACLE_NULLS'], - 'CLIENT_VERSION' => $pdo->getAttribute(\PDO::ATTR_CLIENT_VERSION), - 'SERVER_VERSION' => $pdo->getAttribute(\PDO::ATTR_SERVER_VERSION), - 'STATEMENT_CLASS' => array('PDOStatement'), - 'DEFAULT_FETCH_MODE' => $attr['DEFAULT_FETCH_MODE'], - ), - ); - unset($cast["\0~\0attributes"]['STATEMENT_CLASS'][1]); + $attr = $cast["\0~\0attributes"] = $cast["\0~\0attributes"]->value; + $this->assertInstanceOf('Symfony\Component\VarDumper\Caster\ConstStub', $attr['CASE']); + $this->assertSame('NATURAL', $attr['CASE']->class); + $this->assertSame('BOTH', $attr['DEFAULT_FETCH_MODE']->class); - $this->assertSame($xCast, $cast); - } + $xDump = <<<'EODUMP' +array:2 [ + "\x00~\x00inTransaction" => false + "\x00~\x00attributes" => array:9 [ + "CASE" => NATURAL + "ERRMODE" => SILENT + "PERSISTENT" => false + "DRIVER_NAME" => "sqlite" + "ORACLE_NULLS" => NATURAL + "CLIENT_VERSION" => "%s" + "SERVER_VERSION" => "%s" + "STATEMENT_CLASS" => array:%d [ + 0 => "PDOStatement"%A + ] + "DEFAULT_FETCH_MODE" => BOTH + ] +] +EODUMP; + + $this->assertDumpMatchesFormat($xDump, $cast); + } } diff --git a/htdocs/includes/symfony/var-dumper/Tests/Caster/RedisCasterTest.php b/htdocs/includes/symfony/var-dumper/Tests/Caster/RedisCasterTest.php new file mode 100644 index 00000000000..b096dfe7b6f --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Tests/Caster/RedisCasterTest.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Nicolas Grekas + * @requires extension redis + */ +class RedisCasterTest extends TestCase +{ + use VarDumperTestTrait; + + public function testNotConnected() + { + $redis = new \Redis(); + + if (defined('HHVM_VERSION_ID')) { + $xCast = <<<'EODUMP' +Redis { + #host: "" +%A +} +EODUMP; + } else { + $xCast = <<<'EODUMP' +Redis { + isConnected: false +} +EODUMP; + } + + $this->assertDumpMatchesFormat($xCast, $redis); + } + + public function testConnected() + { + $redis = new \Redis(); + if (!@$redis->connect('127.0.0.1')) { + $e = error_get_last(); + self::markTestSkipped($e['message']); + } + + if (defined('HHVM_VERSION_ID')) { + $xCast = <<<'EODUMP' +Redis { + #host: "127.0.0.1" +%A +} +EODUMP; + } else { + $xCast = <<<'EODUMP' +Redis { + +"socket": Redis Socket Buffer resource + isConnected: true + host: "127.0.0.1" + port: 6379 + auth: null + dbNum: 0 + timeout: 0.0 + persistentId: null + options: { + READ_TIMEOUT: 0.0 + SERIALIZER: NONE + PREFIX: null + SCAN: NORETRY + } +} +EODUMP; + } + + $this->assertDumpMatchesFormat($xCast, $redis); + } +} diff --git a/htdocs/includes/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php b/htdocs/includes/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php index 0d7147fbcd2..63500b9ef4d 100644 --- a/htdocs/includes/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php +++ b/htdocs/includes/symfony/var-dumper/Tests/Caster/ReflectionCasterTest.php @@ -11,22 +11,24 @@ namespace Symfony\Component\VarDumper\Tests\Caster; +use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Test\VarDumperTestTrait; use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo; +use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass; /** * @author Nicolas Grekas */ -class ReflectionCasterTest extends \PHPUnit_Framework_TestCase +class ReflectionCasterTest extends TestCase { - use VarDumperTestTrait; + use VarDumperTestTrait; - public function testReflectionCaster() - { - $var = new \ReflectionClass('ReflectionClass'); + public function testReflectionCaster() + { + $var = new \ReflectionClass('ReflectionClass'); - $this->assertDumpMatchesFormat( - <<<'EOTXT' + $this->assertDumpMatchesFormat( + <<<'EOTXT' ReflectionClass { +name: "ReflectionClass" %Aimplements: array:%d [ @@ -49,23 +51,23 @@ ReflectionClass { "export" => ReflectionMethod { +name: "export" +class: "ReflectionClass" - parameters: { +%A parameters: { $%s: ReflectionParameter { %A position: 0 %A } EOTXT - , $var - ); - } + , $var + ); + } - public function testClosureCaster() - { - $a = $b = 123; - $var = function ($x) use ($a, &$b) {}; + public function testClosureCaster() + { + $a = $b = 123; + $var = function ($x) use ($a, &$b) {}; - $this->assertDumpMatchesFormat( - <<assertDumpMatchesFormat( + <<assertDumpMatchesFormat( - <<<'EOTXT' + $this->assertDumpMatchesFormat( + <<<'EOTXT' ReflectionParameter { +name: "arg1" position: 0 - typeHint: "Symfony\Component\VarDumper\Tests\Caster\NotExistingClass" + typeHint: "Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass" default: null } EOTXT - , $var - ); - } + , $var + ); + } - /** - * @requires PHP 7.0 - */ - public function testReflectionParameterScalar() - { - $f = eval('return function (int $a) {};'); - $var = new \ReflectionParameter($f, 0); + /** + * @requires PHP 7.0 + */ + public function testReflectionParameterScalar() + { + $f = eval('return function (int $a) {};'); + $var = new \ReflectionParameter($f, 0); - $this->assertDumpMatchesFormat( - <<<'EOTXT' + $this->assertDumpMatchesFormat( + <<<'EOTXT' ReflectionParameter { +name: "a" position: 0 typeHint: "int" } EOTXT - , $var - ); - } + , $var + ); + } - /** - * @requires PHP 7.0 - */ - public function testReturnType() - { - $f = eval('return function ():int {};'); - $line = __LINE__ - 1; + /** + * @requires PHP 7.0 + */ + public function testReturnType() + { + $f = eval('return function ():int {};'); + $line = __LINE__ - 1; - $this->assertDumpMatchesFormat( - <<assertDumpMatchesFormat( + <<baz(); - $r = new \ReflectionGenerator($g); + /** + * @requires PHP 7.0 + */ + public function testGenerator() + { + if (extension_loaded('xdebug')) { + $this->markTestSkipped('xdebug is active'); + } - $xDump = <<<'EODUMP' + $generator = new GeneratorDemo(); + $generator = $generator->baz(); + + $expectedDump = <<<'EODUMP' Generator { this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} executing: { Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz(): { - %sGeneratorDemo.php:14: """ - {\n - yield from bar();\n - }\n - """ + %sGeneratorDemo.php:14: { + : { + : yield from bar(); + : } + } } } + closed: false } EODUMP; - $this->assertDumpMatchesFormat($xDump, $g); + $this->assertDumpMatchesFormat($expectedDump, $generator); - foreach ($g as $v) { - break; - } + foreach ($generator as $v) { + break; + } - $xDump = <<<'EODUMP' + $expectedDump = <<<'EODUMP' array:2 [ 0 => ReflectionGenerator { this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …} trace: { - 3. Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() ==> yield(): { - src: { - %sGeneratorDemo.php:9: """ - {\n - yield 1;\n - }\n - """ - } + %sGeneratorDemo.php:9: { + : { + : yield 1; + : } } - 2. Symfony\Component\VarDumper\Tests\Fixtures\bar() ==> Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo(): { - src: { - %sGeneratorDemo.php:20: """ - {\n - yield from GeneratorDemo::foo();\n - }\n - """ - } + %sGeneratorDemo.php:20: { + : { + : yield from GeneratorDemo::foo(); + : } } - 1. Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz() ==> Symfony\Component\VarDumper\Tests\Fixtures\bar(): { - src: { - %sGeneratorDemo.php:14: """ - {\n - yield from bar();\n - }\n - """ - } + %sGeneratorDemo.php:14: { + : { + : yield from bar(); + : } } } + closed: false } 1 => Generator { executing: { Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo(): { - %sGeneratorDemo.php:10: """ - yield 1;\n - }\n - \n - """ + %sGeneratorDemo.php:10: { + : yield 1; + : } + : + } } } + closed: false } ] EODUMP; - $this->assertDumpMatchesFormat($xDump, array($r, $r->getExecutingGenerator())); - } + $r = new \ReflectionGenerator($generator); + $this->assertDumpMatchesFormat($expectedDump, array($r, $r->getExecutingGenerator())); + + foreach ($generator as $v) { + } + + $expectedDump = <<<'EODUMP' +Generator { + closed: true +} +EODUMP; + $this->assertDumpMatchesFormat($expectedDump, $generator); + } } -function reflectionParameterFixture(NotExistingClass $arg1 = null, $arg2) +function reflectionParameterFixture(NotLoadableClass $arg1 = null, $arg2) { } diff --git a/htdocs/includes/symfony/var-dumper/Tests/Caster/SplCasterTest.php b/htdocs/includes/symfony/var-dumper/Tests/Caster/SplCasterTest.php index 5d71e8d379d..04044f68100 100644 --- a/htdocs/includes/symfony/var-dumper/Tests/Caster/SplCasterTest.php +++ b/htdocs/includes/symfony/var-dumper/Tests/Caster/SplCasterTest.php @@ -11,19 +11,20 @@ namespace Symfony\Component\VarDumper\Tests\Caster; +use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Test\VarDumperTestTrait; /** * @author Grégoire Pineau */ -class SplCasterTest extends \PHPUnit_Framework_TestCase +class SplCasterTest extends TestCase { - use VarDumperTestTrait; + use VarDumperTestTrait; - public function getCastFileInfoTests() - { - return array( - array(__FILE__, <<<'EOTXT' + public function getCastFileInfoTests() + { + return array( + array(__FILE__, <<<'EOTXT' SplFileInfo { %Apath: "%sCaster" filename: "SplCasterTest.php" @@ -48,8 +49,8 @@ SplFileInfo { link: false %A} EOTXT - ), - array('https://google.com/about', <<<'EOTXT' + ), + array('https://google.com/about', <<<'EOTXT' SplFileInfo { %Apath: "https://google.com" filename: "about" @@ -57,29 +58,23 @@ SplFileInfo { pathname: "https://google.com/about" extension: "" realPath: false - writable: false - readable: false - executable: false - file: false - dir: false - link: false %A} EOTXT - ), - ); - } + ), + ); + } - /** @dataProvider getCastFileInfoTests */ - public function testCastFileInfo($file, $dump) - { - $this->assertDumpMatchesFormat($dump, new \SplFileInfo($file)); - } + /** @dataProvider getCastFileInfoTests */ + public function testCastFileInfo($file, $dump) + { + $this->assertDumpMatchesFormat($dump, new \SplFileInfo($file)); + } - public function testCastFileObject() - { - $var = new \SplFileObject(__FILE__); - $var->setFlags(\SplFileObject::DROP_NEW_LINE | \SplFileObject::SKIP_EMPTY); - $dump = <<<'EOTXT' + public function testCastFileObject() + { + $var = new \SplFileObject(__FILE__); + $var->setFlags(\SplFileObject::DROP_NEW_LINE | \SplFileObject::SKIP_EMPTY); + $dump = <<<'EOTXT' SplFileObject { %Apath: "%sCaster" filename: "SplCasterTest.php" @@ -102,10 +97,10 @@ SplFileObject { file: true dir: false link: false -%AcsvControl: array:2 [ +%AcsvControl: array:%d [ 0 => "," 1 => """ - ] +%A] flags: DROP_NEW_LINE|SKIP_EMPTY maxLineLen: 0 fstat: array:26 [ @@ -121,6 +116,32 @@ SplFileObject { key: 0 } EOTXT; - $this->assertDumpMatchesFormat($dump, $var); - } + $this->assertDumpMatchesFormat($dump, $var); + } + + /** + * @dataProvider provideCastSplDoublyLinkedList + */ + public function testCastSplDoublyLinkedList($modeValue, $modeDump) + { + $var = new \SplDoublyLinkedList(); + $var->setIteratorMode($modeValue); + $dump = <<assertDumpMatchesFormat($dump, $var); + } + + public function provideCastSplDoublyLinkedList() + { + return array( + array(\SplDoublyLinkedList::IT_MODE_FIFO, 'IT_MODE_FIFO | IT_MODE_KEEP'), + array(\SplDoublyLinkedList::IT_MODE_LIFO, 'IT_MODE_LIFO | IT_MODE_KEEP'), + array(\SplDoublyLinkedList::IT_MODE_FIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_FIFO | IT_MODE_DELETE'), + array(\SplDoublyLinkedList::IT_MODE_LIFO | \SplDoublyLinkedList::IT_MODE_DELETE, 'IT_MODE_LIFO | IT_MODE_DELETE'), + ); + } } diff --git a/htdocs/includes/symfony/var-dumper/Tests/Caster/StubCasterTest.php b/htdocs/includes/symfony/var-dumper/Tests/Caster/StubCasterTest.php new file mode 100644 index 00000000000..887d3d82a4f --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Tests/Caster/StubCasterTest.php @@ -0,0 +1,171 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Caster\ArgsStub; +use Symfony\Component\VarDumper\Caster\ClassStub; +use Symfony\Component\VarDumper\Caster\LinkStub; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\HtmlDumper; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; +use Symfony\Component\VarDumper\Tests\Fixtures\FooInterface; + +class StubCasterTest extends TestCase +{ + use VarDumperTestTrait; + + public function testArgsStubWithDefaults($foo = 234, $bar = 456) + { + $args = array(new ArgsStub(array(123), __FUNCTION__, __CLASS__)); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => { + $foo: 123 + } +] +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $args); + } + + public function testArgsStubWithExtraArgs($foo = 234) + { + $args = array(new ArgsStub(array(123, 456), __FUNCTION__, __CLASS__)); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => { + $foo: 123 + ...: { + 456 + } + } +] +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $args); + } + + public function testArgsStubNoParamWithExtraArgs() + { + $args = array(new ArgsStub(array(123), __FUNCTION__, __CLASS__)); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => { + 123 + } +] +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $args); + } + + public function testArgsStubWithClosure() + { + $args = array(new ArgsStub(array(123), '{closure}', null)); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => { + 123 + } +] +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $args); + } + + public function testLinkStub() + { + $var = array(new LinkStub(__CLASS__, 0, __FILE__)); + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dumper->setDisplayOptions(array('fileLinkFormat' => '%f:%l')); + $dump = $dumper->dump($cloner->cloneVar($var), true); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "Symfony\Component\VarDumper\Tests\Caster\StubCasterTest" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + public function testClassStub() + { + $var = array(new ClassStub('hello', array(FooInterface::class, 'foo'))); + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($var), true, array('fileLinkFormat' => '%f:%l')); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "hello" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + public function testClassStubWithNotExistingClass() + { + $var = array(new ClassStub(NotExisting::class)); + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($var), true); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "Symfony\Component\VarDumper\Tests\Caster\NotExisting" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } + + public function testClassStubWithNotExistingMethod() + { + $var = array(new ClassStub('hello', array(FooInterface::class, 'missing'))); + + $cloner = new VarCloner(); + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $dump = $dumper->dump($cloner->cloneVar($var), true, array('fileLinkFormat' => '%f:%l')); + + $expectedDump = <<<'EODUMP' +array:1 [ + 0 => "hello" +] + +EODUMP; + + $this->assertStringMatchesFormat($expectedDump, $dump); + } +} diff --git a/htdocs/includes/symfony/var-dumper/Tests/Caster/XmlReaderCasterTest.php b/htdocs/includes/symfony/var-dumper/Tests/Caster/XmlReaderCasterTest.php new file mode 100644 index 00000000000..b324d1db9ef --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Tests/Caster/XmlReaderCasterTest.php @@ -0,0 +1,248 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\VarDumper\Tests\Caster; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\VarDumper\Test\VarDumperTestTrait; + +/** + * @author Baptiste Clavié + */ +class XmlReaderCasterTest extends TestCase +{ + use VarDumperTestTrait; + + /** @var \XmlReader */ + private $reader; + + protected function setUp() + { + $this->reader = new \XmlReader(); + $this->reader->open(__DIR__.'/../Fixtures/xml_reader.xml'); + } + + protected function tearDown() + { + $this->reader->close(); + } + + public function testParserProperty() + { + $this->reader->setParserProperty(\XMLReader::SUBST_ENTITIES, true); + + $expectedDump = <<<'EODUMP' +XMLReader { + +nodeType: NONE + parserProperties: { + SUBST_ENTITIES: true + …3 + } + …12 +} +EODUMP; + + $this->assertDumpMatchesFormat($expectedDump, $this->reader); + } + + /** + * @dataProvider provideNodes + */ + public function testNodes($seek, $expectedDump) + { + while ($seek--) { + $this->reader->read(); + } + $this->assertDumpMatchesFormat($expectedDump, $this->reader); + } + + public function provideNodes() + { + return array( + array(0, <<<'EODUMP' +XMLReader { + +nodeType: NONE + …13 +} +EODUMP + ), + array(1, <<<'EODUMP' +XMLReader { + +localName: "foo" + +nodeType: ELEMENT + +baseURI: "%sxml_reader.xml" + …11 +} +EODUMP + ), + array(2, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: SIGNIFICANT_WHITESPACE + +depth: 1 + +value: """ + \n + + """ + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ), + array(3, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: ELEMENT + +depth: 1 + +baseURI: "%sxml_reader.xml" + …10 +} +EODUMP + ), + array(4, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: END_ELEMENT + +depth: 1 + +baseURI: "%sxml_reader.xml" + …10 +} +EODUMP + ), + array(6, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: ELEMENT + +depth: 1 + +isEmptyElement: true + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ), + array(9, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: TEXT + +depth: 2 + +value: "With text" + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ), + array(12, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: ELEMENT + +depth: 1 + +attributeCount: 2 + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ), + array(13, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: END_ELEMENT + +depth: 1 + +baseURI: "%sxml_reader.xml" + …10 +} +EODUMP + ), + array(15, <<<'EODUMP' +XMLReader { + +localName: "bar" + +nodeType: ELEMENT + +depth: 1 + +attributeCount: 1 + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ), + array(16, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: SIGNIFICANT_WHITESPACE + +depth: 2 + +value: """ + \n + + """ + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ), + array(17, <<<'EODUMP' +XMLReader { + +localName: "baz" + +prefix: "baz" + +nodeType: ELEMENT + +depth: 2 + +namespaceURI: "http://symfony.com" + +baseURI: "%sxml_reader.xml" + …8 +} +EODUMP + ), + array(18, <<<'EODUMP' +XMLReader { + +localName: "baz" + +prefix: "baz" + +nodeType: END_ELEMENT + +depth: 2 + +namespaceURI: "http://symfony.com" + +baseURI: "%sxml_reader.xml" + …8 +} +EODUMP + ), + array(19, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: SIGNIFICANT_WHITESPACE + +depth: 2 + +value: """ + \n + + """ + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ), + array(21, <<<'EODUMP' +XMLReader { + +localName: "#text" + +nodeType: SIGNIFICANT_WHITESPACE + +depth: 1 + +value: "\n" + +baseURI: "%sxml_reader.xml" + …9 +} +EODUMP + ), + array(22, <<<'EODUMP' +XMLReader { + +localName: "foo" + +nodeType: END_ELEMENT + +baseURI: "%sxml_reader.xml" + …11 +} +EODUMP + ), + ); + } +} diff --git a/htdocs/includes/symfony/var-dumper/Tests/CliDumperTest.php b/htdocs/includes/symfony/var-dumper/Tests/CliDumperTest.php index cd6d64d1c03..9a7404cea05 100644 --- a/htdocs/includes/symfony/var-dumper/Tests/CliDumperTest.php +++ b/htdocs/includes/symfony/var-dumper/Tests/CliDumperTest.php @@ -11,43 +11,46 @@ namespace Symfony\Component\VarDumper\Tests; +use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Cloner\VarCloner; use Symfony\Component\VarDumper\Dumper\CliDumper; use Symfony\Component\VarDumper\Test\VarDumperTestTrait; +use Twig\Environment; +use Twig\Loader\FilesystemLoader; /** * @author Nicolas Grekas */ -class CliDumperTest extends \PHPUnit_Framework_TestCase +class CliDumperTest extends TestCase { - use VarDumperTestTrait; + use VarDumperTestTrait; - public function testGet() - { - require __DIR__.'/Fixtures/dumb-var.php'; + public function testGet() + { + require __DIR__.'/Fixtures/dumb-var.php'; - $dumper = new CliDumper('php://output'); - $dumper->setColors(false); - $cloner = new VarCloner(); - $cloner->addCasters(array( - ':stream' => function ($res, $a) { - unset($a['uri'], $a['wrapper_data']); + $dumper = new CliDumper('php://output'); + $dumper->setColors(false); + $cloner = new VarCloner(); + $cloner->addCasters(array( + ':stream' => function ($res, $a) { + unset($a['uri'], $a['wrapper_data']); - return $a; - }, - )); - $data = $cloner->cloneVar($var); + return $a; + }, + )); + $data = $cloner->cloneVar($var); - ob_start(); - $dumper->dump($data); - $out = ob_get_clean(); - $out = preg_replace('/[ \t]+$/m', '', $out); - $intMax = PHP_INT_MAX; - $res = (int) $var['res']; + ob_start(); + $dumper->dump($data); + $out = ob_get_clean(); + $out = preg_replace('/[ \t]+$/m', '', $out); + $intMax = PHP_INT_MAX; + $res = (int) $var['res']; - $r = defined('HHVM_VERSION') ? '' : '#%d'; - $this->assertStringMatchesFormat( - <<assertStringMatchesFormat( + << 1 0 => &1 null @@ -62,15 +65,12 @@ array:24 [ 7 => b"é\\x00" "[]" => [] "res" => stream resource {@{$res} - wrapper_type: "plainfile" +%A wrapper_type: "plainfile" stream_type: "STDIO" mode: "r" unread_bytes: 0 seekable: true - timed_out: false - blocked: true - eof: false - options: [] +%A options: [] } "obj" => Symfony\Component\VarDumper\Tests\Fixture\DumbFoo {#%d +foo: "foo" @@ -105,20 +105,20 @@ array:24 [ ] EOTXT - , - $out - ); - } + , + $out + ); + } - /** - * @requires extension xml - */ - public function testXmlResource() - { - $var = xml_parser_create(); + /** + * @requires extension xml + */ + public function testXmlResource() + { + $var = xml_parser_create(); - $this->assertDumpMatchesFormat( - <<assertDumpMatchesFormat( + <<<'EOTXT' xml resource { current_byte_index: %i current_column_number: %i @@ -126,199 +126,257 @@ xml resource { error_code: XML_ERROR_NONE } EOTXT - , - $var - ); - } + , + $var + ); + } - public function testClosedResource() - { - if (defined('HHVM_VERSION') && HHVM_VERSION_ID < 30600) { - $this->markTestSkipped(); - } + public function testJsonCast() + { + $var = (array) json_decode('{"0":{},"1":null}'); + foreach ($var as &$v) { + } + $var[] = &$v; + $var[''] = 2; - $var = fopen(__FILE__, 'r'); - fclose($var); + if (\PHP_VERSION_ID >= 70200) { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +array:4 [ + 0 => {} + 1 => &1 null + 2 => &1 null + "" => 2 +] +EOTXT + , + $var + ); + } else { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +array:4 [ + "0" => {} + "1" => &1 null + 0 => &1 null + "" => 2 +] +EOTXT + , + $var + ); + } + } - $dumper = new CliDumper('php://output'); - $dumper->setColors(false); - $cloner = new VarCloner(); - $data = $cloner->cloneVar($var); + public function testObjectCast() + { + $var = (object) array(1 => 1); + $var->{1} = 2; - ob_start(); - $dumper->dump($data); - $out = ob_get_clean(); - $res = (int) $var; + if (\PHP_VERSION_ID >= 70200) { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +{ + +"1": 2 +} +EOTXT + , + $var + ); + } else { + $this->assertDumpMatchesFormat( + <<<'EOTXT' +{ + +1: 1 + +"1": 2 +} +EOTXT + , + $var + ); + } + } - $this->assertStringMatchesFormat( - <<markTestSkipped(); + } + + $var = fopen(__FILE__, 'r'); + fclose($var); + + $dumper = new CliDumper('php://output'); + $dumper->setColors(false); + $cloner = new VarCloner(); + $data = $cloner->cloneVar($var); + + ob_start(); + $dumper->dump($data); + $out = ob_get_clean(); + $res = (int) $var; + + $this->assertStringMatchesFormat( + << 'bar'), + ); - $dumper = new CliDumper(); - $dumper->setColors(false); - $cloner = new VarCloner(); - $cloner->addCasters(array( - ':stream' => function ($res, $a) { - unset($a['wrapper_data']); + $this->assertDumpEquals( + << (3) "foo" + 2 => (3) "bar" + ] +] +EOTXT + , + $var + ); - return $a; - }, - )); - $cloner->addCasters(array( - ':stream' => eval('return function () use ($twig) { + putenv('DUMP_LIGHT_ARRAY='); + putenv('DUMP_STRING_LENGTH='); + } + + /** + * @requires function Twig\Template::getSourceContext + */ + public function testThrowingCaster() + { + $out = fopen('php://memory', 'r+b'); + + require_once __DIR__.'/Fixtures/Twig.php'; + $twig = new \__TwigTemplate_VarDumperFixture_u75a09(new Environment(new FilesystemLoader())); + + $dumper = new CliDumper(); + $dumper->setColors(false); + $cloner = new VarCloner(); + $cloner->addCasters(array( + ':stream' => function ($res, $a) { + unset($a['wrapper_data']); + + return $a; + }, + )); + $cloner->addCasters(array( + ':stream' => eval('return function () use ($twig) { try { $twig->render(array()); - } catch (\Twig_Error_Runtime $e) { + } catch (\Twig\Error\RuntimeError $e) { throw $e->getPrevious(); } };'), - )); - $line = __LINE__ - 2; - $ref = (int) $out; + )); + $ref = (int) $out; - $data = $cloner->cloneVar($out); - $dumper->dump($data, $out); - rewind($out); - $out = stream_get_contents($out); + $data = $cloner->cloneVar($out); + $dumper->dump($data, $out); + $out = stream_get_contents($out, -1, 0); - if (method_exists($twig, 'getSource')) { - $twig = <<assertStringMatchesFormat( - <<assertStringMatchesFormat( + <<doDisplay(\$context, \$blocks); + : } catch (Twig%sError \$e) { + } + %sTemplate.php:%d: { + : { + : \$this->displayWithErrorHandling(\$this->env->mergeGlobals(\$context), array_merge(\$this->blocks, \$blocks)); + : } + } + %sTemplate.php:%d: { + : try { + : \$this->display(\$context); + : } catch (%s \$e) { + } + %sCliDumperTest.php:%d: { +%A + } + } + } +%Awrapper_type: "PHP" stream_type: "MEMORY" mode: "%s+b" unread_bytes: 0 seekable: true uri: "php://memory" - timed_out: false - blocked: true - eof: false - options: [] - ⚠: Symfony\Component\VarDumper\Exception\ThrowingCasterException {{$r} - #message: "Unexpected Exception thrown from a caster: Foobar" - -trace: { - %d. __TwigTemplate_VarDumperFixture_u75a09->doDisplay() ==> new Exception(): { - src: { - %sTwig.php:19: """ - // line 2\\n - throw new \Exception('Foobar');\\n - }\\n - """ -{$twig} } - } - %d. Twig_Template->displayWithErrorHandling() ==> __TwigTemplate_VarDumperFixture_u75a09->doDisplay(): { - src: { - %sTemplate.php:%d: """ - try {\\n - \$this->doDisplay(\$context, \$blocks);\\n - } catch (Twig_Error \$e) {\\n - """ - } - } - %d. Twig_Template->display() ==> Twig_Template->displayWithErrorHandling(): { - src: { - %sTemplate.php:%d: """ - {\\n - \$this->displayWithErrorHandling(\$this->env->mergeGlobals(\$context), array_merge(\$this->blocks, \$blocks));\\n - }\\n - """ - } - } - %d. Twig_Template->render() ==> Twig_Template->display(): { - src: { - %sTemplate.php:%d: """ - try {\\n - \$this->display(\$context);\\n - } catch (Exception \$e) {\\n - """ - } - } - %d. %slosure%s() ==> Twig_Template->render(): { - src: { - %sCliDumperTest.php:{$line}: """ - }\\n - };'),\\n - ));\\n - """ - } - } - } - } +%Aoptions: [] } EOTXT - , - $out - ); - } + , + $out + ); + } - public function testRefsInProperties() - { - $var = (object) array('foo' => 'foo'); - $var->bar = &$var->foo; + public function testRefsInProperties() + { + $var = (object) array('foo' => 'foo'); + $var->bar = &$var->foo; - $dumper = new CliDumper(); - $dumper->setColors(false); - $cloner = new VarCloner(); + $dumper = new CliDumper(); + $dumper->setColors(false); + $cloner = new VarCloner(); - $out = fopen('php://memory', 'r+b'); - $data = $cloner->cloneVar($var); - $dumper->dump($data, $out); - rewind($out); - $out = stream_get_contents($out); + $data = $cloner->cloneVar($var); + $out = $dumper->dump($data, true); - $r = defined('HHVM_VERSION') ? '' : '#%d'; - $this->assertStringMatchesFormat( - <<assertStringMatchesFormat( + <<getSpecialVars(); + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + * @requires PHP 5.6 + */ + public function testSpecialVars56() + { + $var = $this->getSpecialVars(); - $this->assertDumpEquals( - <<assertDumpEquals( + <<<'EOTXT' array:3 [ 0 => array:1 [ 0 => &1 array:1 [ @@ -333,38 +391,38 @@ array:3 [ 2 => &2 array:1 [&2] ] EOTXT - , - $var - ); - } + , + $var + ); + } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ - public function testGlobalsNoExt() - { - $var = $this->getSpecialVars(); - unset($var[0]); - $out = ''; + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testGlobalsNoExt() + { + $var = $this->getSpecialVars(); + unset($var[0]); + $out = ''; - $dumper = new CliDumper(function ($line, $depth) use (&$out) { - if ($depth >= 0) { - $out .= str_repeat(' ', $depth).$line."\n"; - } - }); - $dumper->setColors(false); - $cloner = new VarCloner(); + $dumper = new CliDumper(function ($line, $depth) use (&$out) { + if ($depth >= 0) { + $out .= str_repeat(' ', $depth).$line."\n"; + } + }); + $dumper->setColors(false); + $cloner = new VarCloner(); - $refl = new \ReflectionProperty($cloner, 'useExt'); - $refl->setAccessible(true); - $refl->setValue($cloner, false); + $refl = new \ReflectionProperty($cloner, 'useExt'); + $refl->setAccessible(true); + $refl->setValue($cloner, false); - $data = $cloner->cloneVar($var); - $dumper->dump($data); + $data = $cloner->cloneVar($var); + $dumper->dump($data); - $this->assertSame( - <<assertSame( + <<<'EOTXT' array:2 [ 1 => array:1 [ "GLOBALS" => &1 array:1 [ @@ -375,38 +433,38 @@ array:2 [ ] EOTXT - , - $out - ); - } + , + $out + ); + } - /** - * @runInSeparateProcess - * @preserveGlobalState disabled - */ - public function testBuggyRefs() - { - if (PHP_VERSION_ID >= 50600) { - $this->markTestSkipped('PHP 5.6 fixed refs counting'); - } + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testBuggyRefs() + { + if (\PHP_VERSION_ID >= 50600) { + $this->markTestSkipped('PHP 5.6 fixed refs counting'); + } - $var = $this->getSpecialVars(); - $var = $var[0]; + $var = $this->getSpecialVars(); + $var = $var[0]; - $dumper = new CliDumper(); - $dumper->setColors(false); - $cloner = new VarCloner(); + $dumper = new CliDumper(); + $dumper->setColors(false); + $cloner = new VarCloner(); - $data = $cloner->cloneVar($var)->withMaxDepth(3); - $out = ''; - $dumper->dump($data, function ($line, $depth) use (&$out) { - if ($depth >= 0) { - $out .= str_repeat(' ', $depth).$line."\n"; - } - }); + $data = $cloner->cloneVar($var)->withMaxDepth(3); + $out = ''; + $dumper->dump($data, function ($line, $depth) use (&$out) { + if ($depth >= 0) { + $out .= str_repeat(' ', $depth).$line."\n"; + } + }); - $this->assertSame( - <<assertSame( + <<<'EOTXT' array:1 [ 0 => array:1 [ 0 => array:1 [ @@ -416,26 +474,41 @@ array:1 [ ] EOTXT - , - $out - ); - } + , + $out + ); + } - private function getSpecialVars() - { - foreach (array_keys($GLOBALS) as $var) { - if ('GLOBALS' !== $var) { - unset($GLOBALS[$var]); - } - } + public function testIncompleteClass() + { + $unserializeCallbackHandler = ini_set('unserialize_callback_func', null); + $var = unserialize('O:8:"Foo\Buzz":0:{}'); + ini_set('unserialize_callback_func', $unserializeCallbackHandler); - $var = function &() { - $var = array(); - $var[] = &$var; + $this->assertDumpMatchesFormat( + <<parent = false; + public function __construct(Twig\Environment $env = null, $path = null) + { + if (null !== $env) { + parent::__construct($env); + } + $this->parent = false; + $this->blocks = array(); + $this->path = $path; + } - $this->blocks = array( - ); - } + protected function doDisplay(array $context, array $blocks = array()) + { + // line 2 + throw new \Exception('Foobar'); + } - protected function doDisplay(array $context, array $blocks = array()) - { - // line 2 - throw new \Exception('Foobar'); - } + public function getTemplateName() + { + return 'foo.twig'; + } - public function getTemplateName() - { - return 'foo.twig'; - } + public function getDebugInfo() + { + return array(20 => 1, 21 => 2); + } - public function getDebugInfo() - { - return array (19 => 2); - } + public function getSourceContext() + { + return new Twig\Source(" foo bar\n twig source\n\n", 'foo.twig', $this->path ?: __FILE__); + } } -/* foo bar*/ -/* twig source*/ -/* */ diff --git a/htdocs/includes/symfony/var-dumper/Tests/Fixtures/xml_reader.xml b/htdocs/includes/symfony/var-dumper/Tests/Fixtures/xml_reader.xml new file mode 100644 index 00000000000..740c399fc44 --- /dev/null +++ b/htdocs/includes/symfony/var-dumper/Tests/Fixtures/xml_reader.xml @@ -0,0 +1,10 @@ + + + + + With text + + + + + diff --git a/htdocs/includes/symfony/var-dumper/Tests/HtmlDumperTest.php b/htdocs/includes/symfony/var-dumper/Tests/HtmlDumperTest.php index 3090435c5d4..96fcbac5b49 100644 --- a/htdocs/includes/symfony/var-dumper/Tests/HtmlDumperTest.php +++ b/htdocs/includes/symfony/var-dumper/Tests/HtmlDumperTest.php @@ -11,44 +11,45 @@ namespace Symfony\Component\VarDumper\Tests; +use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Cloner\VarCloner; use Symfony\Component\VarDumper\Dumper\HtmlDumper; /** * @author Nicolas Grekas */ -class HtmlDumperTest extends \PHPUnit_Framework_TestCase +class HtmlDumperTest extends TestCase { - public function testGet() - { - require __DIR__.'/Fixtures/dumb-var.php'; + public function testGet() + { + require __DIR__.'/Fixtures/dumb-var.php'; - $dumper = new HtmlDumper('php://output'); - $dumper->setDumpHeader(''); - $dumper->setDumpBoundaries('', ''); - $cloner = new VarCloner(); - $cloner->addCasters(array( - ':stream' => function ($res, $a) { - unset($a['uri'], $a['wrapper_data']); + $dumper = new HtmlDumper('php://output'); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $cloner = new VarCloner(); + $cloner->addCasters(array( + ':stream' => function ($res, $a) { + unset($a['uri'], $a['wrapper_data']); - return $a; - }, - )); - $data = $cloner->cloneVar($var); + return $a; + }, + )); + $data = $cloner->cloneVar($var); - ob_start(); - $dumper->dump($data); - $out = ob_get_clean(); - $out = preg_replace('/[ \t]+$/m', '', $out); - $var['file'] = htmlspecialchars($var['file'], ENT_QUOTES, 'UTF-8'); - $intMax = PHP_INT_MAX; - preg_match('/sf-dump-\d+/', $out, $dumpId); - $dumpId = $dumpId[0]; - $res = (int) $var['res']; + ob_start(); + $dumper->dump($data); + $out = ob_get_clean(); + $out = preg_replace('/[ \t]+$/m', '', $out); + $var['file'] = htmlspecialchars($var['file'], ENT_QUOTES, 'UTF-8'); + $intMax = PHP_INT_MAX; + preg_match('/sf-dump-\d+/', $out, $dumpId); + $dumpId = $dumpId[0]; + $res = (int) $var['res']; - $r = defined('HHVM_VERSION') ? '' : '#%d'; - $this->assertStringMatchesFormat( - <<#%d'; + $this->assertStringMatchesFormat( + <<array:24 [ "number" => 1 0 => &1 null @@ -59,26 +60,24 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase 4 => INF 5 => -INF 6 => {$intMax} - "str" => "d&%s;j&%s;\\n" - 7 => b"&%s;\\x00" + "str" => "d&%s;j&%s;\\n" + 7 => b"&%s;\\x00" "[]" => [] "res" => stream resource @{$res} - wrapper_type: "plainfile" +%A wrapper_type: "plainfile" stream_type: "STDIO" mode: "r" unread_bytes: 0 seekable: true - timed_out: false - blocked: true - eof: false - options: [] +%A options: [] } "obj" => DumbFoo {#%d +foo: "foo" +"bar": "bar" } "closure" => Closure {{$r} - class: "Symfony\Component\VarDumper\Tests\HtmlDumperTest" + class: "Symfony\Component\VarDumper\Tests\HtmlDumperTest" this: HtmlDumperTest {{$r} &%s;} parameters: { \$a: {} @@ -87,7 +86,8 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase default: null } } - file: "{$var['file']}" + file: "%sTests%eFixtures%edumb-var.php" line: "{$var['line']} to {$var['line']}" } "line" => {$var['line']} @@ -107,36 +107,57 @@ class HtmlDumperTest extends \PHPUnit_Framework_TestCase EOTXT - , + , + $out + ); + } - $out - ); - } + public function testCharset() + { + $var = mb_convert_encoding('Словарь', 'CP1251', 'UTF-8'); - public function testCharset() - { - $var = mb_convert_encoding('Словарь', 'CP1251', 'UTF-8'); + $dumper = new HtmlDumper('php://output', 'CP1251'); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $cloner = new VarCloner(); - $dumper = new HtmlDumper('php://output', 'CP1251'); - $dumper->setDumpHeader(''); - $dumper->setDumpBoundaries('', ''); - $cloner = new VarCloner(); + $data = $cloner->cloneVar($var); + $out = $dumper->dump($data, true); - $data = $cloner->cloneVar($var); - $out = fopen('php://memory', 'r+b'); - $dumper->dump($data, $out); - rewind($out); - $out = stream_get_contents($out); - - $this->assertStringMatchesFormat( - <<assertStringMatchesFormat( + <<<'EOTXT' b"Словарь" EOTXT - , + , + $out + ); + } - $out - ); - } + public function testAppend() + { + $out = fopen('php://memory', 'r+b'); + + $dumper = new HtmlDumper(); + $dumper->setDumpHeader(''); + $dumper->setDumpBoundaries('', ''); + $cloner = new VarCloner(); + + $dumper->dump($cloner->cloneVar(123), $out); + $dumper->dump($cloner->cloneVar(456), $out); + + $out = stream_get_contents($out, -1, 0); + + $this->assertSame(<<<'EOTXT' +123 + +456 + + +EOTXT + , + $out + ); + } } diff --git a/htdocs/includes/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php b/htdocs/includes/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php index 3295797179c..c76f6be4144 100644 --- a/htdocs/includes/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php +++ b/htdocs/includes/symfony/var-dumper/Tests/Test/VarDumperTestTraitTest.php @@ -11,20 +11,21 @@ namespace Symfony\Component\VarDumper\Tests\Test; +use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Test\VarDumperTestTrait; -class VarDumperTestTraitTest extends \PHPUnit_Framework_TestCase +class VarDumperTestTraitTest extends TestCase { - use VarDumperTestTrait; + use VarDumperTestTrait; - public function testItComparesLargeData() - { - $howMany = 700; - $data = array_fill_keys(range(0, $howMany), array('a', 'b', 'c', 'd')); + public function testItComparesLargeData() + { + $howMany = 700; + $data = array_fill_keys(range(0, $howMany), array('a', 'b', 'c', 'd')); - $expected = sprintf("array:%d [\n", $howMany + 1); - for ($i = 0; $i <= $howMany; ++$i) { - $expected .= << array:4 [ 0 => "a" 1 => "b" @@ -32,9 +33,9 @@ class VarDumperTestTraitTest extends \PHPUnit_Framework_TestCase 3 => "d" ]\n EODUMP; - } - $expected .= "]\n"; + } + $expected .= "]\n"; - $this->assertDumpEquals($expected, $data); - } + $this->assertDumpEquals($expected, $data); + } } diff --git a/htdocs/includes/symfony/var-dumper/Tests/VarClonerTest.php b/htdocs/includes/symfony/var-dumper/Tests/VarClonerTest.php index 31e3a40ae04..2234ba6902d 100644 --- a/htdocs/includes/symfony/var-dumper/Tests/VarClonerTest.php +++ b/htdocs/includes/symfony/var-dumper/Tests/VarClonerTest.php @@ -11,21 +11,22 @@ namespace Symfony\Component\VarDumper\Tests; +use PHPUnit\Framework\TestCase; use Symfony\Component\VarDumper\Cloner\VarCloner; /** * @author Nicolas Grekas */ -class VarClonerTest extends \PHPUnit_Framework_TestCase +class VarClonerTest extends TestCase { - public function testMaxIntBoundary() - { - $data = array(PHP_INT_MAX => 123); + public function testMaxIntBoundary() + { + $data = array(PHP_INT_MAX => 123); - $cloner = new VarCloner(); - $clone = $cloner->cloneVar($data); + $cloner = new VarCloner(); + $clone = $cloner->cloneVar($data); - $expected = << Array @@ -41,6 +42,10 @@ Symfony\Component\VarDumper\Cloner\Data Object [handle] => 0 [refCount] => 0 [position] => 1 + [attr] => Array + ( + ) + ) ) @@ -52,23 +57,25 @@ Symfony\Component\VarDumper\Cloner\Data Object ) + [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0 [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 ) EOTXT; - $this->assertSame(sprintf($expected, PHP_INT_MAX), print_r($clone, true)); - } + $this->assertSame(sprintf($expected, PHP_INT_MAX), print_r($clone, true)); + } - public function testClone() - { - $json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}'); + public function testClone() + { + $json = json_decode('{"1":{"var":"val"},"2":{"var":"val"}}'); - $cloner = new VarCloner(); - $clone = $cloner->cloneVar($json); + $cloner = new VarCloner(); + $clone = $cloner->cloneVar($json); - $expected = << Array @@ -84,6 +91,10 @@ Symfony\Component\VarDumper\Cloner\Data Object [handle] => %i [refCount] => 0 [position] => 1 + [attr] => Array + ( + ) + ) ) @@ -99,6 +110,10 @@ Symfony\Component\VarDumper\Cloner\Data Object [handle] => %i [refCount] => 0 [position] => 2 + [attr] => Array + ( + ) + ) [\000+\0002] => Symfony\Component\VarDumper\Cloner\Stub Object @@ -110,6 +125,10 @@ Symfony\Component\VarDumper\Cloner\Data Object [handle] => %i [refCount] => 0 [position] => 3 + [attr] => Array + ( + ) + ) ) @@ -126,30 +145,112 @@ Symfony\Component\VarDumper\Cloner\Data Object ) + [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0 [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 ) EOTXT; - $this->assertStringMatchesFormat($expected, print_r($clone, true)); + $this->assertStringMatchesFormat($expected, print_r($clone, true)); + } + + public function testJsonCast() + { + if (ini_get('xdebug.overload_var_dump') == 2) { + $this->markTestSkipped('xdebug is active'); + } + + $data = (array) json_decode('{"1":{}}'); + + $cloner = new VarCloner(); + $clone = $cloner->cloneVar($data); + + $expected = <<<'EOTXT' +object(Symfony\Component\VarDumper\Cloner\Data)#%i (6) { + ["data":"Symfony\Component\VarDumper\Cloner\Data":private]=> + array(2) { + [0]=> + array(1) { + [0]=> + object(Symfony\Component\VarDumper\Cloner\Stub)#%i (8) { + ["type"]=> + string(5) "array" + ["class"]=> + string(5) "assoc" + ["value"]=> + int(1) + ["cut"]=> + int(0) + ["handle"]=> + int(0) + ["refCount"]=> + int(0) + ["position"]=> + int(1) + ["attr"]=> + array(0) { + } + } } + [1]=> + array(1) { + ["1"]=> + object(Symfony\Component\VarDumper\Cloner\Stub)#%i (8) { + ["type"]=> + string(6) "object" + ["class"]=> + string(8) "stdClass" + ["value"]=> + NULL + ["cut"]=> + int(0) + ["handle"]=> + int(%i) + ["refCount"]=> + int(0) + ["position"]=> + int(0) + ["attr"]=> + array(0) { + } + } + } + } + ["position":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(0) + ["key":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(0) + ["maxDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(20) + ["maxItemsPerDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(-1) + ["useRefHandles":"Symfony\Component\VarDumper\Cloner\Data":private]=> + int(-1) +} - public function testCaster() - { - $cloner = new VarCloner(array( - '*' => function ($obj, $array) { - return array('foo' => 123); - }, - __CLASS__ => function ($obj, $array) { - ++$array['foo']; +EOTXT; + ob_start(); + var_dump($clone); + $this->assertStringMatchesFormat(\PHP_VERSION_ID >= 70200 ? str_replace('"1"', '1', $expected) : $expected, ob_get_clean()); + } - return $array; - }, - )); - $clone = $cloner->cloneVar($this); + public function testCaster() + { + $cloner = new VarCloner(array( + '*' => function ($obj, $array) { + return array('foo' => 123); + }, + __CLASS__ => function ($obj, $array) { + ++$array['foo']; - $expected = <<cloneVar($this); + + $expected = << Array @@ -165,6 +266,10 @@ Symfony\Component\VarDumper\Cloner\Data Object [handle] => %i [refCount] => 0 [position] => 1 + [attr] => Array + ( + ) + ) ) @@ -176,12 +281,14 @@ Symfony\Component\VarDumper\Cloner\Data Object ) + [position:Symfony\Component\VarDumper\Cloner\Data:private] => 0 + [key:Symfony\Component\VarDumper\Cloner\Data:private] => 0 [maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20 [maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1 [useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1 ) EOTXT; - $this->assertStringMatchesFormat($expected, print_r($clone, true)); - } + $this->assertStringMatchesFormat($expected, print_r($clone, true)); + } } diff --git a/htdocs/includes/symfony/var-dumper/composer.json b/htdocs/includes/symfony/var-dumper/composer.json index 05955f69430..44dbdebcce2 100644 --- a/htdocs/includes/symfony/var-dumper/composer.json +++ b/htdocs/includes/symfony/var-dumper/composer.json @@ -20,9 +20,14 @@ "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "twig/twig": "~1.20|~2.0" + "ext-iconv": "*", + "twig/twig": "~1.34|~2.4" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" }, "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", "ext-symfony_debug": "" }, "autoload": { @@ -35,7 +40,7 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } } } diff --git a/htdocs/includes/symfony/var-dumper/phpunit.xml.dist b/htdocs/includes/symfony/var-dumper/phpunit.xml.dist index bb16a3a4ec0..4a25f42db82 100644 --- a/htdocs/includes/symfony/var-dumper/phpunit.xml.dist +++ b/htdocs/includes/symfony/var-dumper/phpunit.xml.dist @@ -5,9 +5,13 @@ backupGlobals="false" colors="true" bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true" > + + diff --git a/htdocs/includes/tcpdi/tcpdi.php b/htdocs/includes/tcpdi/tcpdi.php index f4c0bd00391..aaa1d70c095 100644 --- a/htdocs/includes/tcpdi/tcpdi.php +++ b/htdocs/includes/tcpdi/tcpdi.php @@ -483,7 +483,7 @@ class TCPDI extends FPDF_TPL { reset ($value[1]); - while (list($k, $v) = each($value[1])) { + foreach ($value[1] as $k => $v) { $this->_straightOut($k . ' '); $this->pdf_write_value($v); } diff --git a/htdocs/includes/tecnickcom/tcpdf/include/tcpdf_static.php b/htdocs/includes/tecnickcom/tcpdf/include/tcpdf_static.php index 969bb165e62..d66ec482549 100644 --- a/htdocs/includes/tecnickcom/tcpdf/include/tcpdf_static.php +++ b/htdocs/includes/tecnickcom/tcpdf/include/tcpdf_static.php @@ -49,7 +49,8 @@ * @version 1.1.1 * @author Nicola Asuni - info@tecnick.com */ -class TCPDF_STATIC { +class TCPDF_STATIC +{ /** * Current TCPDF version. @@ -114,7 +115,8 @@ class TCPDF_STATIC { * @since 5.9.012 (2010-11-10) * @public static */ - public static function getTCPDFVersion() { + public static function getTCPDFVersion() + { return self::$tcpdf_version; } @@ -124,7 +126,8 @@ class TCPDF_STATIC { * @since 6.0.000 (2013-03-16) * @public static */ - public static function getTCPDFProducer() { + public static function getTCPDFProducer() + { return "\x54\x43\x50\x44\x46\x20".self::getTCPDFVersion()."\x20\x28\x68\x74\x74\x70\x3a\x2f\x2f\x77\x77\x77\x2e\x74\x63\x70\x64\x66\x2e\x6f\x72\x67\x29"; } @@ -134,7 +137,8 @@ class TCPDF_STATIC { * @since 4.6.025 (2009-08-17) * @public static */ - public static function set_mqr($mqr) { + public static function set_mqr($mqr) + { if (!defined('PHP_VERSION_ID')) { $version = PHP_VERSION; define('PHP_VERSION_ID', (($version[0] * 10000) + ($version[2] * 100) + $version[4])); @@ -150,7 +154,8 @@ class TCPDF_STATIC { * @since 4.6.025 (2009-08-17) * @public static */ - public static function get_mqr() { + public static function get_mqr() + { if (!defined('PHP_VERSION_ID')) { $version = PHP_VERSION; define('PHP_VERSION_ID', (($version[0] * 10000) + ($version[2] * 100) + $version[4])); @@ -168,9 +173,10 @@ class TCPDF_STATIC { * @since 5.9.204 (2013-01-28) * @public static */ - public static function isValidURL($url) { + public static function isValidURL($url) + { $headers = @get_headers($url); - return (strpos($headers[0], '200') !== false); + return (strpos($headers[0], '200') !== false); } /** @@ -190,7 +196,8 @@ class TCPDF_STATIC { * @since (4.5.019) 2009-02-28 * @public static */ - public static function removeSHY($txt='', $unicode=true) { + public static function removeSHY($txt = '', $unicode = true) + { $txt = preg_replace('/([\\xc2]{1}[\\xad]{1})/', '', $txt); if (!$unicode) { $txt = preg_replace('/([\\xad]{1})/', '', $txt); @@ -208,7 +215,8 @@ class TCPDF_STATIC { * @since 4.4.002 (2008-12-09) * @public static */ - public static function getBorderMode($brd, $position='start', $opencell=true) { + public static function getBorderMode($brd, $position = 'start', $opencell = true) + { if ((!$opencell) OR empty($brd)) { return $brd; } @@ -280,7 +288,8 @@ class TCPDF_STATIC { * @since 4.5.044 (2009-04-16) * @public static */ - public static function empty_string($str) { + public static function empty_string($str) + { return (is_null($str) OR (is_string($str) AND (strlen($str) == 0))); } @@ -292,7 +301,8 @@ class TCPDF_STATIC { * @since 4.5.000 (2008-12-31) * @public static */ - public static function getObjFilename($type='tmp', $file_id='') { + public static function getObjFilename($type = 'tmp', $file_id = '') + { return tempnam(K_PATH_CACHE, '__tcpdf_'.$file_id.'_'.$type.'_'.md5(TCPDF_STATIC::getRandomSeed()).'_'); } @@ -302,7 +312,8 @@ class TCPDF_STATIC { * @return string escaped string. * @public static */ - public static function _escape($s) { + public static function _escape($s) + { // the chr(13) substitution fixes the Bugs item #1421290. return strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r')); } @@ -314,7 +325,8 @@ class TCPDF_STATIC { * @since 5.9.121 (2011-09-28) * @public static */ - public static function _escapeXML($str) { + public static function _escapeXML($str) + { $replaceTable = array("\0" => '', '&' => '&', '<' => '<', '>' => '>'); $str = strtr($str, $replaceTable); return $str; @@ -327,7 +339,8 @@ class TCPDF_STATIC { * @since 4.5.029 (2009-03-19) * @public static */ - public static function objclone($object) { + public static function objclone($object) + { if (($object instanceof Imagick) AND (version_compare(phpversion('imagick'), '3.0.1') !== 1)) { // on the versions after 3.0.1 the clone() method was deprecated in favour of clone keyword return @$object->clone(); @@ -342,7 +355,8 @@ class TCPDF_STATIC { * @since 5.9.086 * @public static */ - public static function sendOutputData($data, $length) { + public static function sendOutputData($data, $length) + { if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) { // the content length may vary if the server is using compression header('Content-Length: '.$length); @@ -358,7 +372,8 @@ class TCPDF_STATIC { * @return replaced page content and updated $diff parameter as array. * @public static */ - public static function replacePageNumAliases($page, $replace, $diff=0) { + public static function replacePageNumAliases($page, $replace, $diff = 0) + { foreach ($replace as $rep) { foreach ($rep[3] as $a) { if (strpos($page, $a) !== false) { @@ -377,7 +392,8 @@ class TCPDF_STATIC { * @since 5.9.152 (2012-03-23) * @public static */ - public static function getTimestamp($date) { + public static function getTimestamp($date) + { if (($date[0] == 'D') AND ($date[1] == ':')) { // remove date prefix if present $date = substr($date, 2); @@ -392,7 +408,8 @@ class TCPDF_STATIC { * @since 5.9.152 (2012-03-23) * @public static */ - public static function getFormattedDate($time) { + public static function getFormattedDate($time) + { return substr_replace(date('YmdHisO', intval($time)), '\'', (0 - 2), 0).'\''; } @@ -404,7 +421,8 @@ class TCPDF_STATIC { * @since 5.9.006 (2010-10-19) * @public static */ - public static function getRandomSeed($seed='') { + public static function getRandomSeed($seed = '') + { $rnd = uniqid(rand().microtime(true), true); if (function_exists('posix_getpid')) { $rnd .= posix_getpid(); @@ -427,7 +445,8 @@ class TCPDF_STATIC { * @since 2.0.000 (2008-01-02) * @public static */ - public static function _md5_16($str) { + public static function _md5_16($str) + { return pack('H*', md5($str)); } @@ -441,12 +460,13 @@ class TCPDF_STATIC { * @since 5.0.005 (2010-05-11) * @public static */ - public static function _AES($key, $text) { + public static function _AES($key, $text) + { // padding (RFC 2898, PKCS #5: Password-Based Cryptography Specification Version 2.0) $padding = 16 - (strlen($text) % 16); $text .= str_repeat(chr($padding), $padding); if (extension_loaded('openssl')) { - $iv = openssl_random_pseudo_bytes (openssl_cipher_iv_length('aes-256-cbc')); + $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc')); $text = openssl_encrypt($text, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); return $iv.substr($text, 0, -16); } @@ -466,7 +486,8 @@ class TCPDF_STATIC { * @since TODO * @public static */ - public static function _AESnopad($key, $text) { + public static function _AESnopad($key, $text) + { if (extension_loaded('openssl')) { $iv = str_repeat("\x00", openssl_cipher_iv_length('aes-256-cbc')); $text = openssl_encrypt($text, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); @@ -489,7 +510,8 @@ class TCPDF_STATIC { * @author Klemen Vodopivec, Nicola Asuni * @public static */ - public static function _RC4($key, $text, &$last_enc_key, &$last_enc_key_c) { + public static function _RC4($key, $text, &$last_enc_key, &$last_enc_key_c) + { if (function_exists('mcrypt_encrypt') AND ($out = @mcrypt_encrypt(MCRYPT_ARCFOUR, $key, $text, MCRYPT_MODE_STREAM, ''))) { // try to use mcrypt function if exist return $out; @@ -533,7 +555,8 @@ class TCPDF_STATIC { * @author Nicola Asuni * @public static */ - public static function getUserPermissionCode($permissions, $mode=0) { + public static function getUserPermissionCode($permissions, $mode = 0) + { $options = array( 'owner' => 2, // bit 2 -- inverted logic: cleared by default 'print' => 4, // bit 3 @@ -570,7 +593,8 @@ class TCPDF_STATIC { * @author Nicola Asuni * @public static */ - public static function convertHexStringToString($bs) { + public static function convertHexStringToString($bs) + { $string = ''; // string to be returned $bslength = strlen($bs); if (($bslength % 2) != 0) { @@ -592,7 +616,8 @@ class TCPDF_STATIC { * @author Nicola Asuni * @public static */ - public static function convertStringToHexString($s) { + public static function convertStringToHexString($s) + { $bs = ''; $chars = preg_split('//', $s, -1, PREG_SPLIT_NO_EMPTY); foreach ($chars as $c) { @@ -609,7 +634,8 @@ class TCPDF_STATIC { * @author Nicola Asuni * @public static */ - public static function getEncPermissionsString($protection) { + public static function getEncPermissionsString($protection) + { $binprot = sprintf('%032b', $protection); $str = chr(bindec(substr($binprot, 24, 8))); $str .= chr(bindec(substr($binprot, 16, 8))); @@ -626,7 +652,8 @@ class TCPDF_STATIC { * @since 5.9.097 (2011-06-23) * @public static */ - public static function encodeNameObject($name) { + public static function encodeNameObject($name) + { $escname = ''; $length = strlen($name); for ($i = 0; $i < $length; ++$i) { @@ -650,7 +677,8 @@ class TCPDF_STATIC { * @since 4.8.000 (2009-09-06) * @public static */ - public static function getAnnotOptFromJSProp($prop, &$spot_colors, $rtl=false) { + public static function getAnnotOptFromJSProp($prop, &$spot_colors, $rtl = false) + { if (isset($prop['aopt']) AND is_array($prop['aopt'])) { // the annotation options area lready defined return $prop['aopt']; @@ -1016,8 +1044,9 @@ class TCPDF_STATIC { * @since 4.2.005 (2008-11-06) * @public static */ - public static function formatPageNumber($num) { - return number_format((float)$num, 0, '', '.'); + public static function formatPageNumber($num) + { + return number_format((float) $num, 0, '', '.'); } /** @@ -1028,8 +1057,9 @@ class TCPDF_STATIC { * @see addTOC(), addHTMLTOC() * @public static */ - public static function formatTOCPageNumber($num) { - return number_format((float)$num, 0, '', '.'); + public static function formatTOCPageNumber($num) + { + return number_format((float) $num, 0, '', '.'); } /** @@ -1040,7 +1070,8 @@ class TCPDF_STATIC { * @since 5.1.000 (2010-05-25) * @public static */ - public static function extractCSSproperties($cssdata) { + public static function extractCSSproperties($cssdata) + { if (empty($cssdata)) { return array(); } @@ -1136,7 +1167,8 @@ class TCPDF_STATIC { * @see setHtmlVSpace() * @public static */ - public static function fixHTMLCode($html, $default_css='', $tagvs='', $tidy_options='', &$tagvspaces) { + public static function fixHTMLCode($html, $default_css = '', $tagvs = '', $tidy_options = '', &$tagvspaces) + { // configure parameters for HTML Tidy if ($tidy_options === '') { $tidy_options = array ( @@ -1202,7 +1234,8 @@ class TCPDF_STATIC { * @since 5.1.000 (2010-05-25) * @public static */ - public static function isValidCSSSelectorForTag($dom, $key, $selector) { + public static function isValidCSSSelectorForTag($dom, $key, $selector) + { $valid = false; // value to be returned $tag = $dom[$key]['value']; $class = array(); @@ -1362,7 +1395,8 @@ class TCPDF_STATIC { * @since 5.1.000 (2010-05-25) * @public static */ - public static function getCSSdataArray($dom, $key, $css) { + public static function getCSSdataArray($dom, $key, $css) + { $cssarray = array(); // style to be returned // get parent CSS selectors $selectors = array(); @@ -1370,7 +1404,7 @@ class TCPDF_STATIC { $selectors = $dom[($dom[$key]['parent'])]['csssel']; } // get all styles that apply - foreach($css as $selector => $style) { + foreach ($css as $selector => $style) { $pos = strpos($selector, ' '); // get specificity $specificity = substr($selector, 0, $pos); @@ -1407,7 +1441,8 @@ class TCPDF_STATIC { * @since 5.9.070 (2011-04-19) * @public static */ - public static function getTagStyleFromCSSarray($css) { + public static function getTagStyleFromCSSarray($css) + { $tagstyle = ''; // value to be returned foreach ($css as $style) { // split single css commands @@ -1438,8 +1473,13 @@ class TCPDF_STATIC { * @since 4.4.004 (2008-12-10) * @public static */ - public static function intToRoman($number) { + public static function intToRoman($number) + { $roman = ''; + if ($number >= 4000) { + // do not represent numbers above 4000 in Roman numerals + return strval($number); + } while ($number >= 1000) { $roman .= 'M'; $number -= 1000; @@ -1504,7 +1544,8 @@ class TCPDF_STATIC { * @since 4.8.038 (2010-03-13) * @public static */ - public static function revstrpos($haystack, $needle, $offset = 0) { + public static function revstrpos($haystack, $needle, $offset = 0) + { $length = strlen($haystack); $offset = ($offset > 0)?($length - $offset):abs($offset); $pos = strpos(strrev($haystack), strrev($needle), $offset); @@ -1519,7 +1560,8 @@ class TCPDF_STATIC { * @since 4.9.012 (2010-04-12) * @public static */ - public static function getHyphenPatternsFromTEX($file) { + public static function getHyphenPatternsFromTEX($file) + { // TEX patterns are available at: // http://www.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/ $data = file_get_contents($file); @@ -1533,7 +1575,7 @@ class TCPDF_STATIC { $patterns_array = preg_split('/[\s]+/', $data); // create new language array of patterns $patterns = array(); - foreach($patterns_array as $val) { + foreach ($patterns_array as $val) { if (!TCPDF_STATIC::empty_string($val)) { $val = trim($val); $val = str_replace('\'', '\\\'', $val); @@ -1547,27 +1589,28 @@ class TCPDF_STATIC { /** * Get the Path-Painting Operators. * @param $style (string) Style of rendering. Possible values are: - *
      - *
    • S or D: Stroke the path.
    • - *
    • s or d: Close and stroke the path.
    • - *
    • f or F: Fill the path, using the nonzero winding number rule to determine the region to fill.
    • - *
    • f* or F*: Fill the path, using the even-odd rule to determine the region to fill.
    • - *
    • B or FD or DF: Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill.
    • - *
    • B* or F*D or DF*: Fill and then stroke the path, using the even-odd rule to determine the region to fill.
    • - *
    • b or fd or df: Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill.
    • - *
    • b or f*d or df*: Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill.
    • - *
    • CNZ: Clipping mode using the even-odd rule to determine which regions lie inside the clipping path.
    • - *
    • CEO: Clipping mode using the nonzero winding number rule to determine which regions lie inside the clipping path
    • - *
    • n: End the path object without filling or stroking it.
    • - *
    + *
      + *
    • S or D: Stroke the path.
    • + *
    • s or d: Close and stroke the path.
    • + *
    • f or F: Fill the path, using the nonzero winding number rule to determine the region to fill.
    • + *
    • f* or F*: Fill the path, using the even-odd rule to determine the region to fill.
    • + *
    • B or FD or DF: Fill and then stroke the path, using the nonzero winding number rule to determine the region to fill.
    • + *
    • B* or F*D or DF*: Fill and then stroke the path, using the even-odd rule to determine the region to fill.
    • + *
    • b or fd or df: Close, fill, and then stroke the path, using the nonzero winding number rule to determine the region to fill.
    • + *
    • b or f*d or df*: Close, fill, and then stroke the path, using the even-odd rule to determine the region to fill.
    • + *
    • CNZ: Clipping mode using the even-odd rule to determine which regions lie inside the clipping path.
    • + *
    • CEO: Clipping mode using the nonzero winding number rule to determine which regions lie inside the clipping path
    • + *
    • n: End the path object without filling or stroking it.
    • + *
    * @param $default (string) default style * @author Nicola Asuni * @since 5.0.000 (2010-04-30) * @public static */ - public static function getPathPaintOperator($style, $default='S') { + public static function getPathPaintOperator($style, $default = 'S') + { $op = ''; - switch($style) { + switch ($style) { case 'S': case 'D': { $op = 'S'; @@ -1644,7 +1687,8 @@ class TCPDF_STATIC { * @since 5.0.000 (2010-05-02) * @public static */ - public static function getTransformationMatrixProduct($ta, $tb) { + public static function getTransformationMatrixProduct($ta, $tb) + { $tm = array(); $tm[0] = ($ta[0] * $tb[0]) + ($ta[2] * $tb[1]); $tm[1] = ($ta[1] * $tb[0]) + ($ta[3] * $tb[1]); @@ -1663,7 +1707,8 @@ class TCPDF_STATIC { * @since 5.0.000 (2010-05-02) * @public static */ - public static function getSVGTransformMatrix($attribute) { + public static function getSVGTransformMatrix($attribute) + { // identity matrix $tm = array(1, 0, 0, 1, 0, 0); $transform = array(); @@ -1760,7 +1805,8 @@ class TCPDF_STATIC { * @since 5.0.000 (2010-05-04) * @public static */ - public static function getVectorsAngle($x1, $y1, $x2, $y2) { + public static function getVectorsAngle($x1, $y1, $x2, $y2) + { $dprod = ($x1 * $x2) + ($y1 * $y2); $dist1 = sqrt(($x1 * $x1) + ($y1 * $y1)); $dist2 = sqrt(($x2 * $x2) + ($y2 * $y2)); @@ -1787,14 +1833,15 @@ class TCPDF_STATIC { * @since 6.0.023 * @public static */ - public static function pregSplit($pattern, $modifiers, $subject, $limit=NULL, $flags=NULL) { + public static function pregSplit($pattern, $modifiers, $subject, $limit = null, $flags = null) + { // the bug only happens on PHP 5.2 when using the u modifier - if ((strpos($modifiers, 'u') === FALSE) OR (count(preg_split('//u', "\n\t", -1, PREG_SPLIT_NO_EMPTY)) == 2)) { + if ((strpos($modifiers, 'u') === false) OR (count(preg_split('//u', "\n\t", -1, PREG_SPLIT_NO_EMPTY)) == 2)) { return preg_split($pattern.$modifiers, $subject, $limit, $flags); } // preg_split is bugged - try alternative solution $ret = array(); - while (($nl = strpos($subject, "\n")) !== FALSE) { + while (($nl = strpos($subject, "\n")) !== false) { $ret = array_merge($ret, preg_split($pattern.$modifiers, substr($subject, 0, $nl), $limit, $flags)); $ret[] = "\n"; $subject = substr($subject, ($nl + 1)); @@ -1805,28 +1852,28 @@ class TCPDF_STATIC { return $ret; } - /** - * Wrapper to use fopen only with local files - * @param string $filename The full path to the file to open - * @param string $mode Acceses type for the file ('r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+', 'c', 'c+' or 'e') - * @return resource Returns a file pointer resource on success, or FALSE on error. - * @public static - */ - public static function fopenLocal($filename, $mode) - { - if (strpos($filename, '//') === 0) { - // Share folder on a (windows) server - // e.g.: "//[MyServerName]/[MySharedFolder]/" - // - // nothing to change - } elseif (strpos($filename, '://') === false) { - $filename = 'file://'.$filename; - } elseif (stream_is_local($filename) !== true) { - return false; - } + /** + * Wrapper to use fopen only with local files + * @param string $filename The full path to the file to open + * @param string $mode Acceses type for the file ('r', 'r+', 'w', 'w+', 'a', 'a+', 'x', 'x+', 'c', 'c+' or 'e') + * @return resource Returns a file pointer resource on success, or FALSE on error. + * @public static + */ + public static function fopenLocal($filename, $mode) + { + if (strpos($filename, '//') === 0) { + // Share folder on a (windows) server + // e.g.: "//[MyServerName]/[MySharedFolder]/" + // + // nothing to change + } elseif (strpos($filename, '://') === false) { + $filename = 'file://'.$filename; + } elseif (stream_is_local($filename) !== true) { + return false; + } - return fopen($filename, $mode); - } + return fopen($filename, $mode); + } /** * Check if the URL exist. @@ -1834,7 +1881,8 @@ class TCPDF_STATIC { * @return Returns TRUE if the URL exists; FALSE otherwise. * @public static */ - public static function url_exists($url) { + public static function url_exists($url) + { $crs = curl_init(); curl_setopt($crs, CURLOPT_URL, $url); curl_setopt($crs, CURLOPT_NOBODY, true); @@ -1861,7 +1909,8 @@ class TCPDF_STATIC { * @return Returns TRUE if the file or directory specified by filename exists; FALSE otherwise. * @public static */ - public static function file_exists($filename) { + public static function file_exists($filename) + { if (preg_match('|^https?://|', $filename) == 1) { return self::url_exists($filename); } @@ -1880,24 +1929,25 @@ class TCPDF_STATIC { * @since 6.0.025 * @public static */ - public static function fileGetContents($file) { + public static function fileGetContents($file) + { $alt = array($file); // if ((strlen($file) > 1) - && ($file[0] === '/') - && ($file[1] !== '/') - && !empty($_SERVER['DOCUMENT_ROOT']) - && ($_SERVER['DOCUMENT_ROOT'] !== '/') + && ($file[0] === '/') + && ($file[1] !== '/') + && !empty($_SERVER['DOCUMENT_ROOT']) + && ($_SERVER['DOCUMENT_ROOT'] !== '/') ) { - $findroot = strpos($file, $_SERVER['DOCUMENT_ROOT']); - if (($findroot === false) || ($findroot > 1)) { - $alt[] = htmlspecialchars_decode(urldecode($_SERVER['DOCUMENT_ROOT'].$file)); - } + $findroot = strpos($file, $_SERVER['DOCUMENT_ROOT']); + if (($findroot === false) || ($findroot > 1)) { + $alt[] = htmlspecialchars_decode(urldecode($_SERVER['DOCUMENT_ROOT'].$file)); + } } // $protocol = 'http'; if (!empty($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) { - $protocol .= 's'; + $protocol .= 's'; } // $url = $file; @@ -1908,26 +1958,26 @@ class TCPDF_STATIC { $alt[] = $url; // if (preg_match('%^(https?)://%', $url) - && empty($_SERVER['HTTP_HOST']) - && empty($_SERVER['DOCUMENT_ROOT']) + && empty($_SERVER['HTTP_HOST']) + && empty($_SERVER['DOCUMENT_ROOT']) ) { $urldata = parse_url($url); if (empty($urldata['query'])) { $host = $protocol.'://'.$_SERVER['HTTP_HOST']; if (strpos($url, $host) === 0) { - // convert URL to full server path - $tmp = str_replace($host, $_SERVER['DOCUMENT_ROOT'], $url); - $alt[] = htmlspecialchars_decode(urldecode($tmp)); + // convert URL to full server path + $tmp = str_replace($host, $_SERVER['DOCUMENT_ROOT'], $url); + $alt[] = htmlspecialchars_decode(urldecode($tmp)); } } } // if (isset($_SERVER['SCRIPT_URI']) - && !preg_match('%^(https?|ftp)://%', $file) - && !preg_match('%^//%', $file) + && !preg_match('%^(https?|ftp)://%', $file) + && !preg_match('%^//%', $file) ) { - $urldata = @parse_url($_SERVER['SCRIPT_URI']); - $alt[] = $urldata['scheme'].'://'.$urldata['host'].(($file[0] == '/') ? '' : '/').$file; + $urldata = @parse_url($_SERVER['SCRIPT_URI']); + $alt[] = $urldata['scheme'].'://'.$urldata['host'].(($file[0] == '/') ? '' : '/').$file; } // $alt = array_unique($alt); @@ -1937,7 +1987,7 @@ class TCPDF_STATIC { } $ret = @file_get_contents($path); if ( $ret != false ) { - return $ret; + return $ret; } // try to use CURL for URLs if (!ini_get('allow_url_fopen') @@ -1951,7 +2001,7 @@ class TCPDF_STATIC { curl_setopt($crs, CURLOPT_FAILONERROR, true); curl_setopt($crs, CURLOPT_RETURNTRANSFER, true); if ((ini_get('open_basedir') == '') && (!ini_get('safe_mode'))) { - curl_setopt($crs, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($crs, CURLOPT_FOLLOWLOCATION, true); } curl_setopt($crs, CURLOPT_CONNECTTIMEOUT, 5); curl_setopt($crs, CURLOPT_TIMEOUT, 30); @@ -1977,7 +2027,8 @@ class TCPDF_STATIC { * @since 5.2.000 (2010-06-02) * @public static */ - public static function _getULONG($str, $offset) { + public static function _getULONG($str, $offset) + { $v = unpack('Ni', substr($str, $offset, 4)); return $v['i']; } @@ -1991,7 +2042,8 @@ class TCPDF_STATIC { * @since 5.2.000 (2010-06-02) * @public static */ - public static function _getUSHORT($str, $offset) { + public static function _getUSHORT($str, $offset) + { $v = unpack('ni', substr($str, $offset, 2)); return $v['i']; } @@ -2005,7 +2057,8 @@ class TCPDF_STATIC { * @since 5.2.000 (2010-06-02) * @public static */ - public static function _getSHORT($str, $offset) { + public static function _getSHORT($str, $offset) + { $v = unpack('si', substr($str, $offset, 2)); return $v['i']; } @@ -2019,7 +2072,8 @@ class TCPDF_STATIC { * @since 5.9.123 (2011-09-30) * @public static */ - public static function _getFWORD($str, $offset) { + public static function _getFWORD($str, $offset) + { $v = self::_getUSHORT($str, $offset); if ($v > 0x7fff) { $v -= 0x10000; @@ -2036,7 +2090,8 @@ class TCPDF_STATIC { * @since 5.9.123 (2011-09-30) * @public static */ - public static function _getUFWORD($str, $offset) { + public static function _getUFWORD($str, $offset) + { $v = self::_getUSHORT($str, $offset); return $v; } @@ -2050,7 +2105,8 @@ class TCPDF_STATIC { * @since 5.9.123 (2011-09-30) * @public static */ - public static function _getFIXED($str, $offset) { + public static function _getFIXED($str, $offset) + { // mantissa $m = self::_getFWORD($str, $offset); // fraction @@ -2068,7 +2124,8 @@ class TCPDF_STATIC { * @since 5.2.000 (2010-06-02) * @public static */ - public static function _getBYTE($str, $offset) { + public static function _getBYTE($str, $offset) + { $v = unpack('Ci', substr($str, $offset, 1)); return $v['i']; } @@ -2082,7 +2139,8 @@ class TCPDF_STATIC { * @since 4.5.027 (2009-03-16) * @public static */ - public static function rfread($handle, $length) { + public static function rfread($handle, $length) + { $data = fread($handle, $length); if ($data === false) { return false; @@ -2100,7 +2158,8 @@ class TCPDF_STATIC { * @return 4-byte integer * @public static */ - public static function _freadint($f) { + public static function _freadint($f) + { $a = unpack('Ni', fread($f, 4)); return $a['i']; } @@ -2470,7 +2529,8 @@ class TCPDF_STATIC { * @since 5.0.010 (2010-05-17) * @public static */ - public static function getPageSizeFromFormat($format) { + public static function getPageSizeFromFormat($format) + { if (isset(self::$page_formats[$format])) { return self::$page_formats[$format]; } @@ -2492,7 +2552,8 @@ class TCPDF_STATIC { * @since 5.0.010 (2010-05-17) * @public static */ - public static function setPageBoxes($page, $type, $llx, $lly, $urx, $ury, $points=false, $k, $pagedim=array()) { + public static function setPageBoxes($page, $type, $llx, $lly, $urx, $ury, $points = false, $k, $pagedim = array()) + { if (!isset($pagedim[$page])) { // initialize array $pagedim[$page] = array(); @@ -2518,7 +2579,8 @@ class TCPDF_STATIC { * @since 5.0.010 (2010-05-17) * @public static */ - public static function swapPageBoxCoordinates($page, $pagedim) { + public static function swapPageBoxCoordinates($page, $pagedim) + { foreach (self::$pageboxes as $type) { // swap X and Y coordinates if (isset($pagedim[$page][$type])) { @@ -2539,7 +2601,8 @@ class TCPDF_STATIC { * @return (string) Canonical page layout name. * @public static */ - public static function getPageLayoutMode($layout='SinglePage') { + public static function getPageLayoutMode($layout = 'SinglePage') + { switch ($layout) { case 'default': case 'single': @@ -2582,7 +2645,8 @@ class TCPDF_STATIC { * @return (string) Canonical page mode name. * @public static */ - public static function getPageMode($mode='UseNone') { + public static function getPageMode($mode = 'UseNone') + { switch ($mode) { case 'UseNone': { $page_mode = 'UseNone'; @@ -2614,8 +2678,6 @@ class TCPDF_STATIC { } return $page_mode; } - - } // END OF TCPDF_STATIC CLASS //============================================================+ diff --git a/htdocs/index.php b/htdocs/index.php index ea0efebc720..be439300291 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -26,7 +26,7 @@ */ -define('CSRFCHECK_WITH_TOKEN', 1); // We force need to use a token to login when making a POST +define('CSRFCHECK_WITH_TOKEN', 1); // We force need to use a token to login when making a POST require 'main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; @@ -156,28 +156,28 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { require_once DOL_DOCUMENT_ROOT.'/core/class/workboardresponse.class.php'; // Number of actions to do (late) - if (!empty($conf->agenda->enabled) && $user->rights->agenda->myactions->read) { + if (!empty($conf->agenda->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_AGENDA) && $user->rights->agenda->myactions->read) { include_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; $board = new ActionComm($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of project opened - if (!empty($conf->projet->enabled) && $user->rights->projet->lire) { + if (!empty($conf->projet->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_PROJECT) && $user->rights->projet->lire) { include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $board = new Project($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of tasks to do (late) - if (!empty($conf->projet->enabled) && empty($conf->global->PROJECT_HIDE_TASKS) && $user->rights->projet->lire) { + if (!empty($conf->projet->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_PROJECT) && empty($conf->global->PROJECT_HIDE_TASKS) && $user->rights->projet->lire) { include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; $board = new Task($db); $dashboardlines[$board->element] = $board->load_board($user); } - // Number of commercial proposals open (expired) - if (!empty($conf->propal->enabled) && $user->rights->propale->lire) { + // Number of commercial customer proposals open (expired) + if (!empty($conf->propal->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->rights->propale->lire) { include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; $board = new Propal($db); $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened"); @@ -186,7 +186,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of supplier proposals open (expired) - if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire) { + if (!empty($conf->supplier_proposal->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && $user->rights->supplier_proposal->lire) { $langs->load("supplier_proposal"); include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php'; $board = new SupplierProposal($db); @@ -196,14 +196,14 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of customer orders a deal - if (!empty($conf->commande->enabled) && $user->rights->commande->lire) { + if (!empty($conf->commande->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->rights->commande->lire) { include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; $board = new Commande($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of suppliers orders a deal - if (!empty($conf->supplier_order->enabled) && $user->rights->fournisseur->commande->lire) { + if (!empty($conf->supplier_order->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && $user->rights->fournisseur->commande->lire) { include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; $board = new CommandeFournisseur($db); $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened"); @@ -211,7 +211,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of contract / services enabled (delayed) - if (!empty($conf->contrat->enabled) && $user->rights->contrat->lire) { + if (!empty($conf->contrat->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_CONTRACT) && $user->rights->contrat->lire) { include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $board = new Contrat($db); $dashboardlines[$board->element.'_inactive'] = $board->load_board($user, "inactive"); @@ -220,7 +220,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of tickets open - if (!empty($conf->ticket->enabled) && $user->rights->ticket->read) { + if (!empty($conf->ticket->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_TICKET) && $user->rights->ticket->read) { include_once DOL_DOCUMENT_ROOT.'/ticket/class/ticket.class.php'; $board = new Ticket($db); $dashboardlines[$board->element.'_opened'] = $board->load_board($user, "opened"); @@ -229,21 +229,21 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of invoices customers (paid) - if (!empty($conf->facture->enabled) && $user->rights->facture->lire) { + if (!empty($conf->facture->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_CUSTOMER) && $user->rights->facture->lire) { include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $board = new Facture($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of supplier invoices (paid) - if (!empty($conf->supplier_invoice->enabled) && !empty($user->rights->fournisseur->facture->lire)) { + if (!empty($conf->supplier_invoice->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_SUPPLIER) && !empty($user->rights->fournisseur->facture->lire)) { include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; $board = new FactureFournisseur($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of transactions to conciliate - if (!empty($conf->banque->enabled) && $user->rights->banque->lire && !$user->socid) { + if (!empty($conf->banque->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_BANK) && $user->rights->banque->lire && !$user->socid) { include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; $board = new Account($db); $nb = $board->countAccountToReconcile(); // Get nb of account to reconciliate @@ -253,14 +253,14 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of cheque to send - if (!empty($conf->banque->enabled) && $user->rights->banque->lire && !$user->socid && empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT)) { + if (!empty($conf->banque->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_BANK) && $user->rights->banque->lire && !$user->socid && empty($conf->global->BANK_DISABLE_CHECK_DEPOSIT)) { include_once DOL_DOCUMENT_ROOT.'/compta/paiement/cheque/class/remisecheque.class.php'; $board = new RemiseCheque($db); $dashboardlines[$board->element] = $board->load_board($user); } // Number of foundation members - if (!empty($conf->adherent->enabled) && $user->rights->adherent->lire && !$user->socid) { + if (!empty($conf->adherent->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_ADHERENT) && $user->rights->adherent->lire && !$user->socid) { include_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; $board = new Adherent($db); $dashboardlines[$board->element.'_shift'] = $board->load_board($user, 'shift'); @@ -268,21 +268,21 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } // Number of expense reports to approve - if (!empty($conf->expensereport->enabled) && $user->rights->expensereport->approve) { + if (!empty($conf->expensereport->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_EXPENSEREPORT) && $user->rights->expensereport->approve) { include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; $board = new ExpenseReport($db); $dashboardlines[$board->element.'_toapprove'] = $board->load_board($user, 'toapprove'); } // Number of expense reports to pay - if (!empty($conf->expensereport->enabled) && $user->rights->expensereport->to_paid) { + if (!empty($conf->expensereport->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_EXPENSEREPORT) && $user->rights->expensereport->to_paid) { include_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; $board = new ExpenseReport($db); $dashboardlines[$board->element.'_topay'] = $board->load_board($user, 'topay'); } // Number of holidays to approve - if (!empty($conf->holiday->enabled) && $user->rights->holiday->approve) { + if (!empty($conf->holiday->enabled) && empty($conf->global->MAIN_DISABLE_BLOCK_HOLIDAY) && $user->rights->holiday->approve) { include_once DOL_DOCUMENT_ROOT.'/holiday/class/holiday.class.php'; $board = new Holiday($db); $dashboardlines[$board->element] = $board->load_board($user); @@ -337,6 +337,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { ), 'supplier_proposal' => array( + 'lang' => 'supplier_proposal', 'groupName' => 'SupplierProposals', 'globalStatsKey' => 'askprice', 'stats' => @@ -486,6 +487,9 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { } if (!empty($boards)) { + if (!empty($groupElement['lang'])) { + $langs->load($groupElement['lang']); + } $groupName = $langs->trans($groupElement['groupName']); $groupKeyLowerCase = strtolower($groupKey); $nbTotalForGroup = 0; @@ -535,9 +539,9 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { $openedDashBoard .= '
    '; if (!empty($board->labelShort)) { - $infoName = ''.$board->labelShort.''; + $infoName = ''.$board->labelShort.''; } else { - $infoName = $board->label; + $infoName = ''.$board->label.''; } $textLateTitle = $langs->trans("NActionsLate", $board->nbtodolate); @@ -557,9 +561,11 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { $nbtodClass = ''; if ($board->nbtodo > 0) { $nbtodClass = 'badge badge-info'; + } else { + $nbtodClass = 'opacitymedium'; } - $openedDashBoard .= ' '.$infoName.' : '.$board->nbtodo.''; + $openedDashBoard .= ''.$infoName.''.$board->nbtodo.''; if ($textLate) { if ($board->url_late) { $openedDashBoard .= ''; @@ -572,7 +578,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { $openedDashBoard .= ''."\n"; if ($board->total > 0 && !empty($conf->global->MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX)) { - $openedDashBoard .= ''.$langs->trans('Total').' : '.price($board->total).''; + $openedDashBoard .= ''.$langs->trans('Total').' '.price($board->total).''; } $openedDashBoard .= '
    '."\n"; } diff --git a/htdocs/install/default.css b/htdocs/install/default.css index eede007e072..da5a19a63dc 100644 --- a/htdocs/install/default.css +++ b/htdocs/install/default.css @@ -466,7 +466,8 @@ table.tablesupport { @media only screen and (max-width: 570px) { .blocksupport { - width: 90%; + width: calc(100% - 4px); + padding: 4px; } .tablesupport { diff --git a/htdocs/install/lib/repair.lib.php b/htdocs/install/lib/repair.lib.php index aa0866fac69..aea82107d29 100644 --- a/htdocs/install/lib/repair.lib.php +++ b/htdocs/install/lib/repair.lib.php @@ -32,8 +32,8 @@ function checkElementExist($id, $table) { global $db; - $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$table; - $sql .= ' WHERE rowid = '.((int) $id); + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$table; + $sql .= " WHERE rowid = ".((int) $id); $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); @@ -87,8 +87,8 @@ function checkLinkedElements($sourcetype, $targettype) $out = $langs->trans('SourceType').': '.$sourcetype.' => '.$langs->trans('TargetType').': '.$targettype.' '; - $sql = 'SELECT rowid, fk_source, fk_target FROM '.MAIN_DB_PREFIX.'element_element'; - $sql .= " WHERE sourcetype='".$db->escape($sourcetype)."' AND targettype='".$db->escape($targettype)."'"; + $sql = "SELECT rowid, fk_source, fk_target FROM ".MAIN_DB_PREFIX."element_element"; + $sql .= " WHERE sourcetype = '".$db->escape($sourcetype)."' AND targettype = '".$db->escape($targettype)."'"; $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); @@ -106,7 +106,7 @@ function checkLinkedElements($sourcetype, $targettype) foreach ($elements as $key => $element) { if (!checkElementExist($element[$sourcetype], $sourcetable) || !checkElementExist($element[$targettype], $targettable)) { $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'element_element'; - $sql .= ' WHERE rowid = '.((int) $key); + $sql .= " WHERE rowid = ".((int) $key); $resql = $db->query($sql); $deleted++; } diff --git a/htdocs/install/mysql/data/llx_00_c_country.sql b/htdocs/install/mysql/data/llx_00_c_country.sql index 4465756f00a..7217fda7d09 100644 --- a/htdocs/install/mysql/data/llx_00_c_country.sql +++ b/htdocs/install/mysql/data/llx_00_c_country.sql @@ -279,5 +279,5 @@ INSERT INTO llx_c_country (rowid,code,code_iso,label,active,favorite) VALUES (24 -- Set field eec -UPDATE llx_c_country SET eec = 1 WHERE code IN ('AT','BE','BG','CY','CZ','DE','DK','EE','ES','FI','FR','GR','HR','NL','HU','IE','IM','IT','LT','LU','LV','MC','MT','PL','PT','RO','SE','SK','SI'); +UPDATE llx_c_country SET eec = 1 WHERE code IN ('AT','BE','BG','CY','CZ','DE','DK','EE','ES','FI','FR','GR','HR','NL','HU','IE','IT','LT','LU','LV','MC','MT','PL','PT','RO','SE','SK','SI'); diff --git a/htdocs/install/mysql/data/llx_c_availability.sql b/htdocs/install/mysql/data/llx_c_availability.sql index 2e06d1de8b3..7291c399da0 100644 --- a/htdocs/install/mysql/data/llx_c_availability.sql +++ b/htdocs/install/mysql/data/llx_c_availability.sql @@ -27,6 +27,8 @@ delete from llx_c_availability; INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (1, 'AV_NOW', 'Immediate', 1, 10); -INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (2, 'AV_1W', '1 week', 1, 20); -INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (3, 'AV_2W', '2 weeks', 1, 30); -INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (4, 'AV_3W', '3 weeks', 1, 40); +INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (2, 'AV_1W', '1 week', 1, 20); +INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (3, 'AV_2W', '2 weeks', 1, 30); +INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (4, 'AV_3W', '3 weeks', 1, 40); +INSERT INTO llx_c_availability (rowid,code,label,active,position) VALUES (5, 'AV_4W', '4 weeks', 1, 50); + diff --git a/htdocs/install/mysql/data/llx_c_email_templates.sql b/htdocs/install/mysql/data/llx_c_email_templates.sql index 4005506e887..bce46a70e49 100644 --- a/htdocs/install/mysql/data/llx_c_email_templates.sql +++ b/htdocs/install/mysql/data/llx_c_email_templates.sql @@ -29,18 +29,19 @@ INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnNewSubscription)' ,30,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourSubscriptionWasRecorded)__', '__(Hello)__ __MEMBER_FULLNAME__,

    \n\n__(ThisIsContentOfYourSubscriptionWasRecorded)__
    \n\n

    \n__(Sincerely)__
    __USER_SIGNATURE__',null, 1); INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingReminderForExpiredSubscription)',40,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(SubscriptionReminderEmail)__', '__(Hello)__ __MEMBER_FULLNAME__,

    \n\n__(ThisIsContentOfSubscriptionReminderEmail)__
    \n
    __ONLINE_PAYMENT_TEXT_AND_URL__
    \n

    \n__(Sincerely)__
    __USER_SIGNATURE__',null, 0); INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingEmailOnCancelation)' ,50,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourMembershipWasCanceled)__', '__(Hello)__ __MEMBER_FULLNAME__,

    \n\n__(YourMembershipWasCanceled)__
    \n

    \n__(Sincerely)__
    __USER_SIGNATURE__',null, 0); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingAnEMailToMember)' ,60,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(CardContent)__', '__(Hello)__,

    \n\n__(ThisIsContentOfYourCard)__
    \n__(ID)__ : __ID__
    \n__(Civiliyty)__ : __MEMBER_CIVILITY__
    \n__(Firstname)__ : __MEMBER_FIRSTNAME__
    \n__(Lastname)__ : __MEMBER_LASTNAME__
    \n__(Fullname)__ : __MEMBER_FULLNAME__
    \n__(Company)__ : __MEMBER_COMPANY__
    \n__(Address)__ : __MEMBER_ADDRESS__
    \n__(Zip)__ : __MEMBER_ZIP__
    \n__(Town)__ : __MEMBER_TOWN__
    \n__(Country)__ : __MEMBER_COUNTRY__
    \n__(Email)__ : __MEMBER_EMAIL__
    \n__(Birthday)__ : __MEMBER_BIRTH__
    \n__(Photo)__ : __MEMBER_PHOTO__
    \n__(Login)__ : __MEMBER_LOGIN__
    \n__(Password)__ : __MEMBER_PASSWORD__
    \n__(Phone)__ : __MEMBER_PHONE__
    \n__(PhonePerso)__ : __MEMBER_PHONEPRO__
    \n__(PhoneMobile)__ : __MEMBER_PHONEMOBILE__

    \n__(Sincerely)__
    __USER_SIGNATURE__',null, 0); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'adherent','member','',0,null,null,'(SendingAnEMailToMember)' ,60,'$conf->adherent->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(CardContent)__', '__(Hello)__,

    \n\n__(ThisIsContentOfYourCard)__
    \n__(ID)__ : __ID__
    \n__(Civility)__ : __MEMBER_CIVILITY__
    \n__(Firstname)__ : __MEMBER_FIRSTNAME__
    \n__(Lastname)__ : __MEMBER_LASTNAME__
    \n__(Fullname)__ : __MEMBER_FULLNAME__
    \n__(Company)__ : __MEMBER_COMPANY__
    \n__(Address)__ : __MEMBER_ADDRESS__
    \n__(Zip)__ : __MEMBER_ZIP__
    \n__(Town)__ : __MEMBER_TOWN__
    \n__(Country)__ : __MEMBER_COUNTRY__
    \n__(Email)__ : __MEMBER_EMAIL__
    \n__(Birthday)__ : __MEMBER_BIRTH__
    \n__(Photo)__ : __MEMBER_PHOTO__
    \n__(Login)__ : __MEMBER_LOGIN__
    \n__(Phone)__ : __MEMBER_PHONE__
    \n__(PhonePerso)__ : __MEMBER_PHONEPRO__
    \n__(PhoneMobile)__ : __MEMBER_PHONEMOBILE__

    \n__(Sincerely)__
    __USER_SIGNATURE__',null, 0); -- Recruiting INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, enabled, active, topic, content, content_lines, joinfiles) VALUES (0, 'recruitment','recruitmentcandidature_send','',0,null,null,'(AnswerCandidature)' ,100,'$conf->recruitment->enabled',1,'[__[MAIN_INFO_SOCIETE_NOM]__] __(YourCandidature)__', '__(Hello)__ __CANDIDATE_FULLNAME__,

    \n\n__(YourCandidatureAnswerMessage)__
    __ONLINE_INTERVIEW_SCHEDULER_TEXT_AND_URL__\n

    \n__(Sincerely)__
    __USER_SIGNATURE__',null, 0); -- Event organization -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskConf)', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventConfRequestWasReceived)__

    __ONLINE_PAYMENT_TEXT_AND_URL__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskBooth)', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventBoothRequestWasReceived)__

    __ONLINE_PAYMENT_TEXT_AND_URL__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsBooth)', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailSubsBooth)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventBoothSubscriptionWasReceived)__

    __ONLINE_PAYMENT_TEXT_AND_URL__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsEvent)', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailSubsEvent)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventEventSubscriptionWasReceived)__

    __(Sincerely)__

    __MYCOMPANY_NAME__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailAttendees)', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventBulkMailToAttendees)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailSpeakers)', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventBulkMailToSpeakers)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskConf)', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__,

    __(OrganizationEventConfRequestWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskBooth)', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__,

    __(OrganizationEventBoothRequestWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +-- TODO Add message for registration only to event __ONLINE_PAYMENT_TEXT_AND_URL__ +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsBooth)', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailBoothPayment)__', '__(Hello)__,

    __(OrganizationEventPaymentOfBoothWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsEvent)', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailRegistrationPayment)__', '__(Hello)__,

    __(OrganizationEventPaymentOfRegistrationWasReceived)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailAttendees)', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__,

    __(OrganizationEventBulkMailToAttendees)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailSpeakers)', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__,

    __(OrganizationEventBulkMailToSpeakers)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -- Partnership INSERT INTO llx_c_email_templates (entity, module, type_template, label, lang, position, topic, joinfiles, content) VALUES (0, 'partnership', 'partnership_send', '(SendingEmailOnPartnershipWillSoonBeCanceled)', '', 100, '[__[MAIN_INFO_SOCIETE_NOM]__] - __(YourPartnershipWillSoonBeCanceledTopic)__', 0, '\n

    __(Hello)__,

    \n__(YourPartnershipWillSoonBeCanceledContent)__

    \n
    \n\n
    \n\n __(Sincerely)__
    \n __[MAIN_INFO_SOCIETE_NOM]__
    \n \n'); diff --git a/htdocs/install/mysql/data/llx_c_forme_juridique.sql b/htdocs/install/mysql/data/llx_c_forme_juridique.sql index 07a09724ed2..7af5d28df8c 100644 --- a/htdocs/install/mysql/data/llx_c_forme_juridique.sql +++ b/htdocs/install/mysql/data/llx_c_forme_juridique.sql @@ -356,3 +356,16 @@ insert into llx_c_forme_juridique (fk_pays, code, libelle) values (13, '1306','S insert into llx_c_forme_juridique (fk_pays, code, libelle) values (13, '1307','Société en participation'); insert into llx_c_forme_juridique (fk_pays, code, libelle) values (13, '1308','Groupe de sociétés'); +-- Sweden (id country=20) +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2001', 'Aktiebolag'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2002', 'Publikt aktiebolag (AB publ)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2003', 'Ekonomisk förening (ek. för.)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2004', 'Bostadsrättsförening (BRF)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2005', 'Hyresrättsförening (HRF)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2006', 'Kooperativ'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2007', 'Enskild firma (EF)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2008', 'Handelsbolag (HB)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2009', 'Kommanditbolag (KB)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2010', 'Enkelt bolag'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2011', 'Ideell förening'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2012', 'Stiftelse'); diff --git a/htdocs/install/mysql/data/llx_c_holiday_type.sql b/htdocs/install/mysql/data/llx_c_holiday_type.sql index addd7f9942e..65f9a51b037 100644 --- a/htdocs/install/mysql/data/llx_c_holiday_type.sql +++ b/htdocs/install/mysql/data/llx_c_holiday_type.sql @@ -25,12 +25,12 @@ -- -- Generic to all countries -insert into llx_c_holiday_types(code, label, affect, delay, newByMonth, fk_country, active) values ('LEAVE_SICK', 'Sick leave', 0, 0, 0, NULL, 1); -insert into llx_c_holiday_types(code, label, affect, delay, newByMonth, fk_country, active) values ('LEAVE_OTHER', 'Other leave', 0, 0, 0, NULL, 1); +insert into llx_c_holiday_types(code, label, affect, delay, newbymonth, fk_country, active) values ('LEAVE_SICK', 'Sick leave', 0, 0, 0, NULL, 1); +insert into llx_c_holiday_types(code, label, affect, delay, newbymonth, fk_country, active) values ('LEAVE_OTHER', 'Other leave', 0, 0, 0, NULL, 1); -- Not enabled by default, we prefer to have an entrey dedicated to country -insert into llx_c_holiday_types(code, label, affect, delay, newByMonth, fk_country, active) values ('LEAVE_PAID', 'Paid vacation', 1, 7, 0, NULL, 0); +insert into llx_c_holiday_types(code, label, affect, delay, newbymonth, fk_country, active) values ('LEAVE_PAID', 'Paid vacation', 1, 7, 0, NULL, 0); -- Leaves specific to France -insert into llx_c_holiday_types(code, label, affect, delay, newByMonth, fk_country, active) values ('LEAVE_RTT_FR', 'RTT' , 1, 7, 0.83, 1, 1); -insert into llx_c_holiday_types(code, label, affect, delay, newByMonth, fk_country, active) values ('LEAVE_PAID_FR', 'Paid vacation', 1, 30, 2.08334, 1, 1); +insert into llx_c_holiday_types(code, label, affect, delay, newbymonth, fk_country, active) values ('LEAVE_RTT_FR', 'RTT' , 1, 7, 0.83, 1, 1); +insert into llx_c_holiday_types(code, label, affect, delay, newbymonth, fk_country, active) values ('LEAVE_PAID_FR', 'Paid vacation', 1, 30, 2.08334, 1, 1); diff --git a/htdocs/install/mysql/data/llx_c_tva.sql b/htdocs/install/mysql/data/llx_c_tva.sql index 72746ac99ea..12b0b92a13e 100644 --- a/htdocs/install/mysql/data/llx_c_tva.sql +++ b/htdocs/install/mysql/data/llx_c_tva.sql @@ -47,9 +47,9 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 1 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 133, 13, '19','0','TVA 19%', 1); -- ANGOLA (id country=35) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 351, 35, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 352, 35, '7','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 353, 35, '14','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 351, 35, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 352, 35, '7','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 353, 35, '14','0','VAT rate - standard',1); -- ARGENTINA (id country=23) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (231, 23, '0','0','IVA Rate 0', 1); @@ -57,31 +57,31 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (23 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (233, 23, '21','0','IVA standard rate',1); -- AUSTRALIA (id country=28) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (281, 28, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (282, 28, '10','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (281, 28, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (282, 28, '10','0','VAT rate - standard',1); -- AUSTRIA (id country=41) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (411, 41, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (412, 41, '10','0','VAT reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (413, 41, '20','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (411, 41, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (412, 41, '10','0','VAT rate - reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (413, 41, '20','0','VAT rate - standard',1); -- BRASIL (id country=56) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (561, 56, '0','0','VAT reduced rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (561, 56, '0','0','VAT rate - reduced',1); -- BULGARIA (id country=59) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (591, 59, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (592, 59, '7','0','VAT reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (593, 59, '20','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (591, 59, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (592, 59, '7','0','VAT rate - reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (593, 59, '20','0','VAT rate - standard',1); -- BELGIUM (id country=2) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 21, 2, '0','0','VAT Rate 0 ou non applicable',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 22, 2, '6','0','VAT reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 23, 2, '21','0','VAT standard rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 24, 2, '12','0','VAT reduced rate', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 21, 2, '0','0','VAT rate 0 ou non applicable',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 22, 2, '6','0','VAT rate - reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 23, 2, '21','0','VAT rate - standard',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 24, 2, '12','0','VAT rate - reduced', 1); -- CANADA (id country=14) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (141, 14, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (142, 14, '7','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (141, 14, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (142, 14, '7','0','VAT rate - standard',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,note,active) values (143, 14,'5','0','9.975','1','GST/TPS and PST/TVQ rate for Province',1); --insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,note,active) values (143, 14,'5','0','9.975','1','GST/TPS and PST/TVQ rate for Quebec',1); --insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,note,active) values (144, 14,'5','0','7','1','GST/TPS and PST/TVQ rate for British Columbia',1); @@ -89,43 +89,43 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_typ -- CAMEROUN (id country=24) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (241, 24, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (242, 24, '19.25','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (241, 24, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (242, 24, '19.25','0','VAT rate - standard',1); -- CHILE (id country=67) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (671, 67, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (672, 67, '19','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (671, 67, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (672, 67, '19','0','VAT rate - standard',1); -- CHINA (id country=9) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 91, 9, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 92, 9, '13','0','VAT reduced rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 93, 9, '3','0','VAT super reduced rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 94, 9, '17','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 91, 9, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 92, 9, '13','0','VAT rate - reduced 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 93, 9, '3','0','VAT rate - super-reduced 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 94, 9, '17','0','VAT rate - standard',1); -- CONGO = REPUBLIQUE DU CONGO (id country=72) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (721, 72, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,note,active) values (722, 72, '18','0', '0.9', '1', 'VAT Rate 18+0.9', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (721, 72, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,note,active) values (722, 72, '18','0', '0.9', '1', 'VAT rate 18+0.9', 1); -- CYPRUS (id country=78) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (781, 78, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (782, 78, '9','0','VAT Rate 9',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (783, 78, '5','0','VAT Rate 5',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (784, 78, '19','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (781, 78, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (782, 78, '9','0','VAT rate 9',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (783, 78, '5','0','VAT rate 5',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (784, 78, '19','0','VAT rate - standard',1); -- DANMERK (id country=80) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (801, 80, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (802, 80, '25','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (801, 80, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (802, 80, '25','0','VAT rate - standard',1); -- FRANCE (id country=1) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 11, 1, '0','0','VAT Rate 0 ou non applicable',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 12, 1, '20','0','VAT standard rate (France hors DOM-TOM)',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 13, 1, '10','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 14, 1, '5.5','0','VAT reduced rate (France hors DOM-TOM)',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 15, 1, '2.1','0','VAT super-reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,code,recuperableonly,note,active) values (16, 1, '8.5', '85', '0', 'VAT standard rate (DOM sauf Guyane et Saint-Martin)',0); -insert into llx_c_tva(rowid,fk_pays,taux,code,recuperableonly,note,active) values (17, 1, '8.5', '85NPR', '1', 'VAT standard rate (DOM sauf Guyane et Saint-Martin), non perçu par le vendeur mais récupérable par acheteur',0); -insert into llx_c_tva(rowid,fk_pays,taux,code,recuperableonly,localtax1,localtax1_type,note,active) values (18, 1, '8.5', '85NPROM', '1', 2, 3, 'VAT standard rate (DOM sauf Guyane et Saint-Martin), NPR, Octroi de Mer',0); -insert into llx_c_tva(rowid,fk_pays,taux,code,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values (19, 1, '8.5', '85NPROMOMR', '1', 2, 3, 2.5, 3, 'VAT standard rate (DOM sauf Guyane et Saint-Martin), NPR, Octroi de Mer et Octroi de Mer Regional',0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 11, 1, '0','0','VAT rate 0 ou non applicable',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 12, 1, '20','0','VAT rate - standard (France hors DOM-TOM)',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 13, 1, '10','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 14, 1, '5.5','0','VAT rate - reduced (France hors DOM-TOM)',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 15, 1, '2.1','0','VAT rate - super-reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,code,recuperableonly,note,active) values (16, 1, '8.5', '85', '0', 'VAT rate - standard (DOM sauf Guyane et Saint-Martin)',0); +insert into llx_c_tva(rowid,fk_pays,taux,code,recuperableonly,note,active) values (17, 1, '8.5', '85NPR', '1', 'VAT rate - standard (DOM sauf Guyane et Saint-Martin), non perçu par le vendeur mais récupérable par acheteur',0); +insert into llx_c_tva(rowid,fk_pays,taux,code,recuperableonly,localtax1,localtax1_type,note,active) values (18, 1, '8.5', '85NPROM', '1', 2, 3, 'VAT rate - standard (DOM sauf Guyane et Saint-Martin), NPR, Octroi de Mer',0); +insert into llx_c_tva(rowid,fk_pays,taux,code,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values (19, 1, '8.5', '85NPROMOMR', '1', 2, 3, 2.5, 3, 'VAT rate - standard (DOM sauf Guyane et Saint-Martin), NPR, Octroi de Mer et Octroi de Mer Regional',0); -- GERMANY (id country=5) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 51, 5, '0','0','No VAT', 1); @@ -147,11 +147,11 @@ insert into llx_c_tva(rowid,fk_pays,taux,localtax1,localtax1_type,localtax2,loca -- ICELAND (id country=116) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1161, 116, '0','0','VAT rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1163, 116,'25.5','0','VAT standard rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1162, 116, '7','0','VAT reduced rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1163, 116,'25.5','0','VAT rate - standard',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1162, 116, '7','0','VAT rate - reduced',1); -- INDIA (id country=117) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '0','0','VAT Rate 0', 0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1171, 117, '0','0','VAT rate 0', 0); insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1172, 117, 'C+S-5' , 0, 2.5, '1', 2.5, '1', 0, 'CGST+SGST - Same state sales', 1); insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1173, 117, 'I-5' , 5, 0, '0', 0, '0', 0, 'IGST', 1); @@ -163,54 +163,58 @@ insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2 insert into llx_c_tva(rowid,fk_pays,code,taux,localtax1,localtax1_type,localtax2,localtax2_type,recuperableonly,note,active) values (1179, 117, 'I-28' , 28, 0, '0', 0, '0', 0, 'IGST', 1); -- IRELAND (id country=8) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 81, 8, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 82, 8, '23','0','VAT standard rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 83, 8, '13.5','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 84, 8, '9','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 85, 8, '4.8','0','VAT reduced rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 81, 8, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 82, 8, '23','0','VAT rate - standard',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 83, 8, '13.5','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 84, 8, '9','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 85, 8, '4.8','0','VAT rate - reduced',1); -- ITALY (id country=3) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 31, 3, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 32, 3, '10','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 33, 3, '4','0','VAT super-reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 34, 3, '22','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 31, 3, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 32, 3, '10','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 33, 3, '4','0','VAT rate - super-reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 34, 3, '22','0','VAT rate - standard',1); -- IVORY COST (id country=21) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values (211, 21, '0','0',0,0,0,0,'IVA Rate 0',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values (212, 21, '18','0',7.5,2,0,0,'IVA standard rate',1); -- JAPAN (id country=123) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1231, 123, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1232, 123, '5','0','VAT Rate 5',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1231, 123, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1232, 123, '5','0','VAT rate 5',1); -- LUXEMBOURG (id country=140) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1401, 140, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1402, 140, '14','0','VAT intermediary rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1403, 140, '8','0','VAT reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1404, 140, '3','0','VAT super-reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1405, 140, '17','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1401, 140, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1402, 140, '14','0','VAT rate - intermediary',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1403, 140, '8','0','VAT rate - reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1404, 140, '3','0','VAT rate - super-reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1405, 140, '17','0','VAT rate - standard',1); + +-- MALI (id country=147) +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1471, 147, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1471, 147, '18','0','VAT rate - standard', 1); -- MONACO (id country=27) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 271, 27, '0','0','VAT Rate 0 ou non applicable',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 272, 27, '8.5','0','VAT standard rate (DOM sauf Guyane et Saint-Martin)',0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 273, 27, '8.5','1','VAT standard rate (DOM sauf Guyane et Saint-Martin), non perçu par le vendeur mais récupérable par acheteur',0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 274, 27, '5.5','0','VAT reduced rate (France hors DOM-TOM)',0); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 275, 27,'19.6','0','VAT standard rate (France hors DOM-TOM)',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 276, 27, '2.1','0','VAT super-reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 277, 27, '7','0','VAT reduced rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 271, 27, '0','0','VAT rate 0 ou non applicable',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 272, 27, '8.5','0','VAT rate - standard (DOM sauf Guyane et Saint-Martin)',0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 273, 27, '8.5','1','VAT rate - standard (DOM sauf Guyane et Saint-Martin), non perçu par le vendeur mais récupérable par acheteur',0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 274, 27, '5.5','0','VAT rate - reduced (France hors DOM-TOM)',0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 275, 27,'19.6','0','VAT rate - standard (France hors DOM-TOM)',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 276, 27, '2.1','0','VAT rate - super-reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 277, 27, '7','0','VAT rate - reduced',1); -- MAROCO (id country=12) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 121, 12, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 122, 12, '14','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 123, 12, '10','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 124, 12, '7','0','VAT super-reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 125, 12, '20','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 121, 12, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 122, 12, '14','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 123, 12, '10','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 124, 12, '7','0','VAT rate - super-reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 125, 12, '20','0','VAT rate - standard',1); -- MALTA (id country=148) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1481, 148, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1482, 148, '7','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1483, 148, '5','0','VAT super-reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1484, 148, '18','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1481, 148, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1482, 148, '7','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1483, 148, '5','0','VAT rate - super-reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1484, 148, '18','0','VAT rate - standard',1); -- NEDERLAND (id country=17) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 171, 17, '0','0','0 BTW tarief', 1); @@ -219,96 +223,96 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 1 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 174, 17, '21','0','Algemeen BTW tarief (vanaf 1 oktober 2012)',0); -- NEW CALEDONIA (id country=165) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1651, 165, '0','0','VAT Rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1651, 165, '0','0','VAT rate 0', 1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1652, 165, '3','0','VAT standard 3', 1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1653, 165, '6','0','VAT standard 6', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1654, 165, '11','0','VAT standard rate', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1654, 165, '11','0','VAT rate - standard', 1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1655, 165, '22','0','VAT standard high', 1); -- NEW ZEALAND (id country=166) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1661, 166, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1662, 166, '15','0','VAT standard rate', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1661, 166, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1662, 166, '15','0','VAT rate - standard', 1); -- NIGERIA (id country=169) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1691, 169, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1692, 169, '5','0','VAT standard rate', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1691, 169, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1692, 169, '5','0','VAT rate - standard', 1); -- NORWAY (id country=173) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1731, 173, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1732, 173, '14','0','VAT reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1733, 173, '8','0','VAT reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1734, 173, '25','0','VAT standard rate', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1731, 173, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1732, 173, '14','0','VAT rate - reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1733, 173, '8','0','VAT rate - reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1734, 173, '25','0','VAT rate - standard', 1); -- PANAMA (id country=178) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1781, 178, '0','0','ITBMS Rate 0',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1782, 178, '7','0','ITBMS standard rate',1); -- PERU (id country=181) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1811, 181, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1818, 181, '18','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1811, 181, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1818, 181, '18','0','VAT rate - standard',1); -- POLAND (id country=184) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1841, 184, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1842, 184, '8','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1843, 184, '3','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1844, 184, '23','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1841, 184, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1842, 184, '8','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1843, 184, '3','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1844, 184, '23','0','VAT rate - standard',1); -- PORTUGAL (id country=25) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 251, 25, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 252, 25, '13','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 253, 25, '23','0','VAT standard rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 254, 25, '6','0','VAT reduced rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 251, 25, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 252, 25, '13','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 253, 25, '23','0','VAT rate - standard',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 254, 25, '6','0','VAT rate - reduced',1); -- ROMANIA (id country=188) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1881, 188, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1882, 188, '9','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1883, 188, '19','0','VAT standard rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1884, 188, '5','0','VAT reduced rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1881, 188, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1882, 188, '9','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1883, 188, '19','0','VAT rate - standard',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1884, 188, '5','0','VAT rate - reduced',1); -- SAUDI ARABIA (id country=26) -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 261, 26, '0', '0', 'VAT Rate 0', 1); -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 262, 26, '5', '0', 'VAT Rate 5', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 261, 26, '0', '0', 'VAT rate 0', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 262, 26, '5', '0', 'VAT rate 5', 1); -- SAN SALVADOR (id country=86) INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 861, 86, '0', '0', 'SIN IVA', 1); INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 862, 86, '13', '0', 'IVA 13', 1); -- SENEGAL (id country=22) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 221, 22, '0', '0', 'VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 222, 22, '10', '0', 'VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 223, 22, '18', '0', 'VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 221, 22, '0', '0', 'VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 222, 22, '10', '0', 'VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 223, 22, '18', '0', 'VAT rate - standard',1); -- SLOVAKIA (id country=201) -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2011, 201, '0', '0', 'VAT Rate 0', 1); -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2012, 201, '10', '0', 'VAT reduced rate', 1); -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2013, 201, '19', '0', 'VAT standard rate', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2011, 201, '0', '0', 'VAT rate 0', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2012, 201, '10', '0', 'VAT rate - reduced', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2013, 201, '19', '0', 'VAT rate - standard', 1); -- SLOVENIA (id country=202) -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2021, 202, '0', '0', 'VAT Rate 0', 1); -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2022, 202,'9.5', '0', 'VAT reduced rate', 1); -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2023, 202, '22', '0', 'VAT standard rate', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2021, 202, '0', '0', 'VAT rate 0', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2022, 202,'9.5', '0', 'VAT rate - reduced', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2023, 202, '22', '0', 'VAT rate - standard', 1); -- SOUTH AFRICA (id country=205) -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2051, 205, '0', '0', 'VAT Rate 0', 1); -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2052, 205, '15', '0', 'VAT standard rate', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2051, 205, '0', '0', 'VAT rate 0', 1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2052, 205, '15', '0', 'VAT rate - standard', 1); -- SPAIN (id country=4) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values ( 41, 4, '0','0', '0','3','-19:-15:-9','5','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values ( 42, 4,'10','0','1.4','3','-19:-15:-9','5','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values ( 43, 4, '4','0','0.5','3','-19:-15:-9','5','VAT super-reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values ( 44, 4,'21','0','5.2','3','-19:-15:-9','5','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values ( 41, 4, '0','0', '0','3','-19:-15:-9','5','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values ( 42, 4,'10','0','1.4','3','-19:-15:-9','5','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values ( 43, 4, '4','0','0.5','3','-19:-15:-9','5','VAT rate - super-reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_type,localtax2,localtax2_type,note,active) values ( 44, 4,'21','0','5.2','3','-19:-15:-9','5','VAT rate - standard',1); -- SWEDEN (id country=20) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 201, 20, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 202, 20, '12','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 203, 20, '6','0','VAT super-reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 204, 20, '25','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 201, 20, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 202, 20, '12','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 203, 20, '6','0','VAT rate - super-reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 204, 20, '25','0','VAT rate - standard',1); -- SWITZERLAND (id country=6) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 61, 6, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 62, 6, '3.7','0','VAT reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 63, 6, '2.5','0','VAT super-reduced rate',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 64, 6, '7.7','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 61, 6, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 62, 6, '3.7','0','VAT rate - reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 63, 6, '2.5','0','VAT rate - super-reduced',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 64, 6, '7.7','0','VAT rate - standard',1); -- SRI LANKA (id country=207) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2071, 207, '0','0','VAT 0', 1); @@ -319,24 +323,24 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (21 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2132, 213, '5','0','VAT 5%',1); -- TUNISIA (id country=10) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (101,10, '0','0','VAT Rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (101,10, '0','0','VAT rate 0',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (102,10, '12','0','VAT 12%',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (103,10, '18','0','VAT 18%',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (104,10, '7.5','0','VAT 6% Majoré à 25% (7.5%)',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (105,10, '15','0','VAT 12% Majoré à 25% (15%)',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (106,10, '22.5','0','VAT 18% Majoré à 25% (22.5%)',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (107,10, '6','0','VAT 6%', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active,localtax1,localtax1_type,localtax2,localtax2_type) values (107,10,'18.18','0','VAT 18%+FODEC', 1, 1, '4', 0, 0); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active,localtax1,localtax1_type,localtax2,localtax2_type) values (108,10,'18.18','0','VAT 18%+FODEC', 1, 1, '4', 0, 0); -- UKRAINE (id country=226) -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2261,226, '0','0','VAT Rate 0',1); +INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2261,226, '0','0','VAT rate 0',1); INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2262,226, '20','0','VAT standart rate',1); -- UNITED OF KINGDOM (id country=7) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 71, 7, '0','0','VAT Rate 0', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 72, 7, '17.5','0','VAT standard rate before 2011',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 73, 7, '5','0','VAT reduced rate', 1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 74, 7, '20','0','VAT standard rate',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 71, 7, '0','0','VAT rate 0', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 72, 7, '17.5','0','VAT rate - standard before 2011',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 73, 7, '5','0','VAT rate - reduced', 1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values ( 74, 7, '20','0','VAT rate - standard',1); -- UNITED STATES (id country=11) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (111,11, '0','0','No Sales Tax',1); @@ -350,16 +354,16 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (11 insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1931,193, '0','0','No VAT in SPM',1); -- SAINT MARTIN (id country=24) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2461,246, '0','0','VAT Rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2461,246, '0','0','VAT rate 0',1); -- MAURITANIA (id country=151) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1511,151, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1512,151, '14','0','VAT Rate 14',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1511,151, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1512,151, '14','0','VAT rate 14',1); -- MAURITIUS (id country=152) -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1521,152, '0','0','VAT Rate 0',1); -insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1522,152, '15','0','VAT Rate 15',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1521,152, '0','0','VAT rate 0',1); +insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1522,152, '15','0','VAT rate 15',1); -- HONDURAS (id country=114) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (1141,114, '0','0','No ISV',1); @@ -375,16 +379,12 @@ INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 4 INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 462, 46, '15','0','VAT 15%',1); INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES ( 463, 46, '7.5','0','VAT 7.5%',1); --- SOUTH AFRICA (id country=205) -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2051,205, '0','0','No VAT',1); -INSERT INTO llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) VALUES (2052,205, '14','0','VAT 14%',1); - -- VENEZUELA (id country=232) insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2321,232, '0','0','No VAT',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2322,232, '12','0','VAT 12%',1); insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,note,active) values (2323,232, '8','0','VAT 8%',1); --- Example of code to insert a vat rate 0 for each country +-- Example of code to insert a VAT rate 0 for each country --delete from llx_c_tva where rowid = 1181; -- to delete a record that does not follow rules for rowid (fk_pays+'1') --insert into llx_c_tva(rowid, fk_pays, taux, recuperableonly, note, active) SELECT CONCAT(c.rowid, '1'), c.rowid, 0, 0, 'No VAT', 1 from llx_c_country as c where c.rowid not in (select fk_pays from llx_c_tva); diff --git a/htdocs/install/mysql/data/llx_c_units.sql b/htdocs/install/mysql/data/llx_c_units.sql index 3a11453c9f8..59692793fe2 100644 --- a/htdocs/install/mysql/data/llx_c_units.sql +++ b/htdocs/install/mysql/data/llx_c_units.sql @@ -1,7 +1,9 @@ -- ======================================================================== --- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville --- Copyright (C) 2004 Laurent Destailleur --- Copyright (C) 2019 Florian Henry +-- Copyright (C) 2001-2002,2004 Rodolphe Quiedeville +-- Copyright (C) 2004 Laurent Destailleur +-- Copyright (C) 2019 Florian Henry +-- Copyright (C) 2021 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 2 of the License, or @@ -17,45 +19,45 @@ -- -- ======================================================================== -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('T', '3','WeightUnitton','T', 'weight', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('KG', '0','WeightUnitkg','kg', 'weight', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('G', '-3','WeightUnitg','g', 'weight', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('MG','-6','WeightUnitmg','mg', 'weight', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('OZ','98','WeightUnitounce','Oz', 'weight', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('LB','99','WeightUnitpound','lb', 'weight', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('T', '100', '3','WeightUnitton','T', 'weight', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('KG','110', '0','WeightUnitkg','kg', 'weight', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('G', '120','-3','WeightUnitg','g', 'weight', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('MG','130','-6','WeightUnitmg','mg', 'weight', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('OZ','140','98','WeightUnitounce','Oz', 'weight', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('LB','150','99','WeightUnitpound','lb', 'weight', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('M', '0','SizeUnitm','m', 'size', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('DM','-1','SizeUnitdm','dm', 'size', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('CM','-2','SizeUnitcm','cm', 'size', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('MM','-3','SizeUnitmm','mm', 'size', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('FT','98','SizeUnitfoot','ft', 'size', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('IN','99','SizeUnitinch','in', 'size', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('M', '200', '0','SizeUnitm','m', 'size', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('DM','210','-1','SizeUnitdm','dm', 'size', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('CM','220','-2','SizeUnitcm','cm', 'size', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('MM','230','-3','SizeUnitmm','mm', 'size', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('FT','240','98','SizeUnitfoot','ft', 'size', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('IN','250','99','SizeUnitinch','in', 'size', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('M2', '0','SurfaceUnitm2','m2', 'surface', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('DM2','-2','SurfaceUnitdm2','dm2', 'surface', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('CM2','-4','SurfaceUnitcm2','cm2', 'surface', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('MM2','-6','SurfaceUnitmm2','mm2', 'surface', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('FT2','98','SurfaceUnitfoot2','ft2', 'surface', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('IN2','99','SurfaceUnitinch2','in2', 'surface', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('M2', '300', '0','SurfaceUnitm2','m2', 'surface', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('DM2','310','-2','SurfaceUnitdm2','dm2', 'surface', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('CM2','320','-4','SurfaceUnitcm2','cm2', 'surface', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('MM2','330','-6','SurfaceUnitmm2','mm2', 'surface', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('FT2','340','98','SurfaceUnitfoot2','ft2', 'surface', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('IN2','350','99','SurfaceUnitinch2','in2', 'surface', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('M3', '0','VolumeUnitm3','m3', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('DM3','-3','VolumeUnitdm3','dm3', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('CM3','-6','VolumeUnitcm3','cm3', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('MM3','-9','VolumeUnitmm3','mm3', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('FT3','88','VolumeUnitfoot3','ft3', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('IN3','89','VolumeUnitinch3','in3', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('OZ3','97','VolumeUnitounce','Oz', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('L', '98','VolumeUnitlitre','L', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('GAL','99','VolumeUnitgallon','gal', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('M3', '400', '0','VolumeUnitm3','m3', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('DM3','410','-3','VolumeUnitdm3','dm3', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('CM3','420','-6','VolumeUnitcm3','cm3', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('MM3','430','-9','VolumeUnitmm3','mm3', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('FT3','440','88','VolumeUnitfoot3','ft3', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('IN3','450','89','VolumeUnitinch3','in3', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('OZ3','460','97','VolumeUnitounce','Oz', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('L', '470','98','VolumeUnitlitre','L', 'volume', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('GAL','480','99','VolumeUnitgallon','gal', 'volume', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('P', '0','Piece','p', 'qty', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('SET', '0','Set','set', 'qty', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('P', '500', '0','Piece','p', 'qty', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('SET','510', '0','Set','set', 'qty', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('S', '0','second','s', 'time', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('MI', '60','minute','i', 'time', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('H', '3600','hour','h', 'time', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('D', '86400','day','d', 'time', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('W', '604800','week','w', 'time', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('MO','2629800','month','m', 'time', 1); -INSERT INTO llx_c_units (code, scale, label, short_label, unit_type, active) VALUES ('Y','31557600','year','y', 'time', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('S', '600', '0','second','s', 'time', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('MI','610', '60','minute','i', 'time', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('H', '620', '3600','hour','h', 'time', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('D', '630', '86400','day','d', 'time', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('W', '640', '604800','week','w', 'time', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('MO','650', '2629800','month','m', 'time', 1); +INSERT INTO llx_c_units (code, sortorder, scale, label, short_label, unit_type, active) VALUES ('Y', '660','31557600','year','y', 'time', 1); diff --git a/htdocs/install/mysql/data/llx_const.sql b/htdocs/install/mysql/data/llx_const.sql index 2f2975a158c..d7193d87a49 100644 --- a/htdocs/install/mysql/data/llx_const.sql +++ b/htdocs/install/mysql/data/llx_const.sql @@ -85,7 +85,7 @@ insert into llx_const (name, value, type, note, visible) values ('MAIN_DELAY_EXP -- -- Mail Mailing -- -insert into llx_const (name, value, type, note, visible) values ('MAIN_FIX_FOR_BUGGED_MTA','1','chaine','Set constant to fix email ending from PHP with some linux ike system',1); +--insert into llx_const (name, value, type, note, visible) values ('MAIN_FIX_FOR_BUGGED_MTA','1','chaine','Set constant to fix email ending from PHP with some linux like system',1); insert into llx_const (name, value, type, note, visible) values ('MAILING_EMAIL_FROM','no-reply@mydomain.com','chaine','EMail emmetteur pour les envois d emailings',0); diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index 29c2aad9bd4..a9f1a669e52 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -37,6 +37,7 @@ ALTER TABLE llx_prelevement_bons ADD COLUMN type varchar(16) DEFAULT 'debit-orde ALTER TABLE llx_prelevement_facture CHANGE COLUMN fk_facture_foun fk_facture_fourn integer NULL; +ALTER TABLE llx_prelevement_facture_demande ADD COLUMN fk_facture_fourn INTEGER NULL; ALTER TABLE llx_prelevement_facture_demande ADD INDEX idx_prelevement_facture_demande_fk_facture (fk_facture); ALTER TABLE llx_prelevement_facture_demande ADD INDEX idx_prelevement_facture_demande_fk_facture_fourn (fk_facture_fourn); diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index ee1ad6b9f2e..ac032d3541d 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -12,8 +12,8 @@ -- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); -- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; -- To create a unique index ALTER TABLE llx_table ADD UNIQUE INDEX uk_table_field (field); --- To drop an index: -- VMYSQL4.1 DROP INDEX nomindex on llx_table --- To drop an index: -- VPGSQL8.2 DROP INDEX nomindex +-- To drop an index: -- VMYSQL4.1 DROP INDEX nomindex on llx_table; +-- To drop an index: -- VPGSQL8.2 DROP INDEX nomindex; -- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_table CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; -- To make pk to be auto increment (postgres): -- -- VPGSQL8.2 CREATE SEQUENCE llx_table_rowid_seq OWNED BY llx_table.rowid; @@ -76,6 +76,7 @@ INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUE INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 14, 'CA-ENG-BASE', 'Canadian basic chart of accounts - English', 1); INSERT INTO llx_accounting_system (fk_country, pcg_version, label, active) VALUES ( 154, 'SAT/24-2019', 'Catalogo y codigo agrupador fiscal del 2019', 1); +UPDATE llx_accounting_system SET fk_country = 1 WHERE fk_country IS NULL; UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'auguria'; UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'bureau2crea'; @@ -86,6 +87,26 @@ DELETE FROM llx_user_param where param = 'MAIN_THEME' and value in ('auguria', ' -- For v14 +--Fix bad sign on multicompany column for customer invoice lines +UPDATE llx_facturedet SET multicurrency_subprice = -multicurrency_subprice WHERE ((multicurrency_subprice < 0 and subprice > 0) OR (multicurrency_subprice > 0 and subprice < 0)); +UPDATE llx_facturedet SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facturedet SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facturedet SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicompany column for customer invoices +UPDATE llx_facture SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facture SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicurrency column for supplier invoice lines +UPDATE llx_facture_fourn_det SET multicurrency_subprice = -multicurrency_subprice WHERE ((multicurrency_subprice < 0 and pu_ht > 0) OR (multicurrency_subprice > 0 and pu_ht < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and tva > 0) OR (multicurrency_total_tva > 0 and tva < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicompany column for customer invoices +UPDATE llx_facture_fourn SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture_fourn SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facture_fourn SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); + + UPDATE llx_c_ticket_type set label = 'Issue or bug' WHERE code = 'ISSUE'; INSERT INTO llx_c_ticket_type (code, pos, label, active, use_default, description) VALUES('PROBLEM', '22', 'Problem', 0, 0, NULL); @@ -267,12 +288,14 @@ INSERT INTO llx_payment_vat (rowid, fk_tva, datec, datep, amount, fk_typepaiemen ALTER TABLE llx_tva ALTER COLUMN paye SET DEFAULT 0; -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, tms, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'eventorganization_send', '', 0, null, null, '2021-02-14 14:42:41', 'EventOrganizationEmailAskConf', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventConfRequestWasReceived)__

    __ONLINE_PAYMENT_TEXT_AND_URL__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, tms, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'eventorganization_send', '', 0, null, null, '2021-02-14 14:42:41', 'EventOrganizationEmailAskBooth', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventBoothRequestWasReceived)__

    __ONLINE_PAYMENT_TEXT_AND_URL__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, tms, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'eventorganization_send', '', 0, null, null, '2021-02-14 14:42:41', 'EventOrganizationEmailSubsBooth', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailSubsBooth)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventBoothSubscriptionWasReceived)__

    __ONLINE_PAYMENT_TEXT_AND_URL__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, tms, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'eventorganization_send', '', 0, null, null, '2021-02-14 14:42:41', 'EventOrganizationEmailSubsEvent', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailSubsEvent)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventEventSubscriptionWasReceived)__

    __(Sincerely)__

    __MYCOMPANY_NAME__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, tms, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'eventorganization_send', '', 0, null, null, '2021-02-14 14:42:41', 'EventOrganizationMassEmailAttendees', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventBulkMailToAttendees)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); -INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, tms, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'eventorganization_send', '', 0, null, null, '2021-02-14 14:42:41', 'EventOrganizationMassEmailSpeakers', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__ __THIRDPARTY_NAME__,

    __(ThisIsContentOfYourOrganizationEventBulkMailToSpeakers)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +-- Event organization +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskConf)', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__,

    __(OrganizationEventConfRequestWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskBooth)', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__,

    __(OrganizationEventBoothRequestWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +-- TODO Add message for registration only to event __ONLINE_PAYMENT_TEXT_AND_URL__ +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsBooth)', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailBoothPayment)__', '__(Hello)__,

    __(OrganizationEventPaymentOfBoothWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsEvent)', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailRegistrationPayment)__', '__(Hello)__,

    __(OrganizationEventPaymentOfRegistrationWasReceived)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailAttendees)', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__,

    __(OrganizationEventBulkMailToAttendees)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailSpeakers)', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__,

    __(OrganizationEventBulkMailToSpeakers)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); ALTER TABLE llx_projet ADD COLUMN accept_conference_suggestions integer DEFAULT 0; ALTER TABLE llx_projet ADD COLUMN accept_booth_suggestions integer DEFAULT 0; @@ -349,6 +372,13 @@ UPDATE llx_payment_salary SET ref = rowid WHERE ref IS NULL; ALTER TABLE llx_salary ALTER COLUMN paye set default 0; +UPDATE llx_extrafields SET elementtype = 'salary' WHERE elementtype = 'payment_salary'; +ALTER TABLE llx_payment_salary_extrafields RENAME TO llx_salary_extrafields; +-- VMYSQL4.1 DROP INDEX idx_payment_salary_extrafields on llx_salary_extrafields; +-- VPGSQL8.2 DROP INDEX idx_payment_salary_extrafields; +ALTER TABLE llx_salary_extrafields ADD INDEX idx_salary_extrafields (fk_object); + + DELETE FROM llx_boxes WHERE box_id IN (SELECT rowid FROM llx_boxes_def WHERE file IN ('box_graph_ticket_by_severity', 'box_ticket_by_severity.php', 'box_nb_ticket_last_x_days.php', 'box_nb_tickets_type.php', 'box_new_vs_close_ticket.php')); DELETE FROM llx_boxes_def WHERE file IN ('box_graph_ticket_by_severity', 'box_ticket_by_severity.php', 'box_nb_ticket_last_x_days.php', 'box_nb_tickets_type.php', 'box_new_vs_close_ticket.php'); @@ -394,6 +424,7 @@ CREATE TABLE llx_eventorganization_conferenceorboothattendee( fk_soc integer, fk_actioncomm integer, fk_project integer NOT NULL, + fk_invoice integer NULL, email varchar(100), date_subscription datetime, amount double DEFAULT NULL, @@ -413,15 +444,24 @@ CREATE TABLE llx_eventorganization_conferenceorboothattendee( -- VPGSQL8.2 ALTER TABLE llx_eventorganization_conferenceorboothattendee ALTER COLUMN fk_actioncomm DROP NOT NULL; ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN fk_project integer NOT NULL; +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN fk_invoice integer NULL; + +ALTER TABLE llx_eventorganization_conferenceorboothattendee DROP FOREIGN KEY fx_eventorganization_conferenceorboothattendee_fk_soc; +ALTER TABLE llx_eventorganization_conferenceorboothattendee DROP FOREIGN KEY fx_eventorganization_conferenceorboothattendee_fk_actioncomm; +ALTER TABLE llx_eventorganization_conferenceorboothattendee DROP FOREIGN KEY fx_eventorganization_conferenceorboothattendee_fk_project; ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_rowid (rowid); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_ref (ref); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_fk_soc (fk_soc); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_fk_actioncomm (fk_actioncomm); -ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD CONSTRAINT fx_eventorganization_conferenceorboothattendee_fk_actioncomm FOREIGN KEY (fk_actioncomm) REFERENCES llx_actioncomm(id); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_email (email); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_status (status); -ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD UNIQUE INDEX uk_eventorganization_conferenceorboothattendee(fk_soc, fk_actioncomm, email); + +-- VMYSQL4.1 DROP INDEX uk_eventorganization_conferenceorboothattendee on llx_eventorganization_conferenceorboothattendee; +-- VPGSQL8.2 DROP INDEX uk_eventorganization_conferenceorboothattendee; + +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD UNIQUE INDEX uk_eventorganization_conferenceorboothattendee(fk_project, email, fk_actioncomm); + create table llx_eventorganization_conferenceorboothattendee_extrafields ( @@ -589,7 +629,7 @@ DROP TABLE llx_categorie_association; DROP TABLE llx_cond_reglement; DROP TABLE llx_zapier_hook_extrafields; -create table llx_onlinesignature +CREATE TABLE llx_onlinesignature ( rowid integer AUTO_INCREMENT PRIMARY KEY, entity integer DEFAULT 1 NOT NULL, @@ -604,3 +644,8 @@ create table llx_onlinesignature -- VMYSQL4.3 ALTER TABLE llx_partnership MODIFY COLUMN date_partnership_end date NULL; -- VPGSQL8.2 ALTER TABLE llx_partnership ALTER COLUMN date_partnership_end DROP NOT NULL; + +ALTER TABLE llx_facture_fourn CHANGE COLUMN fk_mode_transport fk_transport_mode integer; + +ALTER TABLE llx_c_socialnetworks DROP INDEX idx_c_socialnetworks_code; +ALTER TABLE llx_c_socialnetworks ADD UNIQUE INDEX idx_c_socialnetworks_code_entity (code, entity); diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index c76be4edbde..0a8be50ee92 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -12,8 +12,8 @@ -- To change type of field: ALTER TABLE llx_table MODIFY COLUMN name varchar(60); -- To drop a foreign key: ALTER TABLE llx_table DROP FOREIGN KEY fk_name; -- To create a unique index ALTER TABLE llx_table ADD UNIQUE INDEX uk_table_field (field); --- To drop an index: -- VMYSQL4.1 DROP INDEX nomindex on llx_table --- To drop an index: -- VPGSQL8.2 DROP INDEX nomindex +-- To drop an index: -- VMYSQL4.1 DROP INDEX nomindex on llx_table; +-- To drop an index: -- VPGSQL8.2 DROP INDEX nomindex; -- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_table CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; -- To make pk to be auto increment (postgres): -- -- VPGSQL8.2 CREATE SEQUENCE llx_table_rowid_seq OWNED BY llx_table.rowid; @@ -35,14 +35,85 @@ -- VMYSQL4.3 ALTER TABLE llx_partnership MODIFY COLUMN date_partnership_end date NULL; -- VPGSQL8.2 ALTER TABLE llx_partnership ALTER COLUMN date_partnership_end DROP NOT NULL; +ALTER TABLE llx_accounting_bookkeeping ADD COLUMN date_export datetime DEFAULT NULL; + +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN fk_project integer NOT NULL; +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN fk_invoice integer NULL; + +ALTER TABLE llx_eventorganization_conferenceorboothattendee DROP FOREIGN KEY fx_eventorganization_conferenceorboothattendee_fk_soc; +ALTER TABLE llx_eventorganization_conferenceorboothattendee DROP FOREIGN KEY fx_eventorganization_conferenceorboothattendee_fk_actioncomm; +ALTER TABLE llx_eventorganization_conferenceorboothattendee DROP FOREIGN KEY fx_eventorganization_conferenceorboothattendee_fk_project; + +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_rowid (rowid); +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_ref (ref); +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_fk_soc (fk_soc); +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_fk_actioncomm (fk_actioncomm); +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_email (email); +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_status (status); + +-- VMYSQL4.1 DROP INDEX uk_eventorganization_conferenceorboothattendee on llx_eventorganization_conferenceorboothattendee; +-- VPGSQL8.2 DROP INDEX uk_eventorganization_conferenceorboothattendee; + +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD UNIQUE INDEX uk_eventorganization_conferenceorboothattendee(fk_project, email, fk_actioncomm); + + -- VMYSQL4.3 ALTER TABLE llx_eventorganization_conferenceorboothattendee MODIFY COLUMN fk_actioncomm integer NULL; -- VPGSQL8.2 ALTER TABLE llx_eventorganization_conferenceorboothattendee ALTER COLUMN fk_actioncomm DROP NOT NULL; -ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN fk_project integer NOT NULL; +ALTER TABLE llx_mrp_mo ADD COLUMN last_main_doc varchar(255); + +UPDATE llx_extrafields SET elementtype = 'salary' WHERE elementtype = 'payment_salary'; +ALTER TABLE llx_payment_salary_extrafields RENAME TO llx_salary_extrafields; +-- VMYSQL4.1 DROP INDEX idx_payment_salary_extrafields on llx_salary_extrafields; +-- VPGSQL8.2 DROP INDEX idx_payment_salary_extrafields; +ALTER TABLE llx_salary_extrafields ADD INDEX idx_salary_extrafields (fk_object); + + +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskConf)', 10, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskConf)__', '__(Hello)__,

    __(OrganizationEventConfRequestWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailAskBooth)', 20, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailAskBooth)__', '__(Hello)__,

    __(OrganizationEventBoothRequestWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +-- TODO Add message for registration only to event __ONLINE_PAYMENT_TEXT_AND_URL__ +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsBooth)', 30, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailBoothPayment)__', '__(Hello)__,

    __(OrganizationEventPaymentOfBoothWasReceived)__


    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationEmailSubsEvent)', 40, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationEmailRegistrationPayment)__', '__(Hello)__,

    __(OrganizationEventPaymentOfRegistrationWasReceived)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailAttendees)', 50, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailAttendees)__', '__(Hello)__,

    __(OrganizationEventBulkMailToAttendees)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); +INSERT INTO llx_c_email_templates (entity, module, type_template, lang, private, fk_user, datec, label, position, active, topic, content, content_lines, enabled, joinfiles) values (0, '', 'conferenceorbooth', '', 0, null, null, '(EventOrganizationMassEmailSpeakers)', 60, 1, '[__[MAIN_INFO_SOCIETE_NOM]__] __(EventOrganizationMassEmailSpeakers)__', '__(Hello)__,

    __(OrganizationEventBulkMailToSpeakers)__

    __(Sincerely)__
    __USER_SIGNATURE__', null, '1', null); + + +--Fix bad sign on multicompany column for customer invoice lines +UPDATE llx_facturedet SET multicurrency_subprice = -multicurrency_subprice WHERE ((multicurrency_subprice < 0 and subprice > 0) OR (multicurrency_subprice > 0 and subprice < 0)); +UPDATE llx_facturedet SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facturedet SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facturedet SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicompany column for customer invoices +UPDATE llx_facture SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facture SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicurrency column for supplier invoice lines +UPDATE llx_facture_fourn_det SET multicurrency_subprice = -multicurrency_subprice WHERE ((multicurrency_subprice < 0 and pu_ht > 0) OR (multicurrency_subprice > 0 and pu_ht < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and tva > 0) OR (multicurrency_total_tva > 0 and tva < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicompany column for customer invoices +UPDATE llx_facture_fourn SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture_fourn SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facture_fourn SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); -- v15 +ALTER TABLE llx_c_partnership_type ADD UNIQUE INDEX uk_c_partnership_type(entity, code); + +ALTER TABLE llx_partnership ADD COLUMN fk_type integer DEFAULT 0 NOT NULL; + +ALTER TABLE llx_c_holiday_types CHANGE COLUMN newByMonth newbymonth double(8,5) DEFAULT 0 NOT NULL; + +ALTER TABLE llx_product ADD COLUMN mandatory_period tinyint NULL DEFAULT 0; + +ALTER TABLE llx_holiday ADD COLUMN date_approve DATETIME DEFAULT NULL; +ALTER TABLE llx_holiday ADD COLUMN fk_user_approve integer DEFAULT NULL; + +ALTER TABLE llx_ticket MODIFY COLUMN progress integer; + + ALTER TABLE llx_emailcollector_emailcollectoraction MODIFY COLUMN actionparam TEXT; ALTER TABLE llx_knowledgemanagement_knowledgerecord ADD COLUMN lang varchar(6); @@ -63,6 +134,7 @@ ALTER TABLE llx_categorie_ticket ADD CONSTRAINT fk_categorie_ticket_categorie_ro ALTER TABLE llx_categorie_ticket ADD CONSTRAINT fk_categorie_ticket_ticket_rowid FOREIGN KEY (fk_ticket) REFERENCES llx_ticket (rowid); ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN ref_fourn varchar(128); ALTER TABLE llx_product_customer_price MODIFY COLUMN ref_customer varchar(128); +ALTER TABLE llx_product_association ADD COLUMN rang integer DEFAULT 0; -- -- add action trigger INSERT INTO llx_c_action_trigger (code,label,description,elementtype,rang) VALUES ('ORDER_SUPPLIER_CANCEL','Supplier order request canceled','Executed when a supplier order is canceled','order_supplier',13); @@ -73,5 +145,306 @@ ALTER TABLE llx_mrp_mo ADD COLUMN mrptype integer DEFAULT 0; DELETE FROM llx_menu WHERE type = 'top' AND module = 'cashdesk' AND mainmenu = 'cashdesk'; - INSERT INTO llx_c_action_trigger (code, label, description, elementtype, rang) values ('MEMBER_EXCLUDE', 'Member excluded', 'Executed when a member is excluded', 'member', 27); + +CREATE TABLE llx_categorie_knowledgemanagement +( + fk_categorie integer NOT NULL, + fk_knowledgemanagement integer NOT NULL, + import_key varchar(14) +)ENGINE=innodb; + +ALTER TABLE llx_categorie_knowledgemanagement ADD PRIMARY KEY pk_categorie_knowledgemanagement (fk_categorie, fk_knowledgemanagement); +ALTER TABLE llx_categorie_knowledgemanagement ADD INDEX idx_categorie_knowledgemanagement_fk_categorie (fk_categorie); +ALTER TABLE llx_categorie_knowledgemanagement ADD INDEX idx_categorie_knowledgemanagement_fk_knowledgemanagement (fk_knowledgemanagement); + +ALTER TABLE llx_categorie_knowledgemanagement ADD CONSTRAINT fk_categorie_knowledgemanagement_categorie_rowid FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid); +ALTER TABLE llx_categorie_knowledgemanagement ADD CONSTRAINT fk_categorie_knowledgemanagement_knowledgemanagement_rowid FOREIGN KEY (fk_knowledgemanagement) REFERENCES llx_knowledgemanagement_knowledgerecord (rowid); + +ALTER TABLE llx_product_lot ADD COLUMN barcode varchar(180) DEFAULT NULL; +ALTER TABLE llx_product_lot ADD COLUMN fk_barcode_type integer DEFAULT NULL; + +ALTER TABLE llx_projet ADD COLUMN max_attendees integer DEFAULT 0; + +ALTER TABLE llx_commande_fournisseur_dispatch ADD COLUMN cost_price double(24,8) DEFAULT 0; + +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2001', 'Aktiebolag'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2002', 'Publikt aktiebolag (AB publ)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2003', 'Ekonomisk förening (ek. för.)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2004', 'Bostadsrättsförening (BRF)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2005', 'Hyresrättsförening (HRF)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2006', 'Kooperativ'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2007', 'Enskild firma (EF)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2008', 'Handelsbolag (HB)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2009', 'Kommanditbolag (KB)'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2010', 'Enkelt bolag'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2011', 'Ideell förening'); +INSERT INTO llx_c_forme_juridique (fk_pays, code, libelle) VALUES (20, '2012', 'Stiftelse'); + +-- START GRH/HRM MODULE + + +CREATE TABLE llx_hrm_evaluation +( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + description text, + note_public text, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + status smallint NOT NULL, + date_eval date, + fk_user integer NOT NULL, + fk_job integer NOT NULL +) ENGINE=innodb; +ALTER TABLE llx_hrm_evaluation ADD INDEX idx_hrm_evaluation_rowid (rowid); +ALTER TABLE llx_hrm_evaluation ADD INDEX idx_hrm_evaluation_ref (ref); +ALTER TABLE llx_hrm_evaluation ADD CONSTRAINT llx_hrm_evaluation_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_hrm_evaluation ADD INDEX idx_hrm_evaluation_status (status); + + +create table llx_hrm_evaluation_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_hrm_evaluation_extrafields ADD INDEX idx_evaluation_fk_object(fk_object); + + +CREATE TABLE llx_hrm_evaluationdet +( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + fk_skill integer NOT NULL, + fk_evaluation integer NOT NULL, + rankorder integer NOT NULL, + required_rank integer NOT NULL, + import_key varchar(14) +) ENGINE=innodb; + +ALTER TABLE llx_hrm_evaluationdet ADD INDEX idx_hrm_evaluationdet_rowid (rowid); +ALTER TABLE llx_hrm_evaluationdet ADD CONSTRAINT llx_hrm_evaluationdet_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_hrm_evaluationdet ADD INDEX idx_hrm_evaluationdet_fk_skill (fk_skill); +ALTER TABLE llx_hrm_evaluationdet ADD INDEX idx_hrm_evaluationdet_fk_evaluation (fk_evaluation); + + +create table llx_hrm_evaluationdet_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_hrm_evaluationdet_extrafields ADD INDEX idx_evaluationdet_fk_object(fk_object); + + + +CREATE TABLE llx_hrm_job +( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + label varchar(255) NOT NULL, + description text, + date_creation datetime NOT NULL, + tms timestamp, + deplacement varchar(255), + note_public text, + note_private text, + fk_user_creat integer, + fk_user_modif integer +) ENGINE=innodb; + +ALTER TABLE llx_hrm_job ADD INDEX idx_hrm_job_rowid (rowid); +ALTER TABLE llx_hrm_job ADD INDEX idx_hrm_job_label (label); + + +create table llx_hrm_job_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_hrm_job_extrafields ADD INDEX idx_job_fk_object(fk_object); + + + +CREATE TABLE llx_hrm_job_user( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + -- ref varchar(128) NOT NULL, + description text, + date_creation datetime NOT NULL, + tms timestamp, + fk_contrat integer, + fk_user integer NOT NULL, + fk_job integer NOT NULL, + date_start date, + date_end date, + abort_comment varchar(255), + note_public text, + note_private text, + fk_user_creat integer, + fk_user_modif integer +) ENGINE=innodb; + +ALTER TABLE llx_hrm_job_user ADD INDEX idx_hrm_job_user_rowid (rowid); +-- ALTER TABLE llx_hrm_job_user ADD INDEX idx_hrm_job_user_ref (ref); + + +create table llx_hrm_job_user_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_hrm_job_user_extrafields ADD INDEX idx_position_fk_object(fk_object); + + + +CREATE TABLE llx_hrm_skill +( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + label varchar(255), + description text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + required_level integer NOT NULL, + date_validite integer NOT NULL, + temps_theorique double(24,8) NOT NULL, + skill_type integer NOT NULL, + note_public text, + note_private text +) ENGINE=innodb; + +ALTER TABLE llx_hrm_skill ADD INDEX idx_hrm_skill_rowid (rowid); +ALTER TABLE llx_hrm_skill ADD CONSTRAINT llx_hrm_skill_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_hrm_skill ADD INDEX idx_hrm_skill_skill_type (skill_type); + +create table llx_hrm_skill_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_hrm_skill_extrafields ADD INDEX idx_skill_fk_object(fk_object); + + +CREATE TABLE llx_hrm_skilldet +( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + description text, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + fk_skill integer NOT NULL, + rankorder integer +) ENGINE=innodb; + +ALTER TABLE llx_hrm_skilldet ADD INDEX idx_hrm_skilldet_rowid (rowid); +ALTER TABLE llx_hrm_skilldet ADD CONSTRAINT llx_hrm_skilldet_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); + +create table llx_hrm_skilldet_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + +ALTER TABLE llx_hrm_skilldet_extrafields ADD INDEX idx_skilldet_fk_object(fk_object); + + +CREATE TABLE llx_hrm_skillrank +( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + fk_skill integer NOT NULL, + rankorder integer NOT NULL, + fk_object integer NOT NULL, + date_creation datetime NOT NULL, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + objecttype varchar(128) NOT NULL +) ENGINE=innodb; + +ALTER TABLE llx_hrm_skillrank ADD INDEX idx_hrm_skillrank_rowid (rowid); +ALTER TABLE llx_hrm_skillrank ADD INDEX idx_hrm_skillrank_fk_skill (fk_skill); +ALTER TABLE llx_hrm_skillrank ADD CONSTRAINT llx_hrm_skillrank_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); + +--END GRH/HRM MODULE + +ALTER TABLE llx_c_units ADD COLUMN sortorder smallint AFTER code; + +-- Manage accountancy auxiliary account for thirdparties per entity +ALTER TABLE llx_societe_perentity ADD COLUMN accountancy_code_customer varchar(24) AFTER entity; -- equivalent to code_compta in llx_societe +ALTER TABLE llx_societe_perentity ADD COLUMN accountancy_code_supplier varchar(24) AFTER accountancy_code_customer; -- equivalent to code_compta_supplier in llx_societe + +ALTER TABLE llx_projet_task ADD COLUMN budget_amount double(24,8) AFTER priority; + +-- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_graph_ticket_by_severity.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_graph_ticket_by_severity.php' AND entity = 1); +-- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_graph_nb_ticket_last_x_days.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_graph_nb_ticket_last_x_days.php' AND entity = 1); +-- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_graph_nb_tickets_type.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_graph_nb_tickets_type.php' AND entity = 1); +-- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_graph_new_vs_close_ticket.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_graph_new_vs_close_ticket.php' AND entity = 1); + +ALTER TABLE llx_user DROP COLUMN jabberid; +ALTER TABLE llx_user DROP COLUMN skype; +ALTER TABLE llx_user DROP COLUMN twitter; +ALTER TABLE llx_user DROP COLUMN facebook; +ALTER TABLE llx_user DROP COLUMN linkedin; +ALTER TABLE llx_user DROP COLUMN instagram; +ALTER TABLE llx_user DROP COLUMN snapchat; +ALTER TABLE llx_user DROP COLUMN googleplus; +ALTER TABLE llx_user DROP COLUMN youtube; +ALTER TABLE llx_user DROP COLUMN whatsapp; + +ALTER TABLE llx_adherent DROP COLUMN jabberid; +ALTER TABLE llx_adherent DROP COLUMN skype; +ALTER TABLE llx_adherent DROP COLUMN twitter; +ALTER TABLE llx_adherent DROP COLUMN facebook; +ALTER TABLE llx_adherent DROP COLUMN linkedin; +ALTER TABLE llx_adherent DROP COLUMN instagram; +ALTER TABLE llx_adherent DROP COLUMN snapchat; +ALTER TABLE llx_adherent DROP COLUMN googleplus; +ALTER TABLE llx_adherent DROP COLUMN youtube; +ALTER TABLE llx_adherent DROP COLUMN whatsapp; + +ALTER TABLE llx_societe DROP COLUMN jabberid; +ALTER TABLE llx_societe DROP COLUMN skype; +ALTER TABLE llx_societe DROP COLUMN twitter; +ALTER TABLE llx_societe DROP COLUMN facebook; +ALTER TABLE llx_societe DROP COLUMN linkedin; +ALTER TABLE llx_societe DROP COLUMN instagram; +ALTER TABLE llx_societe DROP COLUMN snapchat; +ALTER TABLE llx_societe DROP COLUMN googleplus; +ALTER TABLE llx_societe DROP COLUMN youtube; +ALTER TABLE llx_societe DROP COLUMN whatsapp; + +ALTER TABLE llx_socpeople DROP COLUMN jabberid; +ALTER TABLE llx_socpeople DROP COLUMN skype; +ALTER TABLE llx_socpeople DROP COLUMN twitter; +ALTER TABLE llx_socpeople DROP COLUMN facebook; +ALTER TABLE llx_socpeople DROP COLUMN linkedin; +ALTER TABLE llx_socpeople DROP COLUMN instagram; +ALTER TABLE llx_socpeople DROP COLUMN snapchat; +ALTER TABLE llx_socpeople DROP COLUMN googleplus; +ALTER TABLE llx_socpeople DROP COLUMN youtube; +ALTER TABLE llx_socpeople DROP COLUMN whatsapp; + diff --git a/htdocs/install/mysql/migration/repair.sql b/htdocs/install/mysql/migration/repair.sql index 59f04fdb2ca..5208a733769 100644 --- a/htdocs/install/mysql/migration/repair.sql +++ b/htdocs/install/mysql/migration/repair.sql @@ -501,6 +501,25 @@ UPDATE llx_accounting_bookkeeping set date_creation = tms where date_creation IS -- UPDATE llx_facturedet_rec set label = NULL WHERE label IS NOT NULL; +--Fix bad sign on multicompany column for customer invoice lines +UPDATE llx_facturedet SET multicurrency_subprice = -multicurrency_subprice WHERE ((multicurrency_subprice < 0 and subprice > 0) OR (multicurrency_subprice > 0 and subprice < 0)); +UPDATE llx_facturedet SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facturedet SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facturedet SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicompany column for customer invoices +UPDATE llx_facture SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facture SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicurrency column for supplier invoice lines +UPDATE llx_facture_fourn_det SET multicurrency_subprice = -multicurrency_subprice WHERE ((multicurrency_subprice < 0 and pu_ht > 0) OR (multicurrency_subprice > 0 and pu_ht < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and tva > 0) OR (multicurrency_total_tva > 0 and tva < 0)); +UPDATE llx_facture_fourn_det SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); +--Fix bad sign on multicompany column for customer invoices +UPDATE llx_facture_fourn SET multicurrency_total_ht = -multicurrency_total_ht WHERE ((multicurrency_total_ht < 0 and total_ht > 0) OR (multicurrency_total_ht > 0 and total_ht < 0)); +UPDATE llx_facture_fourn SET multicurrency_total_tva = -multicurrency_total_tva WHERE ((multicurrency_total_tva < 0 and total_tva > 0) OR (multicurrency_total_tva > 0 and total_tva < 0)); +UPDATE llx_facture_fourn SET multicurrency_total_ttc = -multicurrency_total_ttc WHERE ((multicurrency_total_ttc < 0 and total_ttc > 0) OR (multicurrency_total_ttc > 0 and total_ttc < 0)); + UPDATE llx_facturedet SET situation_percent = 100 WHERE situation_percent IS NULL AND fk_prev_id IS NULL; diff --git a/htdocs/install/mysql/tables/llx_adherent.sql b/htdocs/install/mysql/tables/llx_adherent.sql index 1d3a784dd74..bd74c33c688 100644 --- a/htdocs/install/mysql/tables/llx_adherent.sql +++ b/htdocs/install/mysql/tables/llx_adherent.sql @@ -51,15 +51,15 @@ create table llx_adherent url varchar(255) NULL, socialnetworks text DEFAULT NULL, -- json with socialnetworks - skype varchar(255), -- deprecated - twitter varchar(255), -- deprecated - facebook varchar(255), -- deprecated - linkedin varchar(255), -- deprecated - instagram varchar(255), -- deprecated - snapchat varchar(255), -- deprecated - googleplus varchar(255), -- deprecated - youtube varchar(255), -- deprecated - whatsapp varchar(255), -- deprecated + --skype varchar(255), -- deprecated + --twitter varchar(255), -- deprecated + --facebook varchar(255), -- deprecated + --linkedin varchar(255), -- deprecated + --instagram varchar(255), -- deprecated + --snapchat varchar(255), -- deprecated + --googleplus varchar(255), -- deprecated + --youtube varchar(255), -- deprecated + --whatsapp varchar(255), -- deprecated phone varchar(30), phone_perso varchar(30), diff --git a/htdocs/install/mysql/tables/llx_c_holiday_types.sql b/htdocs/install/mysql/tables/llx_c_holiday_types.sql index 9c09d486bec..b602ee1d330 100644 --- a/htdocs/install/mysql/tables/llx_c_holiday_types.sql +++ b/htdocs/install/mysql/tables/llx_c_holiday_types.sql @@ -22,7 +22,7 @@ CREATE TABLE llx_c_holiday_types ( label varchar(255) NOT NULL, affect integer NOT NULL, -- a request will change sold or not delay integer NOT NULL, -- Minimum delay to be allowed to make request - newByMonth double(8,5) DEFAULT 0 NOT NULL, -- Amount of new days for each user each month + newbymonth double(8,5) DEFAULT 0 NOT NULL, -- Amount of new days for each user each month fk_country integer DEFAULT NULL, -- This type is dedicated to a country active integer DEFAULT 1 ) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_c_partnership_type.key.sql b/htdocs/install/mysql/tables/llx_c_partnership_type.key.sql new file mode 100644 index 00000000000..c4aa0c04b0a --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_partnership_type.key.sql @@ -0,0 +1,19 @@ +-- ======================================================================== +-- Copyright (C) 2021 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 +-- 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 . +-- +-- ======================================================================== + +ALTER TABLE llx_c_partnership_type ADD UNIQUE INDEX uk_c_partnership_type(entity, code); diff --git a/htdocs/install/mysql/tables/llx_c_partnership_type.sql b/htdocs/install/mysql/tables/llx_c_partnership_type.sql index 23d5a89e16c..d2a4a3b7549 100644 --- a/htdocs/install/mysql/tables/llx_c_partnership_type.sql +++ b/htdocs/install/mysql/tables/llx_c_partnership_type.sql @@ -30,6 +30,6 @@ create table llx_c_partnership_type entity integer DEFAULT 1 NOT NULL, code varchar(32) NOT NULL, label varchar(64) NOT NULL, - active tinyint DEFAULT 1 NOT NULL + active tinyint DEFAULT 1 NOT NULL )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_c_socialnetworks.key.sql b/htdocs/install/mysql/tables/llx_c_socialnetworks.key.sql index 2b7dcdc9d4e..3d3afb94d8a 100644 --- a/htdocs/install/mysql/tables/llx_c_socialnetworks.key.sql +++ b/htdocs/install/mysql/tables/llx_c_socialnetworks.key.sql @@ -16,4 +16,4 @@ -- ======================================================================== -ALTER TABLE llx_c_socialnetworks ADD UNIQUE INDEX idx_c_socialnetworks_code (code); +ALTER TABLE llx_c_socialnetworks ADD UNIQUE INDEX idx_c_socialnetworks_code_entity (entity, code); diff --git a/htdocs/install/mysql/tables/llx_c_units.sql b/htdocs/install/mysql/tables/llx_c_units.sql index d4ff78b79f1..ef77703ae6e 100644 --- a/htdocs/install/mysql/tables/llx_c_units.sql +++ b/htdocs/install/mysql/tables/llx_c_units.sql @@ -19,11 +19,12 @@ -- ======================================================================== create table llx_c_units( - rowid integer AUTO_INCREMENT PRIMARY KEY, - code varchar(3), - scale integer, - label varchar(50), - short_label varchar(5), - unit_type varchar(10), - active tinyint DEFAULT 1 NOT NULL + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(3), + sortorder smallint, + scale integer, + label varchar(50), + short_label varchar(5), + unit_type varchar(10), + active tinyint DEFAULT 1 NOT NULL ) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_categorie_knowledgemanagement.key.sql b/htdocs/install/mysql/tables/llx_categorie_knowledgemanagement.key.sql new file mode 100644 index 00000000000..47769643bd5 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_categorie_knowledgemanagement.key.sql @@ -0,0 +1,21 @@ +-- Copyright (C) 2021 EOXIA +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +ALTER TABLE llx_categorie_knowledgemanagement ADD PRIMARY KEY pk_categorie_knowledgemanagement (fk_categorie, fk_knowledgemanagement); +ALTER TABLE llx_categorie_knowledgemanagement ADD INDEX idx_categorie_knowledgemanagement_fk_categorie (fk_categorie); +ALTER TABLE llx_categorie_knowledgemanagement ADD INDEX idx_categorie_knowledgemanagement_fk_knowledgemanagement (fk_knowledgemanagement); + +ALTER TABLE llx_categorie_knowledgemanagement ADD CONSTRAINT fk_categorie_knowledgemanagement_categorie_rowid FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid); +ALTER TABLE llx_categorie_knowledgemanagement ADD CONSTRAINT fk_categorie_knowledgemanagement_knowledgemanagement_rowid FOREIGN KEY (fk_knowledgemanagement) REFERENCES llx_knowledgemanagement (rowid); diff --git a/htdocs/install/mysql/tables/llx_categorie_knowledgemanagement.sql b/htdocs/install/mysql/tables/llx_categorie_knowledgemanagement.sql new file mode 100644 index 00000000000..a693fb19c41 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_categorie_knowledgemanagement.sql @@ -0,0 +1,20 @@ +-- Copyright (C) 2021 EOXIA +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +create table llx_categorie_knowledgemanagement( + fk_categorie integer NOT NULL, + fk_knowledgemanagement integer NOT NULL, + import_key varchar(14) +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql index b5f85fea250..974e10c09ff 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur_dispatch.sql @@ -36,5 +36,6 @@ create table llx_commande_fournisseur_dispatch sellby date DEFAULT NULL, status integer, datec datetime, - tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + cost_price double(24,8) DEFAULT 0 )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseurdet.sql b/htdocs/install/mysql/tables/llx_commande_fournisseurdet.sql index c7a7f8ecf7f..b780d24f1e2 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseurdet.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseurdet.sql @@ -29,10 +29,10 @@ create table llx_commande_fournisseurdet label varchar(255), -- product label description text, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3) DEFAULT 0, -- taux tva - localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + tva_tx double(7,4) DEFAULT 0, -- taux tva + localtax1_tx double(7,4) DEFAULT 0, -- localtax1 rate localtax1_type varchar(10) NULL, -- localtax1 type - localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_tx double(7,4) DEFAULT 0, -- localtax2 rate localtax2_type varchar(10) NULL, -- localtax2 type qty real, -- quantity remise_percent real DEFAULT 0, -- pourcentage de remise diff --git a/htdocs/install/mysql/tables/llx_commandedet.sql b/htdocs/install/mysql/tables/llx_commandedet.sql index c7b94a46add..caff1ce7028 100644 --- a/htdocs/install/mysql/tables/llx_commandedet.sql +++ b/htdocs/install/mysql/tables/llx_commandedet.sql @@ -29,10 +29,10 @@ create table llx_commandedet label varchar(255) DEFAULT NULL, description text, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3), -- Vat rate - localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + tva_tx double(7,4), -- Vat rate + localtax1_tx double(7,4) DEFAULT 0, -- localtax1 rate localtax1_type varchar(10) NULL, -- localtax1 type - localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_tx double(7,4) DEFAULT 0, -- localtax2 rate localtax2_type varchar(10) NULL, -- localtax2 type qty real, -- quantity remise_percent real DEFAULT 0, -- pourcentage de remise diff --git a/htdocs/install/mysql/tables/llx_contratdet.sql b/htdocs/install/mysql/tables/llx_contratdet.sql index bbe19955e33..e9be3c4ad0c 100644 --- a/htdocs/install/mysql/tables/llx_contratdet.sql +++ b/htdocs/install/mysql/tables/llx_contratdet.sql @@ -38,10 +38,10 @@ create table llx_contratdet date_cloture datetime, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3) DEFAULT 0, -- taux tva - localtax1_tx double(6,3) DEFAULT 0, -- local tax 1 rate + tva_tx double(7,4) DEFAULT 0, -- taux tva + localtax1_tx double(7,4) DEFAULT 0, -- local tax 1 rate localtax1_type varchar(10) NULL, -- localtax1 type - localtax2_tx double(6,3) DEFAULT 0, -- local tax 2 rate + localtax2_tx double(7,4) DEFAULT 0, -- local tax 2 rate localtax2_type varchar(10) NULL, -- localtax2 type qty real NOT NULL, -- quantity remise_percent real DEFAULT 0, -- pourcentage de remise diff --git a/htdocs/install/mysql/tables/llx_element_tag.key.sql b/htdocs/install/mysql/tables/llx_element_tag.key.sql new file mode 100644 index 00000000000..d3a0b38afa9 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_element_tag.key.sql @@ -0,0 +1,21 @@ +-- ============================================================================ +-- Copyright (C) 2021 Maxime Kohlhaas +-- +-- 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 . +-- +-- ============================================================================ + +ALTER TABLE llx_element_tag ADD UNIQUE INDEX idx_element_tag_uk (fk_categorie, fk_element); + +ALTER TABLE llx_element_tag ADD CONSTRAINT fk_element_tag_categorie_rowid FOREIGN KEY (fk_categorie) REFERENCES llx_categorie (rowid); diff --git a/htdocs/install/mysql/tables/llx_element_tag.sql b/htdocs/install/mysql/tables/llx_element_tag.sql new file mode 100644 index 00000000000..d43ced98130 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_element_tag.sql @@ -0,0 +1,25 @@ +-- ============================================================================ +-- Copyright (C) 2021 Maxime Kohlhaas +-- +-- 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 . +-- +-- ============================================================================ + +create table llx_element_tag +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + fk_categorie integer NOT NULL, + fk_element integer NOT NULL, + import_key varchar(14) +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_eventorganization_conferenceorboothattendee.key.sql b/htdocs/install/mysql/tables/llx_eventorganization_conferenceorboothattendee.key.sql index 0633e3cc2a2..9e1bbcde191 100644 --- a/htdocs/install/mysql/tables/llx_eventorganization_conferenceorboothattendee.key.sql +++ b/htdocs/install/mysql/tables/llx_eventorganization_conferenceorboothattendee.key.sql @@ -18,15 +18,11 @@ ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_rowid (rowid); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_ref (ref); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_fk_soc (fk_soc); -ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD CONSTRAINT fx_eventorganization_conferenceorboothattendee_fk_soc FOREIGN KEY (fk_soc) REFERENCES llx_societe(rowid); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_fk_actioncomm (fk_actioncomm); -ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD CONSTRAINT fx_eventorganization_conferenceorboothattendee_fk_actioncomm FOREIGN KEY (fk_actioncomm) REFERENCES llx_actioncomm(id); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_fk_project (fk_project); -ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD CONSTRAINT fx_eventorganization_conferenceorboothattendee_fk_project FOREIGN KEY (fk_project) REFERENCES llx_projet(rowid); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_email (email); ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD INDEX idx_eventorganization_conferenceorboothattendee_status (status); -- END MODULEBUILDER INDEXES -ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD UNIQUE INDEX uk_eventorganization_conferenceorboothattendee(fk_soc, fk_project, fk_actioncomm, email); - +ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD UNIQUE INDEX uk_eventorganization_conferenceorboothattendee(fk_project, email, fk_actioncomm); diff --git a/htdocs/install/mysql/tables/llx_eventorganization_conferenceorboothattendee.sql b/htdocs/install/mysql/tables/llx_eventorganization_conferenceorboothattendee.sql index 6d01cf4bba1..b505f8f6a31 100644 --- a/htdocs/install/mysql/tables/llx_eventorganization_conferenceorboothattendee.sql +++ b/htdocs/install/mysql/tables/llx_eventorganization_conferenceorboothattendee.sql @@ -21,6 +21,7 @@ CREATE TABLE llx_eventorganization_conferenceorboothattendee( fk_soc integer, fk_actioncomm integer, fk_project integer NOT NULL, + fk_invoice integer NULL, email varchar(100), date_subscription datetime, amount double DEFAULT NULL, diff --git a/htdocs/install/mysql/tables/llx_expensereport_det.sql b/htdocs/install/mysql/tables/llx_expensereport_det.sql index bd97600e2c8..e6304f64c7f 100644 --- a/htdocs/install/mysql/tables/llx_expensereport_det.sql +++ b/htdocs/install/mysql/tables/llx_expensereport_det.sql @@ -31,10 +31,10 @@ CREATE TABLE llx_expensereport_det value_unit double(24,8) NOT NULL, -- P.U. TTC (example 120) remise_percent real, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3), -- Vat rate - localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + tva_tx double(7,4), -- Vat rate + localtax1_tx double(7,4) DEFAULT 0, -- localtax1 rate localtax1_type varchar(10) NULL, -- localtax1 type - localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_tx double(7,4) DEFAULT 0, -- localtax2 rate localtax2_type varchar(10) NULL, -- localtax2 type total_ht double(24,8) DEFAULT 0 NOT NULL, total_tva double(24,8) DEFAULT 0 NOT NULL, diff --git a/htdocs/install/mysql/tables/llx_facture_fourn_det.sql b/htdocs/install/mysql/tables/llx_facture_fourn_det.sql index 40b613d4ac5..4012fb7087d 100644 --- a/htdocs/install/mysql/tables/llx_facture_fourn_det.sql +++ b/htdocs/install/mysql/tables/llx_facture_fourn_det.sql @@ -33,10 +33,10 @@ create table llx_facture_fourn_det remise_percent real DEFAULT 0, -- % de la remise ligne (exemple 20%) fk_remise_except integer NULL, -- Lien vers table des remises fixes vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3), -- TVA taux product/service - localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + tva_tx double(7,4), -- TVA taux product/service + localtax1_tx double(7,4) DEFAULT 0, -- localtax1 rate localtax1_type varchar(10) NULL, -- localtax1 type - localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_tx double(7,4) DEFAULT 0, -- localtax2 rate localtax2_type varchar(10) NULL, -- localtax2 type total_ht double(24,8), -- Total line price of product excluding tax tva double(24,8), -- Total TVA of line diff --git a/htdocs/install/mysql/tables/llx_facturedet.sql b/htdocs/install/mysql/tables/llx_facturedet.sql index 3b1ea86cc0e..5e48b16be09 100644 --- a/htdocs/install/mysql/tables/llx_facturedet.sql +++ b/htdocs/install/mysql/tables/llx_facturedet.sql @@ -31,10 +31,10 @@ create table llx_facturedet label varchar(255) DEFAULT NULL, description text, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3), -- Vat rate (example 20%) - localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + tva_tx double(7,4), -- Vat rate (example 20%) + localtax1_tx double(7,4) DEFAULT 0, -- localtax1 rate localtax1_type varchar(10) NULL, -- localtax1 type - localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_tx double(7,4) DEFAULT 0, -- localtax2 rate localtax2_type varchar(10) NULL, -- localtax2 type qty real, -- Quantity (exemple 2). Note: for credit note, the price is negative, not the quantity. Like for discount, price is negative, not quantity. remise_percent real DEFAULT 0, -- % de la remise ligne (exemple 20%) diff --git a/htdocs/install/mysql/tables/llx_facturedet_rec.sql b/htdocs/install/mysql/tables/llx_facturedet_rec.sql index a66d7ccb0c3..f515276c442 100644 --- a/htdocs/install/mysql/tables/llx_facturedet_rec.sql +++ b/htdocs/install/mysql/tables/llx_facturedet_rec.sql @@ -30,10 +30,10 @@ create table llx_facturedet_rec label varchar(255) DEFAULT NULL, description text, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3), -- taux tva - localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + tva_tx double(7,4), -- taux tva + localtax1_tx double(7,4) DEFAULT 0, -- localtax1 rate localtax1_type varchar(10) NULL, -- localtax1 type - localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_tx double(7,4) DEFAULT 0, -- localtax2 rate localtax2_type varchar(10) NULL, -- localtax2 type qty real, -- quantity remise_percent real DEFAULT 0, -- pourcentage de remise diff --git a/htdocs/install/mysql/tables/llx_holiday.sql b/htdocs/install/mysql/tables/llx_holiday.sql index 3cd5727d867..992f9502394 100644 --- a/htdocs/install/mysql/tables/llx_holiday.sql +++ b/htdocs/install/mysql/tables/llx_holiday.sql @@ -33,8 +33,10 @@ date_fin DATE NOT NULL, halfday integer DEFAULT 0, -- 0=start morning and end afternoon, -1=start afternoon end afternoon, 1=start morning and end morning, 2=start afternoon and end morning statut integer NOT NULL DEFAULT '1', fk_validator integer NOT NULL, -- who should approve -date_valid DATETIME DEFAULT NULL, -- date approval -fk_user_valid integer DEFAULT NULL, -- user approval +date_valid DATETIME DEFAULT NULL, -- date approval (both date valid and date_approval) +fk_user_valid integer DEFAULT NULL, -- user approval (both user valid and user that approved) +date_approve DATETIME DEFAULT NULL, -- date approval (not used yet) +fk_user_approve integer DEFAULT NULL, -- user approval (not used yet) date_refuse DATETIME DEFAULT NULL, fk_user_refuse integer DEFAULT NULL, date_cancel DATETIME DEFAULT NULL, diff --git a/htdocs/install/mysql/tables/llx_hrm_evaluation.key.sql b/htdocs/install/mysql/tables/llx_hrm_evaluation.key.sql new file mode 100644 index 00000000000..804bc6b4803 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_evaluation.key.sql @@ -0,0 +1,29 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_evaluation ADD INDEX idx_hrm_evaluation_rowid (rowid); +ALTER TABLE llx_hrm_evaluation ADD INDEX idx_hrm_evaluation_ref (ref); +ALTER TABLE llx_hrm_evaluation ADD CONSTRAINT llx_hrm_evaluation_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_hrm_evaluation ADD INDEX idx_hrm_evaluation_status (status); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_hrm_evaluation ADD UNIQUE INDEX uk_hrm_evaluation_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_hrm_evaluation ADD CONSTRAINT llx_hrm_evaluation_fk_field FOREIGN KEY (fk_field) REFERENCES llx_hrm_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_hrm_evaluation.sql b/htdocs/install/mysql/tables/llx_hrm_evaluation.sql new file mode 100644 index 00000000000..bc9b7a1effc --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_evaluation.sql @@ -0,0 +1,37 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +CREATE TABLE llx_hrm_evaluation( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + label varchar(255), + description text, + note_public text, + note_private text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + import_key varchar(14), + status smallint NOT NULL, + date_eval date, + fk_user integer NOT NULL, + fk_job integer NOT NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_hrm_evaluation_extrafields.key.sql b/htdocs/install/mysql/tables/llx_hrm_evaluation_extrafields.key.sql new file mode 100644 index 00000000000..ff9ba9d6cb6 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_evaluation_extrafields.key.sql @@ -0,0 +1,21 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_evaluation_extrafields ADD INDEX idx_evaluation_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_hrm_evaluation_extrafields.sql b/htdocs/install/mysql/tables/llx_hrm_evaluation_extrafields.sql new file mode 100644 index 00000000000..da00cc3c333 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_evaluation_extrafields.sql @@ -0,0 +1,25 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +create table llx_hrm_evaluation_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_hrm_evaluationdet.key.sql b/htdocs/install/mysql/tables/llx_hrm_evaluationdet.key.sql new file mode 100644 index 00000000000..05309ce57e2 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_evaluationdet.key.sql @@ -0,0 +1,29 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_evaluationdet ADD INDEX idx_hrm_evaluationdet_rowid (rowid); +ALTER TABLE llx_hrm_evaluationdet ADD CONSTRAINT llx_hrm_evaluationdet_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_hrm_evaluationdet ADD INDEX idx_hrm_evaluationdet_fk_skill (fk_skill); +ALTER TABLE llx_hrm_evaluationdet ADD INDEX idx_hrm_evaluationdet_fk_evaluation (fk_evaluation); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_hrm_evaluationdet ADD UNIQUE INDEX uk_hrm_evaluationdet_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_hrm_evaluationdet ADD CONSTRAINT llx_hrm_evaluationdet_fk_field FOREIGN KEY (fk_field) REFERENCES llx_hrm_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_hrm_evaluationdet.sql b/htdocs/install/mysql/tables/llx_hrm_evaluationdet.sql new file mode 100644 index 00000000000..4e1b3860ec8 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_evaluationdet.sql @@ -0,0 +1,31 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +CREATE TABLE llx_hrm_evaluationdet +( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + fk_skill integer NOT NULL, + fk_evaluation integer NOT NULL, + rankorder integer NOT NULL, + required_rank integer NOT NULL, + import_key varchar(14) +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_hrm_evaluationdet_extrafields.key.sql b/htdocs/install/mysql/tables/llx_hrm_evaluationdet_extrafields.key.sql new file mode 100644 index 00000000000..5072e2eb67b --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_evaluationdet_extrafields.key.sql @@ -0,0 +1,21 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_evaluationdet_extrafields ADD INDEX idx_evaluationdet_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_hrm_evaluationdet_extrafields.sql b/htdocs/install/mysql/tables/llx_hrm_evaluationdet_extrafields.sql new file mode 100644 index 00000000000..4d4031ba228 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_evaluationdet_extrafields.sql @@ -0,0 +1,24 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +create table llx_hrm_evaluationdet_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_hrm_job.key.sql b/htdocs/install/mysql/tables/llx_hrm_job.key.sql new file mode 100644 index 00000000000..6fe7da6016e --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_job.key.sql @@ -0,0 +1,27 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_job ADD INDEX idx_hrm_job_rowid (rowid); +ALTER TABLE llx_hrm_job ADD INDEX idx_hrm_job_label (label); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_hrm_job ADD UNIQUE INDEX uk_hrm_job_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_hrm_job ADD CONSTRAINT llx_hrm_job_fk_field FOREIGN KEY (fk_field) REFERENCES llx_hrm_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_hrm_job.sql b/htdocs/install/mysql/tables/llx_hrm_job.sql new file mode 100644 index 00000000000..51f472af377 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_job.sql @@ -0,0 +1,32 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +CREATE TABLE llx_hrm_job( + + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + label varchar(255) NOT NULL, + description text, + date_creation datetime NOT NULL, + tms timestamp, + deplacement varchar(255), + note_public text, + note_private text, + fk_user_creat integer, + fk_user_modif integer + +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_hrm_job_extrafields.key.sql b/htdocs/install/mysql/tables/llx_hrm_job_extrafields.key.sql new file mode 100644 index 00000000000..b5226dc4c38 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_job_extrafields.key.sql @@ -0,0 +1,21 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_job_extrafields ADD INDEX idx_job_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_hrm_job_extrafields.sql b/htdocs/install/mysql/tables/llx_hrm_job_extrafields.sql new file mode 100644 index 00000000000..10cccf1c36f --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_job_extrafields.sql @@ -0,0 +1,25 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +create table llx_hrm_job_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_hrm_job_user.key.sql b/htdocs/install/mysql/tables/llx_hrm_job_user.key.sql new file mode 100644 index 00000000000..ead2f7f3b18 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_job_user.key.sql @@ -0,0 +1,27 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_job_user ADD INDEX idx_hrm_job_user_rowid (rowid); +-- ALTER TABLE llx_hrm_job_user ADD INDEX idx_hrm_job_user_ref (ref); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_hrm_job_user ADD UNIQUE INDEX uk_hrm_job_user_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_hrm_job_user ADD CONSTRAINT llx_hrm_job_user_fk_field FOREIGN KEY (fk_field) REFERENCES llx_hrm_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_hrm_job_user.sql b/htdocs/install/mysql/tables/llx_hrm_job_user.sql new file mode 100644 index 00000000000..6124f84e1e6 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_job_user.sql @@ -0,0 +1,36 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +CREATE TABLE llx_hrm_job_user( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + -- ref varchar(128) NOT NULL, + description text, + date_creation datetime NOT NULL, + tms timestamp, + fk_contrat integer, + fk_user integer NOT NULL, + fk_job integer NOT NULL, + date_start datetime, + date_end datetime, + abort_comment varchar(255), + note_public text, + note_private text, + fk_user_creat integer, + fk_user_modif integer + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_hrm_job_user_extrafields.key.sql b/htdocs/install/mysql/tables/llx_hrm_job_user_extrafields.key.sql new file mode 100644 index 00000000000..99ed1f4c1bc --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_job_user_extrafields.key.sql @@ -0,0 +1,21 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_job_user_extrafields ADD INDEX idx_position_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_hrm_job_user_extrafields.sql b/htdocs/install/mysql/tables/llx_hrm_job_user_extrafields.sql new file mode 100644 index 00000000000..7495563f68d --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_job_user_extrafields.sql @@ -0,0 +1,25 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +create table llx_hrm_job_user_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_hrm_skill.key.sql b/htdocs/install/mysql/tables/llx_hrm_skill.key.sql new file mode 100644 index 00000000000..b3196bf8522 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skill.key.sql @@ -0,0 +1,28 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_skill ADD INDEX idx_hrm_skill_rowid (rowid); +ALTER TABLE llx_hrm_skill ADD CONSTRAINT llx_hrm_skill_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_hrm_skill ADD INDEX idx_hrm_skill_skill_type (skill_type); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_hrm_skill ADD UNIQUE INDEX uk_hrm_skill_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_hrm_skill ADD CONSTRAINT llx_hrm_skill_fk_field FOREIGN KEY (fk_field) REFERENCES llx_hrm_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_hrm_skill.sql b/htdocs/install/mysql/tables/llx_hrm_skill.sql new file mode 100644 index 00000000000..96a31be588a --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skill.sql @@ -0,0 +1,35 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +CREATE TABLE llx_hrm_skill( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + label varchar(255), + description text, + date_creation datetime NOT NULL, + tms timestamp, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + required_level integer NOT NULL, + date_validite integer NOT NULL, + temps_theorique double(24,8) NOT NULL, + skill_type integer NOT NULL, + note_public text, + note_private text + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_hrm_skill_extrafields.key.sql b/htdocs/install/mysql/tables/llx_hrm_skill_extrafields.key.sql new file mode 100644 index 00000000000..a4ae591731e --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skill_extrafields.key.sql @@ -0,0 +1,21 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_skill_extrafields ADD INDEX idx_skill_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_hrm_skill_extrafields.sql b/htdocs/install/mysql/tables/llx_hrm_skill_extrafields.sql new file mode 100644 index 00000000000..d47657e34f8 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skill_extrafields.sql @@ -0,0 +1,25 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +create table llx_hrm_skill_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_hrm_skilldet.key.sql b/htdocs/install/mysql/tables/llx_hrm_skilldet.key.sql new file mode 100644 index 00000000000..289276e07b5 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skilldet.key.sql @@ -0,0 +1,27 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_skilldet ADD INDEX idx_hrm_skilldet_rowid (rowid); +ALTER TABLE llx_hrm_skilldet ADD CONSTRAINT llx_hrm_skilldet_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_hrm_skilldet ADD UNIQUE INDEX uk_hrm_skilldet_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_hrm_skilldet ADD CONSTRAINT llx_hrm_skilldet_fk_field FOREIGN KEY (fk_field) REFERENCES llx_hrm_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_hrm_skilldet.sql b/htdocs/install/mysql/tables/llx_hrm_skilldet.sql new file mode 100644 index 00000000000..0257d886813 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skilldet.sql @@ -0,0 +1,26 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +CREATE TABLE llx_hrm_skilldet( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + description text, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + fk_skill integer NOT NULL, + rankorder integer +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_hrm_skilldet_extrafields.key.sql b/htdocs/install/mysql/tables/llx_hrm_skilldet_extrafields.key.sql new file mode 100644 index 00000000000..319eb193a18 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skilldet_extrafields.key.sql @@ -0,0 +1,21 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_skilldet_extrafields ADD INDEX idx_skilldet_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_hrm_skilldet_extrafields.sql b/htdocs/install/mysql/tables/llx_hrm_skilldet_extrafields.sql new file mode 100644 index 00000000000..a6e14f476c0 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skilldet_extrafields.sql @@ -0,0 +1,24 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + +create table llx_hrm_skilldet_extrafields +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + fk_object integer NOT NULL, + import_key varchar(14) -- import key +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_hrm_skillrank.key.sql b/htdocs/install/mysql/tables/llx_hrm_skillrank.key.sql new file mode 100644 index 00000000000..11d89b0187c --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skillrank.key.sql @@ -0,0 +1,27 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_hrm_skillrank ADD INDEX idx_hrm_skillrank_rowid (rowid); +ALTER TABLE llx_hrm_skillrank ADD INDEX idx_hrm_skillrank_fk_skill (fk_skill); +ALTER TABLE llx_hrm_skillrank ADD CONSTRAINT llx_hrm_skillrank_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_hrm_skillrank ADD UNIQUE INDEX uk_hrm_skillrank_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_hrm_skillrank ADD CONSTRAINT llx_hrm_skillrank_fk_field FOREIGN KEY (fk_field) REFERENCES llx_hrm_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_hrm_skillrank.sql b/htdocs/install/mysql/tables/llx_hrm_skillrank.sql new file mode 100644 index 00000000000..4c4109ee7f7 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_hrm_skillrank.sql @@ -0,0 +1,29 @@ +-- Copyright (C) 2021 Gauthier VERDOL +-- Copyright (C) 2021 Greg Rastklan +-- Copyright (C) 2021 Jean-Pascal BOUDET +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see https://www.gnu.org/licenses/. + + +CREATE TABLE llx_hrm_skillrank +( + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + fk_skill integer NOT NULL, + rankorder integer NOT NULL, + fk_object integer NOT NULL, + date_creation datetime NOT NULL, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + fk_user_creat integer NOT NULL, + fk_user_modif integer, + objecttype varchar(128) NOT NULL +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_mrp_mo.sql b/htdocs/install/mysql/tables/llx_mrp_mo.sql index 185ea1583c9..88dc5d42789 100644 --- a/htdocs/install/mysql/tables/llx_mrp_mo.sql +++ b/htdocs/install/mysql/tables/llx_mrp_mo.sql @@ -39,6 +39,7 @@ CREATE TABLE llx_mrp_mo( date_start_planned datetime, date_end_planned datetime, fk_bom integer, - fk_project integer + fk_project integer, + last_main_doc varchar(255) -- END MODULEBUILDER FIELDS -) ENGINE=innodb; \ No newline at end of file +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_partnership.sql b/htdocs/install/mysql/tables/llx_partnership.sql index 6ab312f8875..47ee7f3a48b 100644 --- a/htdocs/install/mysql/tables/llx_partnership.sql +++ b/htdocs/install/mysql/tables/llx_partnership.sql @@ -20,6 +20,7 @@ CREATE TABLE llx_partnership( rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, ref varchar(128) DEFAULT '(PROV)' NOT NULL, status smallint NOT NULL DEFAULT '0', + fk_type integer DEFAULT 0 NOT NULL, fk_soc integer, fk_member integer, date_partnership_start date NOT NULL, diff --git a/htdocs/install/mysql/tables/llx_product.sql b/htdocs/install/mysql/tables/llx_product.sql index e89a7658e5a..80e3f90b828 100644 --- a/htdocs/install/mysql/tables/llx_product.sql +++ b/htdocs/install/mysql/tables/llx_product.sql @@ -47,11 +47,11 @@ create table llx_product price_base_type varchar(3) DEFAULT 'HT', cost_price double(24,8) DEFAULT NULL, -- Cost price without tax. Can be used for margin calculation. default_vat_code varchar(10), -- Same code than into table llx_c_tva (but no constraints). Should be used in priority to find default vat, npr, localtaxes for product. - tva_tx double(6,3), -- Default VAT rate of product + tva_tx double(7,4), -- Default VAT rate of product recuperableonly integer NOT NULL DEFAULT '0', -- French NPR VAT - localtax1_tx double(6,3) DEFAULT 0, + localtax1_tx double(7,4) DEFAULT 0, localtax1_type varchar(10) NOT NULL DEFAULT '0', - localtax2_tx double(6,3) DEFAULT 0, + localtax2_tx double(7,4) DEFAULT 0, localtax2_type varchar(10) NOT NULL DEFAULT '0', fk_user_author integer DEFAULT NULL, -- user making creation fk_user_modif integer, -- user making last change @@ -103,6 +103,8 @@ create table llx_product desiredstock float DEFAULT 0, fk_unit integer DEFAULT NULL, price_autogen tinyint DEFAULT 0, - fk_default_bom integer DEFAULT NULL, - fk_project integer DEFAULT NULL -- Used when the product was generated by a project or is specific to a project + fk_project integer DEFAULT NULL, -- Used when product was generated by a project or is specifif to a project + mandatory_period tinyint DEFAULT 0, -- is used to signal to the user that the start and end dates are mandatory for this type of product the fk_product_type == 1 (service) (non-blocking action) + + fk_default_bom integer DEFAULT NULL )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_association.sql b/htdocs/install/mysql/tables/llx_product_association.sql index 91cc14882f1..f97e2aa6a0b 100644 --- a/htdocs/install/mysql/tables/llx_product_association.sql +++ b/htdocs/install/mysql/tables/llx_product_association.sql @@ -23,6 +23,7 @@ create table llx_product_association fk_product_pere integer NOT NULL DEFAULT 0, -- id du produit maitre fk_product_fils integer NOT NULL DEFAULT 0, -- id du sous-produit qty double NULL, - incdec integer DEFAULT 1 -- when set to 1 changing stock of product will change stock of linked product too + incdec integer DEFAULT 1, -- when set to 1 changing stock of product will change stock of linked product too + rang integer DEFAULT 0 )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_product_customer_price.sql b/htdocs/install/mysql/tables/llx_product_customer_price.sql index 361a42a5b54..7f843a8784e 100644 --- a/htdocs/install/mysql/tables/llx_product_customer_price.sql +++ b/htdocs/install/mysql/tables/llx_product_customer_price.sql @@ -35,11 +35,11 @@ create table llx_product_customer_price price_min_ttc double(24,8) DEFAULT 0, price_base_type varchar(3) DEFAULT 'HT', default_vat_code varchar(10), -- Same code than into table llx_c_tva (but no constraints). Should be used in priority to find default vat, npr, localtaxes for product. - tva_tx double(6,3), + tva_tx double(7,4), recuperableonly integer NOT NULL DEFAULT '0', -- Other NPR VAT - localtax1_tx double(6,3) DEFAULT 0, -- Other local VAT 1 + localtax1_tx double(7,4) DEFAULT 0, -- Other local VAT 1 localtax1_type varchar(10) NOT NULL DEFAULT '0', - localtax2_tx double(6,3) DEFAULT 0, -- Other local VAT 2 + localtax2_tx double(7,4) DEFAULT 0, -- Other local VAT 2 localtax2_type varchar(10) NOT NULL DEFAULT '0', fk_user integer, import_key varchar(14) -- Import key diff --git a/htdocs/install/mysql/tables/llx_product_customer_price_log.sql b/htdocs/install/mysql/tables/llx_product_customer_price_log.sql index 29906fe7ff2..cd591b41099 100644 --- a/htdocs/install/mysql/tables/llx_product_customer_price_log.sql +++ b/htdocs/install/mysql/tables/llx_product_customer_price_log.sql @@ -34,11 +34,11 @@ create table llx_product_customer_price_log price_min_ttc double(24,8) DEFAULT 0, price_base_type varchar(3) DEFAULT 'HT', default_vat_code varchar(10), -- Same code than into table llx_c_tva (but no constraints). Should be used in priority to find default vat, npr, localtaxes for product. - tva_tx double(6,3), + tva_tx double(7,4), recuperableonly integer NOT NULL DEFAULT '0', -- Other NPR VAT - localtax1_tx double(6,3) DEFAULT 0, -- Other local VAT 1 + localtax1_tx double(7,4) DEFAULT 0, -- Other local VAT 1 localtax1_type varchar(10) NOT NULL DEFAULT '0', - localtax2_tx double(6,3) DEFAULT 0, -- Other local VAT 2 + localtax2_tx double(7,4) DEFAULT 0, -- Other local VAT 2 localtax2_type varchar(10) NOT NULL DEFAULT '0', fk_user integer, import_key varchar(14) -- Import key diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index 2a01df30e4b..51b691e8ae2 100644 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -39,10 +39,10 @@ create table llx_product_fournisseur_price default_vat_code varchar(10), barcode varchar(180) DEFAULT NULL, -- barcode fk_barcode_type integer DEFAULT NULL, -- barcode type - tva_tx double(6,3) NOT NULL, - localtax1_tx double(6,3) DEFAULT 0, + tva_tx double(7,4) NOT NULL, + localtax1_tx double(7,4) DEFAULT 0, localtax1_type varchar(10) NOT NULL DEFAULT '0', - localtax2_tx double(6,3) DEFAULT 0, + localtax2_tx double(7,4) DEFAULT 0, localtax2_type varchar(10) NOT NULL DEFAULT '0', info_bits integer NOT NULL DEFAULT 0, fk_user integer, diff --git a/htdocs/install/mysql/tables/llx_product_lot.sql b/htdocs/install/mysql/tables/llx_product_lot.sql index f8d02f19ccb..162f1c6c122 100644 --- a/htdocs/install/mysql/tables/llx_product_lot.sql +++ b/htdocs/install/mysql/tables/llx_product_lot.sql @@ -25,8 +25,10 @@ CREATE TABLE llx_product_lot ( eatby date DEFAULT NULL, -- Eatby date sellby date DEFAULT NULL, -- Sellby date eol_date datetime NULL, - manufacturing_date datetime NULL, - scrapping_date datetime NULL, + manufacturing_date datetime NULL, -- date when first manufacturing of this lot has started + scrapping_date datetime NULL, -- date when we decided to scrap all products of this lot + barcode varchar(180) DEFAULT NULL, -- barcode + fk_barcode_type integer DEFAULT NULL, -- barcode type datec datetime, tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, fk_user_creat integer, diff --git a/htdocs/install/mysql/tables/llx_product_price.sql b/htdocs/install/mysql/tables/llx_product_price.sql index ff862e427e0..9ebbeed9f96 100644 --- a/htdocs/install/mysql/tables/llx_product_price.sql +++ b/htdocs/install/mysql/tables/llx_product_price.sql @@ -35,11 +35,11 @@ create table llx_product_price price_min_ttc double(24,8) default NULL, price_base_type varchar(3) DEFAULT 'HT', default_vat_code varchar(10), -- Same code than into table llx_c_tva (but no constraints). Should be used in priority to find default vat, npr, localtaxes for product. - tva_tx double(6,3) DEFAULT 0 NOT NULL, -- Used only when option PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL is on (not supported) + tva_tx double(7,4) DEFAULT 0 NOT NULL, -- Used only when option PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL is on (not supported) recuperableonly integer NOT NULL DEFAULT '0', - localtax1_tx double(6,3) DEFAULT 0, + localtax1_tx double(7,4) DEFAULT 0, localtax1_type varchar(10) NOT NULL DEFAULT '0', - localtax2_tx double(6,3) DEFAULT 0, + localtax2_tx double(7,4) DEFAULT 0, localtax2_type varchar(10) NOT NULL DEFAULT '0', fk_user_author integer, tosell tinyint DEFAULT 1, diff --git a/htdocs/install/mysql/tables/llx_projet.sql b/htdocs/install/mysql/tables/llx_projet.sql index 97acc8d3411..197a92ac2be 100644 --- a/htdocs/install/mysql/tables/llx_projet.sql +++ b/htdocs/install/mysql/tables/llx_projet.sql @@ -47,9 +47,10 @@ create table llx_projet usage_opportunity integer DEFAULT 0, -- Set to 1 if project is used to follow an opportunity usage_task integer DEFAULT 1, -- Set to 1 if project is used to manage tasks and/or record timesheet usage_bill_time integer DEFAULT 0, -- Set to 1 if time spent must be converted into invoices - usage_organize_event integer DEFAULT 0, -- Set to 1 if you want to use project to organize an event, receive attendees subscription + usage_organize_event integer DEFAULT 0, -- Set to 1 if you want to use project to organize an event or receive attendees registration accept_conference_suggestions integer DEFAULT 0, -- Set to 1 if you want to allow unknown people to suggest conferences accept_booth_suggestions integer DEFAULT 0, -- Set to 1 if you want to Allow unknown people to suggest booth + max_attendees integer DEFAULT 0, price_registration double(24,8), price_booth double(24,8), model_pdf varchar(255), diff --git a/htdocs/install/mysql/tables/llx_projet_task.sql b/htdocs/install/mysql/tables/llx_projet_task.sql index 01edb857738..721dbf8355f 100644 --- a/htdocs/install/mysql/tables/llx_projet_task.sql +++ b/htdocs/install/mysql/tables/llx_projet_task.sql @@ -35,6 +35,7 @@ create table llx_projet_task planned_workload real DEFAULT 0, progress integer DEFAULT 0, -- percentage increase priority integer DEFAULT 0, -- priority + budget_amount double(24,8), fk_user_creat integer, -- user who created the task fk_user_modif integer, -- user who modify the task fk_user_valid integer, -- user who validated the task diff --git a/htdocs/install/mysql/tables/llx_propaldet.sql b/htdocs/install/mysql/tables/llx_propaldet.sql index 7156d90af2f..4dc9d570838 100644 --- a/htdocs/install/mysql/tables/llx_propaldet.sql +++ b/htdocs/install/mysql/tables/llx_propaldet.sql @@ -29,10 +29,10 @@ create table llx_propaldet description text, fk_remise_except integer NULL, -- Lien vers table des remises fixes vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3) DEFAULT 0, -- Vat rate - localtax1_tx double(6,3) DEFAULT 0, -- localtax1 rate + tva_tx double(7,4) DEFAULT 0, -- Vat rate + localtax1_tx double(7,4) DEFAULT 0, -- localtax1 rate localtax1_type varchar(10) NULL, -- localtax1 type - localtax2_tx double(6,3) DEFAULT 0, -- localtax2 rate + localtax2_tx double(7,4) DEFAULT 0, -- localtax2 rate localtax2_type varchar(10) NULL, -- localtax2 type qty real, -- quantity remise_percent real DEFAULT 0, -- pourcentage de remise diff --git a/htdocs/install/mysql/tables/llx_payment_salary_extrafields.key.sql b/htdocs/install/mysql/tables/llx_salary_extrafields.key.sql similarity index 89% rename from htdocs/install/mysql/tables/llx_payment_salary_extrafields.key.sql rename to htdocs/install/mysql/tables/llx_salary_extrafields.key.sql index 9231351a749..9c6e047d9ee 100644 --- a/htdocs/install/mysql/tables/llx_payment_salary_extrafields.key.sql +++ b/htdocs/install/mysql/tables/llx_salary_extrafields.key.sql @@ -17,4 +17,4 @@ -- =================================================================== -ALTER TABLE llx_payment_salary_extrafields ADD INDEX idx_payment_salary_extrafields (fk_object); +ALTER TABLE llx_salary_extrafields ADD INDEX idx_salary_extrafields (fk_object); diff --git a/htdocs/install/mysql/tables/llx_payment_salary_extrafields.sql b/htdocs/install/mysql/tables/llx_salary_extrafields.sql similarity index 91% rename from htdocs/install/mysql/tables/llx_payment_salary_extrafields.sql rename to htdocs/install/mysql/tables/llx_salary_extrafields.sql index 5f15918ef18..bedab6757b4 100644 --- a/htdocs/install/mysql/tables/llx_payment_salary_extrafields.sql +++ b/htdocs/install/mysql/tables/llx_salary_extrafields.sql @@ -16,10 +16,10 @@ -- -- =================================================================== -create table llx_payment_salary_extrafields +create table llx_salary_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - fk_object integer NOT NULL, -- salary payment id + fk_object integer NOT NULL, -- salary id import_key varchar(14) -- import key )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index c40a42ee0bd..c30c934b792 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -37,9 +37,9 @@ create table llx_societe status tinyint DEFAULT 1, -- cessation d'activité ( 1 -- en activité, 0 -- cessation d'activité) code_client varchar(24), -- code client - code_fournisseur varchar(24), -- code founisseur - code_compta varchar(24), -- code compta client - code_compta_fournisseur varchar(24), -- code compta founisseur + code_fournisseur varchar(24), -- code fournisseur + code_compta varchar(24), -- customer accountancy auxiliary account + code_compta_fournisseur varchar(24), -- supplier accountancy auxiliary account address varchar(255), -- company address zip varchar(25), -- zipcode town varchar(50), -- town @@ -52,15 +52,15 @@ create table llx_societe email varchar(128), -- socialnetworks text DEFAULT NULL, -- json with socialnetworks - skype varchar(255), -- deprecated - twitter varchar(255), -- deprecated - facebook varchar(255), -- deprecated - linkedin varchar(255), -- deprecated - instagram varchar(255), -- deprecated - snapchat varchar(255), -- deprecated - googleplus varchar(255), -- deprecated - youtube varchar(255), -- deprecated - whatsapp varchar(255), -- deprecated + --skype varchar(255), -- deprecated + --twitter varchar(255), -- deprecated + --facebook varchar(255), -- deprecated + --linkedin varchar(255), -- deprecated + --instagram varchar(255), -- deprecated + --snapchat varchar(255), -- deprecated + --googleplus varchar(255), -- deprecated + --youtube varchar(255), -- deprecated + --whatsapp varchar(255), -- deprecated fk_effectif integer DEFAULT 0, -- fk_typent integer DEFAULT NULL, -- type ent @@ -99,9 +99,9 @@ create table llx_societe fk_shipping_method integer, -- preferred shipping method id tva_assuj tinyint DEFAULT 1, -- assujeti ou non a la TVA localtax1_assuj tinyint DEFAULT 0, -- assujeti ou non a local tax 1 - localtax1_value double(6,3), + localtax1_value double(7,4), localtax2_assuj tinyint DEFAULT 0, -- assujeti ou non a local tax 2 - localtax2_value double(6,3), + localtax2_value double(7,4), barcode varchar(180), -- barcode fk_barcode_type integer NULL DEFAULT 0, -- barcode type price_level integer NULL, -- level of price for multiprices diff --git a/htdocs/install/mysql/tables/llx_societe_perentity.sql b/htdocs/install/mysql/tables/llx_societe_perentity.sql index 408169476d9..800d4a10679 100644 --- a/htdocs/install/mysql/tables/llx_societe_perentity.sql +++ b/htdocs/install/mysql/tables/llx_societe_perentity.sql @@ -21,8 +21,8 @@ create table llx_societe_perentity rowid integer AUTO_INCREMENT PRIMARY KEY, fk_soc integer, entity integer DEFAULT 1 NOT NULL, -- multi company id --- code_compta varchar(24), -- code compta client --- code_compta_fournisseur varchar(24), -- code compta founisseur + accountancy_code_customer varchar(24), -- customer accountancy auxiliary account + accountancy_code_supplier varchar(24), -- supplier accountancy auxiliary account accountancy_code_sell varchar(32), -- Selling accountancy code accountancy_code_buy varchar(32) -- Buying accountancy code )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_societe_remise.sql b/htdocs/install/mysql/tables/llx_societe_remise.sql index 2d4e3a9c258..37746051b0b 100644 --- a/htdocs/install/mysql/tables/llx_societe_remise.sql +++ b/htdocs/install/mysql/tables/llx_societe_remise.sql @@ -27,7 +27,7 @@ create table llx_societe_remise tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, datec datetime, -- creation date fk_user_author integer, -- creation user - remise_client double(6,3) DEFAULT 0 NOT NULL, -- discount + remise_client double(7,4) DEFAULT 0 NOT NULL, -- discount note text )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_societe_remise_except.sql b/htdocs/install/mysql/tables/llx_societe_remise_except.sql index 63762f8ad32..8fed65fe5f0 100644 --- a/htdocs/install/mysql/tables/llx_societe_remise_except.sql +++ b/htdocs/install/mysql/tables/llx_societe_remise_except.sql @@ -29,7 +29,7 @@ create table llx_societe_remise_except amount_ht double(24,8) NOT NULL, amount_tva double(24,8) DEFAULT 0 NOT NULL, amount_ttc double(24,8) DEFAULT 0 NOT NULL, - tva_tx double(6,3) DEFAULT 0 NOT NULL, + tva_tx double(7,4) DEFAULT 0 NOT NULL, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. fk_user integer NOT NULL, fk_facture_line integer, diff --git a/htdocs/install/mysql/tables/llx_societe_remise_supplier.sql b/htdocs/install/mysql/tables/llx_societe_remise_supplier.sql index d6dfdc20d9d..85ba8e9b7ff 100644 --- a/htdocs/install/mysql/tables/llx_societe_remise_supplier.sql +++ b/htdocs/install/mysql/tables/llx_societe_remise_supplier.sql @@ -27,7 +27,7 @@ create table llx_societe_remise_supplier tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, datec datetime, -- creation date fk_user_author integer, -- creation user - remise_supplier double(6,3) DEFAULT 0 NOT NULL, -- discount + remise_supplier double(7,4) DEFAULT 0 NOT NULL, -- discount note text )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_socpeople.sql b/htdocs/install/mysql/tables/llx_socpeople.sql index 1f28534d5d3..59bd22ddfdc 100644 --- a/htdocs/install/mysql/tables/llx_socpeople.sql +++ b/htdocs/install/mysql/tables/llx_socpeople.sql @@ -44,16 +44,16 @@ create table llx_socpeople email varchar(255), socialnetworks text DEFAULT NULL, -- json with socialnetworks - jabberid varchar(255), - skype varchar(255), - twitter varchar(255), -- - facebook varchar(255), -- - linkedin varchar(255), -- - instagram varchar(255), -- - snapchat varchar(255), -- - googleplus varchar(255), -- - youtube varchar(255), -- - whatsapp varchar(255), -- + --jabberid varchar(255), + --skype varchar(255), + --twitter varchar(255), -- + --facebook varchar(255), -- + --linkedin varchar(255), -- + --instagram varchar(255), -- + --snapchat varchar(255), -- + --googleplus varchar(255), -- + --youtube varchar(255), -- + --whatsapp varchar(255), -- photo varchar(255), no_email smallint NOT NULL DEFAULT 0, -- deprecated. Use table llx_mailing_unsubscribe instead diff --git a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql index 6990bf334e5..4e3d8bd13f9 100644 --- a/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql +++ b/htdocs/install/mysql/tables/llx_supplier_proposaldet.sql @@ -24,10 +24,10 @@ CREATE TABLE llx_supplier_proposaldet ( description text, fk_remise_except integer DEFAULT NULL, vat_src_code varchar(10) DEFAULT '', -- Vat code used as source of vat fields. Not strict foreign key here. - tva_tx double(6,3) DEFAULT 0, -- Vat rate - localtax1_tx double(6,3) DEFAULT 0, + tva_tx double(7,4) DEFAULT 0, -- Vat rate + localtax1_tx double(7,4) DEFAULT 0, localtax1_type varchar(10) DEFAULT NULL, - localtax2_tx double(6,3) DEFAULT 0, + localtax2_tx double(7,4) DEFAULT 0, localtax2_type varchar(10) DEFAULT NULL, qty double DEFAULT NULL, remise_percent double DEFAULT '0', diff --git a/htdocs/install/mysql/tables/llx_ticket.sql b/htdocs/install/mysql/tables/llx_ticket.sql index c053e787dfa..d891a65d502 100644 --- a/htdocs/install/mysql/tables/llx_ticket.sql +++ b/htdocs/install/mysql/tables/llx_ticket.sql @@ -29,7 +29,7 @@ CREATE TABLE llx_ticket message text, fk_statut integer, resolution integer, - progress varchar(100), + progress integer DEFAULT 0, -- progression 0 - 100 or null timing varchar(20), type_code varchar(32), category_code varchar(32), diff --git a/htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql b/htdocs/install/mysql/tables/llx_workstation_workstation_usergroup.sql similarity index 100% rename from htdocs/install/mysql/tables/llx_workstation_workstation_user_group.sql rename to htdocs/install/mysql/tables/llx_workstation_workstation_usergroup.sql diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 8160f6e89b8..16ed758b1f8 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -565,7 +565,7 @@ if ($ok && GETPOST('restore_user_pictures', 'alpha')) { $filetotestsmall = $dolibarr_main_data_root.'/users/'.substr(sprintf('%08d', $obj->rowid), -1, 1).'/'.substr(sprintf('%08d', $obj->rowid), -2, 1).'/thumbs/'.$name.'_small'.$ext; $filetotestmini = $dolibarr_main_data_root.'/users/'.substr(sprintf('%08d', $obj->rowid), -1, 1).'/'.substr(sprintf('%08d', $obj->rowid), -2, 1).'/thumbs/'.$name.'_mini'.$ext; $exists = dol_is_file($filetotest); - print 'Check user '.$obj->rowid.' lastname='.$obj->lastname.' fistname='.$obj->firstname.' photo='.$obj->photo.' file '.$filetotest." exists=".$exists."
    \n"; + print 'Check user '.$obj->rowid.' lastname='.$obj->lastname.' firstname='.$obj->firstname.' photo='.$obj->photo.' file '.$filetotest." exists=".$exists."
    \n"; if ($exists) { $filetarget = $dolibarr_main_data_root.'/users/'.$obj->rowid.'/'.$name.$ext; $filetargetsmall = $dolibarr_main_data_root.'/users/'.$obj->rowid.'/thumbs/'.$name.'_small'.$ext; @@ -1180,7 +1180,7 @@ if ($ok && GETPOST('clean_perm_table', 'alpha')) { foreach ($conf->modules as $key => $val) { $listofmods .= ($listofmods ? ',' : '')."'".$val."'"; } - $sql = 'SELECT id, libelle as label, module from '.MAIN_DB_PREFIX.'rights_def WHERE module NOT IN ('.$db->sanitize($listofmods).') AND id > 100000'; + $sql = "SELECT id, libelle as label, module from ".MAIN_DB_PREFIX."rights_def WHERE module NOT IN (".$db->sanitize($listofmods).") AND id > 100000"; $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); @@ -1191,7 +1191,7 @@ if ($ok && GETPOST('clean_perm_table', 'alpha')) { if ($obj->id > 0) { print '
    \n"; + print '\n"; } } } diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index f2cb92efc7f..9440e166429 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -144,11 +144,6 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ $db = getDoliDBInstance($conf->db->type, $conf->db->host, $conf->db->user, $conf->db->pass, $conf->db->name, $conf->db->port); - // Create the global $hookmanager object - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager = new HookManager($db); - $hookmanager->initHooks(array('upgrade')); - if (!$db->connected) { print ''; dolibarr_install_syslog('upgrade2: failed to connect to database :'.$conf->db->name.' on '.$conf->db->host.' for user '.$conf->db->user, LOG_ERR); @@ -182,6 +177,11 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ $conf->global->MAIN_ENABLE_LOG_TO_HTML = 1; } + // Create the global $hookmanager object + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager = new HookManager($db); + $hookmanager->initHooks(array('upgrade')); + /*************************************************************************************** * @@ -530,7 +530,7 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ // Can call a dedicated external upgrade process if (!$error) { - $parameters = array('versionfrom'=>$versionfrom, 'versionto='.$versionto); + $parameters = array('versionfrom' => $versionfrom, 'versionto' => $versionto); $object = new stdClass(); $action = "upgrade"; $reshook = $hookmanager->executeHooks('doUpgrade2', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks @@ -4360,7 +4360,7 @@ function migrate_reload_modules($db, $langs, $conf, $listofmodule = array(), $fo $mod = new $classname($db); //$mod->remove('noboxes'); - $mod->delete_menus(); // We must delete to be sure it is inserted with new values + $mod->delete_menus(); // We must delete to be sure it is inserted with new values $mod->init($reloadmode); } else { dolibarr_install_syslog('Failed to include '.DOL_DOCUMENT_ROOT.'/core/modules/mod'.$moduletoreloadshort.'.class.php'); @@ -4537,7 +4537,8 @@ and rowid in (...) */ /** - * Migrate users fields facebook and co to socialnetworks + * Migrate users fields facebook and co to socialnetworks. + * Can be called only when version is 10.0.* or lower. Fields does not exists after. * * @return void */ @@ -4628,6 +4629,7 @@ function migrate_users_socialnetworks() /** * Migrate members fields facebook and co to socialnetworks + * Can be called only when version is 10.0.* or lower. Fields does not exists after. * * @return void */ @@ -4719,6 +4721,7 @@ function migrate_members_socialnetworks() /** * Migrate contacts fields facebook and co to socialnetworks + * Can be called only when version is 10.0.* or lower. Fields does not exists after. * * @return void */ @@ -4814,6 +4817,7 @@ function migrate_contacts_socialnetworks() /** * Migrate thirdparties fields facebook and co to socialnetworks + * Can be called only when version is 10.0.* or lower. Fields does not exists after. * * @return void */ diff --git a/htdocs/intracommreport/admin/intracommreport.php b/htdocs/intracommreport/admin/intracommreport.php index c696dddcabd..13231c43af2 100644 --- a/htdocs/intracommreport/admin/intracommreport.php +++ b/htdocs/intracommreport/admin/intracommreport.php @@ -17,7 +17,7 @@ */ /** - * \file htdocs/admin/intracommreport.php + * \file htdocs/intracommreport/admin/intracommreport.php * \ingroup intracommreport * \brief Page to setup the module intracomm report */ diff --git a/htdocs/knowledgemanagement/class/knowledgerecord.class.php b/htdocs/knowledgemanagement/class/knowledgerecord.class.php index 310bdf2959b..a152a693343 100644 --- a/htdocs/knowledgemanagement/class/knowledgerecord.class.php +++ b/htdocs/knowledgemanagement/class/knowledgerecord.class.php @@ -102,9 +102,10 @@ class KnowledgeRecord extends CommonObject 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'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'visible'=>5, 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", "showoncombobox"=>1), - 'question' => array('type'=>'text', 'label'=>'Question', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'csslist'=>'tdoverflowmax300', 'copytoclipboard'=>1), - 'lang' => array('type'=>'varchar(6)', 'label'=>'Language', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1), - 'answer' => array('type'=>'html', 'label'=>'Solution', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>3, 'csslist'=>'tdoverflowmax300', 'copytoclipboard'=>1), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>20, 'index'=>1), + 'question' => array('type'=>'text', 'label'=>'Question', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'csslist'=>'tdoverflowmax300', 'copytoclipboard'=>1, 'tdcss'=>'titlefieldcreate nowraponall'), + 'lang' => array('type'=>'varchar(6)', 'label'=>'Language', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'tdcss'=>'titlefieldcreate nowraponall'), + 'answer' => array('type'=>'html', 'label'=>'Solution', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>3, 'csslist'=>'tdoverflowmax300', 'copytoclipboard'=>1, 'tdcss'=>'titlefieldcreate nowraponall'), '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,), 'last_main_doc' => array('type'=>'varchar(255)', 'label'=>'LastMainDoc', 'enabled'=>'1', 'position'=>600, 'notnull'=>0, 'visible'=>0,), @@ -119,6 +120,7 @@ class KnowledgeRecord extends CommonObject ); public $rowid; public $ref; + public $entity; public $date_creation; public $tms; public $last_main_doc; @@ -456,6 +458,15 @@ class KnowledgeRecord extends CommonObject */ public function delete(User $user, $notrigger = false) { + $error = 0; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".((int) $this->rowid); + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->error .= $this->db->lasterror(); + $errorflag = -1; + } return $this->deleteCommon($user, $notrigger); //return $this->deleteCommon($user, $notrigger, 1); } @@ -816,12 +827,12 @@ class KnowledgeRecord extends CommonObject if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("knowledgemanagement"); - $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated'); - $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); - $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated'); - $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled'); } $statusType = 'status'.$status; @@ -901,7 +912,7 @@ class KnowledgeRecord extends CommonObject $this->lines = array(); $objectline = new KnowledgeRecordLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_knowledgerecord = '.$this->id)); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_knowledgerecord = '.((int) $this->id))); if (is_numeric($result)) { $this->error = $this->error; @@ -1036,6 +1047,22 @@ class KnowledgeRecord extends CommonObject return $error; } + + /** + * Sets object to supplied categories. + * + * Deletes object from existing categories not supplied. + * Adds it to non existing supplied categories. + * Existing categories are left untouch. + * + * @param int[]|int $categories Category or categories IDs + * @return void + */ + public function setCategories($categories) + { + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + return parent::setCategoriesCommon($categories, Categorie::TYPE_KNOWLEDGEMANAGEMENT); + } } diff --git a/htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_advanced.php b/htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_advanced.php index 70cda7254c8..8cdbee53395 100644 --- a/htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_advanced.php +++ b/htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_advanced.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2007 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2008 Raphael Bertrand (Resultic) - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019-2021 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 @@ -21,7 +21,7 @@ */ /** - * \file htdocs/core/modules/knowledgemanagement/mod_knowledgerecord_advanced.php + * \file htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_advanced.php * \ingroup knowledgemanagement * \brief File containing class for advanced numbering model of KnowledgeRecord */ diff --git a/htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_standard.php b/htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_standard.php index 9833fa9bfb7..ba5a3c3b391 100644 --- a/htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_standard.php +++ b/htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_standard.php @@ -18,7 +18,7 @@ */ /** - * \file htdocs/core/modules/knowledgemanagement/mod_knowledgerecord_standard.php + * \file htdocs/knowledgemanagement/core/modules/knowledgemanagement/mod_knowledgerecord_standard.php * \ingroup knowledgemanagement * \brief File of class to manage KnowledgeRecord numbering rules standard */ diff --git a/htdocs/knowledgemanagement/core/modules/knowledgemanagement/modules_knowledgerecord.php b/htdocs/knowledgemanagement/core/modules/knowledgemanagement/modules_knowledgerecord.php index 58def153c4b..edfe6beff62 100644 --- a/htdocs/knowledgemanagement/core/modules/knowledgemanagement/modules_knowledgerecord.php +++ b/htdocs/knowledgemanagement/core/modules/knowledgemanagement/modules_knowledgerecord.php @@ -23,7 +23,7 @@ */ /** - * \file htdocs/core/modules/knowledgemanagement/modules_knowledgerecord.php + * \file htdocs/knowledgemanagement/core/modules/knowledgemanagement/modules_knowledgerecord.php * \ingroup knowledgemanagement * \brief File that contains parent class for knowledgerecords document models and parent class for knowledgerecords numbering models */ diff --git a/htdocs/knowledgemanagement/knowledgemanagementindex.php b/htdocs/knowledgemanagement/knowledgemanagementindex.php index d9b1f07e6e0..ccb3503eb2f 100644 --- a/htdocs/knowledgemanagement/knowledgemanagementindex.php +++ b/htdocs/knowledgemanagement/knowledgemanagementindex.php @@ -145,7 +145,7 @@ if (! empty($conf->knowledgemanagement->enabled) && $user->rights->knowledgemana END MODULEBUILDER DRAFT MYOBJECT */ -print '
    '; +print '
    '; $NBMAX = (empty($conf->global->MAIN_SIZE_SHORTLIST_LIMIT) ? 25 : $conf->global->MAIN_SIZE_SHORTLIST_LIMIT); @@ -202,7 +202,7 @@ if (! empty($conf->knowledgemanagement->enabled) && $user->rights->knowledgemana } */ -print '
    '; +print ''; // End of page llxFooter(); diff --git a/htdocs/knowledgemanagement/knowledgerecord_agenda.php b/htdocs/knowledgemanagement/knowledgerecord_agenda.php index 7853aa7e2ff..2779fca570a 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_agenda.php +++ b/htdocs/knowledgemanagement/knowledgerecord_agenda.php @@ -154,7 +154,7 @@ if ($object->id > 0) { $morehtmlref.='
    '.$langs->trans('Project') . ' '; if ($permissiontoadd) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; } $morehtmlref.=' : '; if ($action == 'classify') { diff --git a/htdocs/knowledgemanagement/knowledgerecord_card.php b/htdocs/knowledgemanagement/knowledgerecord_card.php index 08092696cab..d06028ac4d9 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_card.php +++ b/htdocs/knowledgemanagement/knowledgerecord_card.php @@ -31,6 +31,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/class/knowledgerecord.class.php'; require_once DOL_DOCUMENT_ROOT.'/knowledgemanagement/lib/knowledgemanagement_knowledgerecord.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; // Load translation files required by the page $langs->loadLangs(array("knowledgemanagement", "ticket", "other")); @@ -104,14 +105,14 @@ if ($reshook < 0) { if (empty($reshook)) { $error = 0; - $backurlforlist = dol_buildpath('/knowledgemanagement/knowledgerecord_list.php', 1); + $backurlforlist = DOL_URL_ROOT.'/knowledgemanagement/knowledgerecord_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_buildpath('/knowledgemanagement/knowledgerecord_card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + $backtopage = DOL_URL_ROOT.'/knowledgemanagement/knowledgerecord_card.php?id='.($id > 0 ? $id : '__ID__'); } } } @@ -192,6 +193,16 @@ if ($action == 'create') { // Common attributes include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php'; + if ($conf->categorie->enabled) { + $cate_arbo = $form->select_all_categories(Categorie::TYPE_KNOWLEDGEMANAGEMENT, '', 'parent', 64, 0, 1); + + if (count($cate_arbo)) { + // Categories + print '
    "; + } + } // Other attributes include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php'; @@ -229,6 +240,24 @@ if (($id || $ref) && $action == 'edit') { // Common attributes include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php'; + if ($conf->categorie->enabled) { + $cate_arbo = $form->select_all_categories(Categorie::TYPE_KNOWLEDGEMANAGEMENT, '', 'parent', 64, 0, 1); + + if (count($cate_arbo)) { + // Categories + print '"; + } + } // Other attributes include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php'; @@ -281,7 +310,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
    '; /* @@ -295,7 +324,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $langs->load("projects"); $morehtmlref .= '
    '.$langs->trans('Project') . ' '; if ($permissiontoadd) { - //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; + //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); @@ -335,6 +364,13 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea //unset($object->fields['fk_soc']); // Hide field already shown in banner include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php'; + // Categories + if ($conf->categorie->enabled) { + print '
    "; + } + // Other attributes. Fields from hook formObjectOptions and Extrafields. include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; @@ -368,12 +404,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print dolGetButtonAction($langs->trans('SetToDraft'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes', '', $permissiontoadd); } if (($object->status == $object::STATUS_DRAFT || $object->status == $object::STATUS_VALIDATED) && $permissiontovalidate) { - print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit', '', $permissiontoadd); + print dolGetButtonAction($langs->trans('Modify'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken(), '', $permissiontoadd); } // Validate if ($object->status == $object::STATUS_DRAFT) { if ((empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) && $permissiontovalidate) { - print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_validate&confirm=yes', '', $permissiontoadd); + print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_validate&token='.newToken().'&confirm=yes', '', $permissiontoadd); } else { $langs->load("errors"); //print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_validate&confirm=yes', '', 0); @@ -382,7 +418,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Clone - print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&socid='.$object->socid.'&action=clone&object=scrumsprint', '', $permissiontoadd); + print dolGetButtonAction($langs->trans('ToClone'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=clone&token='.newToken().'&object=scrumsprint', '', $permissiontoadd); /* if ($permissiontoadd) { @@ -402,7 +438,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea */ // 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', '', $permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)); + 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"; } @@ -435,11 +471,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; + print '
    '; $MAXEVENT = 10; - $morehtmlright = ''; + $morehtmlright = ''; $morehtmlright .= $langs->trans("SeeAll"); $morehtmlright .= ''; @@ -448,7 +484,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); - print '
    '; + print ''; } //Select mail models is same action as presend diff --git a/htdocs/knowledgemanagement/knowledgerecord_contact.php b/htdocs/knowledgemanagement/knowledgerecord_contact.php index 1eb80efafa1..c338653b840 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_contact.php +++ b/htdocs/knowledgemanagement/knowledgerecord_contact.php @@ -139,7 +139,7 @@ if ($object->id) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/knowledgemanagement/knowledgerecord_document.php b/htdocs/knowledgemanagement/knowledgerecord_document.php index 4a572ee22bb..90bb9f736cc 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_document.php +++ b/htdocs/knowledgemanagement/knowledgerecord_document.php @@ -80,7 +80,7 @@ if ($id > 0 || !empty($ref)) { //if ($user->socid > 0) $socid = $user->socid; //$result = restrictedArea($user, 'knowledgemanagement', $object->id); -$permissiontoadd = $user->rights->knowledgemanagement->knowledgerecord->write; // Used by the include of actions_addupdatedelete.inc.php +$permissiontoadd = $user->rights->knowledgemanagement->knowledgerecord->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php @@ -137,7 +137,7 @@ if ($object->id) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/knowledgemanagement/knowledgerecord_list.php b/htdocs/knowledgemanagement/knowledgerecord_list.php index 0e8f3a12514..aed45b1db26 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_list.php +++ b/htdocs/knowledgemanagement/knowledgerecord_list.php @@ -1,6 +1,6 @@ - * Copyright (C) ---Put here your own copyright and developer email--- + * Copyright (C) 2021 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 @@ -104,7 +104,7 @@ foreach ($object->fields as $key => $val) { // List of fields to search into when doing a "search in all" $fieldstosearchall = array(); foreach ($object->fields as $key => $val) { - if ($val['searchall']) { + if (!empty($val['searchall'])) { $fieldstosearchall['t.'.$key] = $val['label']; } } @@ -226,7 +226,7 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { // Add fields from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook -$sql .= preg_replace('/^,/', '', $hookmanager->resPrint); +$sql .= 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'])) { @@ -371,13 +371,13 @@ $param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( - //'validate'=>$langs->trans("Validate"), - //'generate_doc'=>$langs->trans("ReGeneratePDF"), - //'builddoc'=>$langs->trans("PDFMerge"), - //'presend'=>$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'] = ''.$langs->trans("Delete"); + $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { $arrayofmassactions = array(); @@ -444,6 +444,7 @@ print '
    '.$langs->trans("SourceFileFormat").'
    '.$langs->trans("SourceFileFormat").''; $text = $objmodelimport->getDriverDescForKey($format); print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text); @@ -1875,6 +1882,7 @@ if ($step == 6 && $datatoimport) { $modulepart = 'import'; $relativepath = GETPOST('filetoimport'); print ''; + print img_mime($file, '', 'pictofixedwidth'); print $filetoimport; print ''; print '
    Found line with id '.$obj->id.', label "'.$obj->label.'" of module "'.$obj->module.'" to delete'; if (GETPOST('clean_perm_table', 'alpha') == 'confirmed') { - $sqldelete = 'DELETE FROM '.MAIN_DB_PREFIX.'rights_def WHERE id = '.$obj->id; + $sqldelete = "DELETE FROM ".MAIN_DB_PREFIX."rights_def WHERE id = ".((int) $obj->id); $resqldelete = $db->query($sqldelete); if (!$resqldelete) { dol_print_error($db); diff --git a/htdocs/install/step2.php b/htdocs/install/step2.php index f95cb218561..30bee881584 100644 --- a/htdocs/install/step2.php +++ b/htdocs/install/step2.php @@ -141,7 +141,7 @@ if ($action == "set") { $requestnb = 0; // To disable some code, so you can call step2 with url like - // http://localhost/dolibarrnew/install/step2.php?action=set&createtables=0&createkeys=0&createfunctions=0&createdata=llx_20_c_departements + // http://localhost/dolibarrnew/install/step2.php?action=set&token='.newToken().'&createtables=0&createkeys=0&createfunctions=0&createdata=llx_20_c_departements $createtables = isset($_GET['createtables']) ?GETPOST('createtables') : 1; $createkeys = isset($_GET['createkeys']) ?GETPOST('createkeys') : 1; $createfunctions = isset($_GET['createfunctions']) ?GETPOST('createfunction') : 1; @@ -570,19 +570,27 @@ dolibarr_install_syslog("Exit ".$ret); dolibarr_install_syslog("- step2: end"); +// Force here a value we need after because master.inc.php is not loaded into step2. +// This code must be similar with the one into main.inc.php +$conf->file->instance_unique_id = (empty($dolibarr_main_instance_unique_id) ? (empty($dolibarr_main_cookie_cryptkey) ? '' : $dolibarr_main_cookie_cryptkey) : $dolibarr_main_instance_unique_id); // Unique id of instance -$out = ' '; +$hash_unique_id = md5('dolibarr'.$conf->file->instance_unique_id); + +$out = 'global->MAIN_FIRST_PING_OK_ID) && $conf->global->MAIN_FIRST_PING_OK_ID == 'disabled') ? '' : ' value="checked" checked="true"').'> '; $out .= ''; $out .= ''; $out .= ''; diff --git a/htdocs/install/upgrade.php b/htdocs/install/upgrade.php index 129ee9d7827..b36914ad36b 100644 --- a/htdocs/install/upgrade.php +++ b/htdocs/install/upgrade.php @@ -283,7 +283,7 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ $db->free($resql); } else { if ($db->lasterrno() != 'DB_ERROR_NOSUCHTABLE') { - print '
    '.dol_escape_htmltag($sql).' : '.dol_escape_htmltag($db->lasterror())."
    '.dol_escape_htmltag($sql).' : '.dol_escape_htmltag($db->lasterror())."
    '.$langs->trans("ErrorFailedToConnectToDatabase", $conf->db->name).''.$langs->trans('Error').'
    '.$langs->trans("Categories").''; + print img_picto('', 'category').$form->multiselectarray('categories', $cate_arbo, GETPOST('categories', 'array'), '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); + print "
    '.$langs->trans("Categories").''; + $c = new Categorie($db); + $cats = $c->containing($object->id, Categorie::TYPE_KNOWLEDGEMANAGEMENT); + $arrayselected = array(); + if (is_array($cats)) { + foreach ($cats as $cat) { + $arrayselected[] = $cat->id; + } + } + print $form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); + print "
    '.$langs->trans("Categories").''; + print $form->showCategories($object->id, Categorie::TYPE_KNOWLEDGEMANAGEMENT, 1); + print "
    '; foreach ($object->fields as $key => $val) { + $searchkey = empty($search[$key]) ? '' : $search[$key]; $cssforfield = (empty($val['css']) ? '' : $val['css']); if ($key == 'status') { $cssforfield .= ($cssforfield ? ' ' : '').'center'; @@ -458,9 +459,9 @@ foreach ($object->fields as $key => $val) { print ''; } @@ -522,7 +523,7 @@ 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 (!empty($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 @@ -612,7 +613,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { if (!$i) { $totalarray['nbfield']++; } - if (!empty($val['isameasure'])) { + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; } diff --git a/htdocs/knowledgemanagement/knowledgerecord_note.php b/htdocs/knowledgemanagement/knowledgerecord_note.php index 87d9eed9bdb..2e58480adec 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_note.php +++ b/htdocs/knowledgemanagement/knowledgerecord_note.php @@ -111,7 +111,7 @@ if ($id > 0 || !empty($ref)) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/knowledgemanagement/lib/knowledgemanagement_knowledgerecord.lib.php b/htdocs/knowledgemanagement/lib/knowledgemanagement_knowledgerecord.lib.php index e70b4654d19..e77439970ba 100644 --- a/htdocs/knowledgemanagement/lib/knowledgemanagement_knowledgerecord.lib.php +++ b/htdocs/knowledgemanagement/lib/knowledgemanagement_knowledgerecord.lib.php @@ -1,5 +1,5 @@ * * 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 @@ -16,7 +16,7 @@ */ /** - * \file htdocs/knowledgemanagementlib/knowledgemanagement_knowledgerecord.lib.php + * \file htdocs/knowledgemanagement/lib/knowledgemanagement_knowledgerecord.lib.php * \ingroup knowledgemanagement * \brief Library files with common functions for KnowledgeRecord */ diff --git a/htdocs/langs/am_ET/mrp.lang b/htdocs/langs/am_ET/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/am_ET/mrp.lang +++ b/htdocs/langs/am_ET/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/ar_IQ/accountancy.lang b/htdocs/langs/ar_IQ/accountancy.lang index 771f0a83e7b..3bb3fbfab17 100644 --- a/htdocs/langs/ar_IQ/accountancy.lang +++ b/htdocs/langs/ar_IQ/accountancy.lang @@ -1,434 +1,3 @@ -# Dolibarr language file - en_US - Accountancy (Double entries) -Accountancy=Accountancy -Accounting=Accounting -ACCOUNTING_EXPORT_SEPARATORCSV=Column separator for export file -ACCOUNTING_EXPORT_DATE=Date format for export file -ACCOUNTING_EXPORT_PIECE=Export the number of piece -ACCOUNTING_EXPORT_GLOBAL_ACCOUNT=Export with global account -ACCOUNTING_EXPORT_LABEL=Export label -ACCOUNTING_EXPORT_AMOUNT=Export amount -ACCOUNTING_EXPORT_DEVISE=Export currency -Selectformat=Select the format for the file -ACCOUNTING_EXPORT_FORMAT=Select the format for the file -ACCOUNTING_EXPORT_ENDLINE=Select the carriage return type -ACCOUNTING_EXPORT_PREFIX_SPEC=Specify the prefix for the file name -ThisService=This service -ThisProduct=This product -DefaultForService=Default for service -DefaultForProduct=Default for product -ProductForThisThirdparty=Product for this thirdparty -ServiceForThisThirdparty=Service for this thirdparty -CantSuggest=Can't suggest -AccountancySetupDoneFromAccountancyMenu=Most setup of the accountancy is done from the menu %s -ConfigAccountingExpert=Configuration of the module accounting (double entry) -Journalization=Journalization -Journals=Journals -JournalFinancial=Financial journals -BackToChartofaccounts=Return chart of accounts -Chartofaccounts=Chart of accounts -ChartOfSubaccounts=Chart of individual accounts -ChartOfIndividualAccountsOfSubsidiaryLedger=Chart of individual accounts of the subsidiary ledger -CurrentDedicatedAccountingAccount=Current dedicated account -AssignDedicatedAccountingAccount=New account to assign -InvoiceLabel=Invoice label -OverviewOfAmountOfLinesNotBound=Overview of amount of lines not bound to an accounting account -OverviewOfAmountOfLinesBound=Overview of amount of lines already bound to an accounting account -OtherInfo=Other information -DeleteCptCategory=Remove accounting account from group -ConfirmDeleteCptCategory=Are you sure you want to remove this accounting account from the accounting account group? -JournalizationInLedgerStatus=Status of journalization +# Dolibarr language file - Source file is en_US - accountancy AlreadyInGeneralLedger=Already transferred in accounting journals and ledger NotYetInGeneralLedger=Not yet transferred in accouting journals and ledger -GroupIsEmptyCheckSetup=Group is empty, check setup of the personalized accounting group -DetailByAccount=Show detail by account -AccountWithNonZeroValues=Accounts with non-zero values -ListOfAccounts=List of accounts -CountriesInEEC=Countries in EEC -CountriesNotInEEC=Countries not in EEC -CountriesInEECExceptMe=Countries in EEC except %s -CountriesExceptMe=All countries except %s -AccountantFiles=Export source documents -ExportAccountingSourceDocHelp=With this tool, you can export the source events (list in CSV and PDFs) that were used to generate your accountancy. -ExportAccountingSourceDocHelp2=To export your journals, use the menu entry %s - %s. -VueByAccountAccounting=View by accounting account -VueBySubAccountAccounting=View by accounting subaccount - -MainAccountForCustomersNotDefined=Main accounting account for customers not defined in setup -MainAccountForSuppliersNotDefined=Main accounting account for vendors not defined in setup -MainAccountForUsersNotDefined=Main accounting account for users not defined in setup -MainAccountForVatPaymentNotDefined=Main accounting account for VAT payment not defined in setup -MainAccountForSubscriptionPaymentNotDefined=Main accounting account for subscription payment not defined in setup - -AccountancyArea=Accounting area -AccountancyAreaDescIntro=Usage of the accountancy module is done in several step: -AccountancyAreaDescActionOnce=The following actions are usually executed one time only, or once per year... -AccountancyAreaDescActionOnceBis=Next steps should be done to save you time in future by suggesting you the correct default accounting account when making the journalization (writing record in Journals and General ledger) -AccountancyAreaDescActionFreq=The following actions are usually executed every month, week or day for very large companies... - -AccountancyAreaDescJournalSetup=STEP %s: Create or check content of your journal list from menu %s -AccountancyAreaDescChartModel=STEP %s: Check that a model of chart of account exists or create one from menu %s -AccountancyAreaDescChart=STEP %s: Select and|or complete your chart of account from menu %s - -AccountancyAreaDescVat=STEP %s: Define accounting accounts for each VAT Rates. For this, use the menu entry %s. -AccountancyAreaDescDefault=STEP %s: Define default accounting accounts. For this, use the menu entry %s. -AccountancyAreaDescExpenseReport=STEP %s: Define default accounting accounts for each type of expense report. For this, use the menu entry %s. -AccountancyAreaDescSal=STEP %s: Define default accounting accounts for payment of salaries. For this, use the menu entry %s. -AccountancyAreaDescContrib=STEP %s: Define default accounting accounts for special expenses (miscellaneous taxes). For this, use the menu entry %s. -AccountancyAreaDescDonation=STEP %s: Define default accounting accounts for donation. For this, use the menu entry %s. -AccountancyAreaDescSubscription=STEP %s: Define default accounting accounts for member subscription. For this, use the menu entry %s. -AccountancyAreaDescMisc=STEP %s: Define mandatory default account and default accounting accounts for miscellaneous transactions. For this, use the menu entry %s. -AccountancyAreaDescLoan=STEP %s: Define default accounting accounts for loans. For this, use the menu entry %s. -AccountancyAreaDescBank=STEP %s: Define accounting accounts and journal code for each bank and financial accounts. For this, use the menu entry %s. -AccountancyAreaDescProd=STEP %s: Define accounting accounts on your products/services. For this, use the menu entry %s. - -AccountancyAreaDescBind=STEP %s: Check the binding between existing %s lines and accounting account is done, so application will be able to journalize transactions in Ledger in one click. Complete missing bindings. For this, use the menu entry %s. -AccountancyAreaDescWriteRecords=STEP %s: Write transactions into the Ledger. For this, go into menu %s, and click into button %s. -AccountancyAreaDescAnalyze=STEP %s: Add or edit existing transactions and generate reports and exports. - -AccountancyAreaDescClosePeriod=STEP %s: Close period so we can't make modification in a future. - -TheJournalCodeIsNotDefinedOnSomeBankAccount=A mandatory step in setup has not been completed (accounting code journal not defined for all bank accounts) -Selectchartofaccounts=Select active chart of accounts -ChangeAndLoad=Change and load -Addanaccount=Add an accounting account -AccountAccounting=Accounting account -AccountAccountingShort=Account -SubledgerAccount=Subledger account -SubledgerAccountLabel=Subledger account label -ShowAccountingAccount=Show accounting account -ShowAccountingJournal=Show accounting journal -ShowAccountingAccountInLedger=Show accounting account in ledger -ShowAccountingAccountInJournals=Show accounting account in journals -AccountAccountingSuggest=Accounting account suggested -MenuDefaultAccounts=Default accounts -MenuBankAccounts=Bank accounts -MenuVatAccounts=Vat accounts -MenuTaxAccounts=Tax accounts -MenuExpenseReportAccounts=Expense report accounts -MenuLoanAccounts=Loan accounts -MenuProductsAccounts=Product accounts -MenuClosureAccounts=Closure accounts -MenuAccountancyClosure=Closure -MenuAccountancyValidationMovements=Validate movements -ProductsBinding=Products accounts -TransferInAccounting=Transfer in accounting -RegistrationInAccounting=Registration in accounting -Binding=Binding to accounts -CustomersVentilation=Customer invoice binding -SuppliersVentilation=Vendor invoice binding -ExpenseReportsVentilation=Expense report binding -CreateMvts=Create new transaction -UpdateMvts=Modification of a transaction -ValidTransaction=Validate transaction -WriteBookKeeping=Register transactions in accounting -Bookkeeping=Ledger -BookkeepingSubAccount=Subledger -AccountBalance=Account balance -ObjectsRef=Source object ref -CAHTF=Total purchase vendor before tax -TotalExpenseReport=Total expense report -InvoiceLines=Lines of invoices to bind -InvoiceLinesDone=Bound lines of invoices -ExpenseReportLines=Lines of expense reports to bind -ExpenseReportLinesDone=Bound lines of expense reports -IntoAccount=Bind line with the accounting account -TotalForAccount=Total accounting account - - -Ventilate=Bind -LineId=Id line -Processing=Processing -EndProcessing=Process terminated. -SelectedLines=Selected lines -Lineofinvoice=Line of invoice -LineOfExpenseReport=Line of expense report -NoAccountSelected=No accounting account selected -VentilatedinAccount=Binded successfully to the accounting account -NotVentilatedinAccount=Not bound to the accounting account -XLineSuccessfullyBinded=%s products/services successfully bound to an accounting account -XLineFailedToBeBinded=%s products/services were not bound to any accounting account - -ACCOUNTING_LIMIT_LIST_VENTILATION=Maximum number of lines on list and bind page (recommended: 50) -ACCOUNTING_LIST_SORT_VENTILATION_TODO=Begin the sorting of the page "Binding to do" by the most recent elements -ACCOUNTING_LIST_SORT_VENTILATION_DONE=Begin the sorting of the page "Binding done" by the most recent elements - -ACCOUNTING_LENGTH_DESCRIPTION=Truncate product & services description in listings after x chars (Best = 50) -ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT=Truncate product & services account description form in listings after x chars (Best = 50) -ACCOUNTING_LENGTH_GACCOUNT=Length of the general accounting accounts (If you set value to 6 here, the account '706' will appear like '706000' on screen) -ACCOUNTING_LENGTH_AACCOUNT=Length of the third-party accounting accounts (If you set value to 6 here, the account '401' will appear like '401000' on screen) -ACCOUNTING_MANAGE_ZERO=Allow to manage different number of zeros at the end of an accounting account. Needed by some countries (like Switzerland). If set to off (default), you can set the following two parameters to ask the application to add virtual zeros. -BANK_DISABLE_DIRECT_INPUT=Disable direct recording of transaction in bank account -ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL=Enable draft export on journal -ACCOUNTANCY_COMBO_FOR_AUX=Enable combo list for subsidiary account (may be slow if you have a lot of third parties, break ability to search on a part of value) -ACCOUNTING_DATE_START_BINDING=Define a date to start binding & transfer in accountancy. Below this date, the transactions will not be transferred to accounting. -ACCOUNTING_DEFAULT_PERIOD_ON_TRANSFER=On accountancy transfer, select period show by default - -ACCOUNTING_SELL_JOURNAL=Sell journal -ACCOUNTING_PURCHASE_JOURNAL=Purchase journal -ACCOUNTING_MISCELLANEOUS_JOURNAL=Miscellaneous journal -ACCOUNTING_EXPENSEREPORT_JOURNAL=Expense report journal -ACCOUNTING_SOCIAL_JOURNAL=Social journal -ACCOUNTING_HAS_NEW_JOURNAL=Has new Journal - -ACCOUNTING_RESULT_PROFIT=Result accounting account (Profit) -ACCOUNTING_RESULT_LOSS=Result accounting account (Loss) -ACCOUNTING_CLOSURE_DEFAULT_JOURNAL=Journal of closure - -ACCOUNTING_ACCOUNT_TRANSFER_CASH=Accounting account of transitional bank transfer -TransitionalAccount=Transitional bank transfer account - -ACCOUNTING_ACCOUNT_SUSPENSE=Accounting account of wait -DONATION_ACCOUNTINGACCOUNT=Accounting account to register donations -ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT=Accounting account to register subscriptions - -ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT=Accounting account by default to register customer deposit - -ACCOUNTING_PRODUCT_BUY_ACCOUNT=Accounting account by default for the bought products (used if not defined in the product sheet) -ACCOUNTING_PRODUCT_BUY_INTRA_ACCOUNT=Accounting account by default for the bought products in EEC (used if not defined in the product sheet) -ACCOUNTING_PRODUCT_BUY_EXPORT_ACCOUNT=Accounting account by default for the bought products and imported out of EEC (used if not defined in the product sheet) -ACCOUNTING_PRODUCT_SOLD_ACCOUNT=Accounting account by default for the sold products (used if not defined in the product sheet) -ACCOUNTING_PRODUCT_SOLD_INTRA_ACCOUNT=Accounting account by default for the products sold in EEC (used if not defined in the product sheet) -ACCOUNTING_PRODUCT_SOLD_EXPORT_ACCOUNT=Accounting account by default for the products sold and exported out of EEC (used if not defined in the product sheet) - -ACCOUNTING_SERVICE_BUY_ACCOUNT=Accounting account by default for the bought services (used if not defined in the service sheet) -ACCOUNTING_SERVICE_BUY_INTRA_ACCOUNT=Accounting account by default for the bought services in EEC (used if not defined in the service sheet) -ACCOUNTING_SERVICE_BUY_EXPORT_ACCOUNT=Accounting account by default for the bought services and imported out of EEC (used if not defined in the service sheet) -ACCOUNTING_SERVICE_SOLD_ACCOUNT=Accounting account by default for the sold services (used if not defined in the service sheet) -ACCOUNTING_SERVICE_SOLD_INTRA_ACCOUNT=Accounting account by default for the services sold in EEC (used if not defined in the service sheet) -ACCOUNTING_SERVICE_SOLD_EXPORT_ACCOUNT=Accounting account by default for the services sold and exported out of EEC (used if not defined in the service sheet) - -Doctype=Type of document -Docdate=Date -Docref=Reference -LabelAccount=Label account -LabelOperation=Label operation -Sens=Direction -AccountingDirectionHelp=For an accounting account of a customer, use Credit to record a payment you have received
    For an accounting account of a supplier, use Debit to record a payment you made -LetteringCode=Lettering code -Lettering=Lettering -Codejournal=Journal -JournalLabel=Journal label -NumPiece=Piece number -TransactionNumShort=Num. transaction -AccountingCategory=Custom group -GroupByAccountAccounting=Group by general ledger account -GroupBySubAccountAccounting=Group by subledger account -AccountingAccountGroupsDesc=You can define here some groups of accounting account. They will be used for personalized accounting reports. -ByAccounts=By accounts -ByPredefinedAccountGroups=By predefined groups -ByPersonalizedAccountGroups=By personalized groups -ByYear=By year -NotMatch=Not Set -DeleteMvt=Delete some operation lines from accounting -DelMonth=Month to delete -DelYear=Year to delete -DelJournal=Journal to delete -ConfirmDeleteMvt=This will delete all operation lines of the accounting for the year/month and/or for a specific journal (At least one criterion is required). You will have to reuse the feature '%s' to have the deleted record back in the ledger. -ConfirmDeleteMvtPartial=This will delete the transaction from the accounting (all operation lines related to the same transaction will be deleted) -FinanceJournal=Finance journal -ExpenseReportsJournal=Expense reports journal -DescFinanceJournal=Finance journal including all the types of payments by bank account -DescJournalOnlyBindedVisible=This is a view of record that are bound to an accounting account and can be recorded into the Journals and Ledger. -VATAccountNotDefined=Account for VAT not defined -ThirdpartyAccountNotDefined=Account for third party not defined -ProductAccountNotDefined=Account for product not defined -FeeAccountNotDefined=Account for fee not defined -BankAccountNotDefined=Account for bank not defined -CustomerInvoicePayment=Payment of invoice customer -ThirdPartyAccount=Third-party account -NewAccountingMvt=New transaction -NumMvts=Numero of transaction -ListeMvts=List of movements -ErrorDebitCredit=Debit and Credit cannot have a value at the same time -AddCompteFromBK=Add accounting accounts to the group -ReportThirdParty=List third-party account -DescThirdPartyReport=Consult here the list of third-party customers and vendors and their accounting accounts -ListAccounts=List of the accounting accounts -UnknownAccountForThirdparty=Unknown third-party account. We will use %s -UnknownAccountForThirdpartyBlocking=Unknown third-party account. Blocking error -ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Subledger account not defined or third party or user unknown. We will use %s -ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored=Third-party unknown and subledger not defined on the payment. We will keep the subledger account value empty. -ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking=Subledger account not defined or third party or user unknown. Blocking error. -UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking=Unknown third-party account and waiting account not defined. Blocking error -PaymentsNotLinkedToProduct=Payment not linked to any product / service -OpeningBalance=Opening balance -ShowOpeningBalance=Show opening balance -HideOpeningBalance=Hide opening balance -ShowSubtotalByGroup=Show subtotal by level - -Pcgtype=Group of account -PcgtypeDesc=Group of account are used as predefined 'filter' and 'grouping' criteria for some accounting reports. For example, 'INCOME' or 'EXPENSE' are used as groups for accounting accounts of products to build the expense/income report. - -Reconcilable=Reconcilable - -TotalVente=Total turnover before tax -TotalMarge=Total sales margin - -DescVentilCustomer=Consult here the list of customer invoice lines bound (or not) to a product accounting account -DescVentilMore=In most cases, if you use predefined products or services and you set the account number on the product/service card, the application will be able to make all the binding between your invoice lines and the accounting account of your chart of accounts, just in one click with the button "%s". If account was not set on product/service cards or if you still have some lines not bound to an account, you will have to make a manual binding from the menu "%s". -DescVentilDoneCustomer=Consult here the list of the lines of invoices customers and their product accounting account -DescVentilTodoCustomer=Bind invoice lines not already bound with a product accounting account -ChangeAccount=Change the product/service accounting account for selected lines with the following accounting account: -Vide=- -DescVentilSupplier=Consult here the list of vendor invoice lines bound or not yet bound to a product accounting account (only record not already transfered in accountancy are visible) -DescVentilDoneSupplier=Consult here the list of the lines of vendor invoices and their accounting account -DescVentilTodoExpenseReport=Bind expense report lines not already bound with a fee accounting account -DescVentilExpenseReport=Consult here the list of expense report lines bound (or not) to a fee accounting account -DescVentilExpenseReportMore=If you setup accounting account on type of expense report lines, the application will be able to make all the binding between your expense report lines and the accounting account of your chart of accounts, just in one click with the button "%s". If account was not set on fees dictionary or if you still have some lines not bound to any account, you will have to make a manual binding from the menu "%s". -DescVentilDoneExpenseReport=Consult here the list of the lines of expenses reports and their fees accounting account - -Closure=Annual closure -DescClosure=Consult here the number of movements by month who are not validated & fiscal years already open -OverviewOfMovementsNotValidated=Step 1/ Overview of movements not validated. (Necessary to close a fiscal year) -AllMovementsWereRecordedAsValidated=All movements were recorded as validated -NotAllMovementsCouldBeRecordedAsValidated=Not all movements could be recorded as validated -ValidateMovements=Validate movements -DescValidateMovements=Any modification or deletion of writing, lettering and deletes will be prohibited. All entries for an exercise must be validated otherwise closing will not be possible - -ValidateHistory=Bind Automatically -AutomaticBindingDone=Automatic binding done - -ErrorAccountancyCodeIsAlreadyUse=Error, you cannot delete this accounting account because it is used -MvtNotCorrectlyBalanced=Movement not correctly balanced. Debit = %s | Credit = %s -Balancing=Balancing -FicheVentilation=Binding card -GeneralLedgerIsWritten=Transactions are written in the Ledger -GeneralLedgerSomeRecordWasNotRecorded=Some of the transactions could not be journalized. If there is no other error message, this is probably because they were already journalized. -NoNewRecordSaved=No more record to journalize -ListOfProductsWithoutAccountingAccount=List of products not bound to any accounting account -ChangeBinding=Change the binding -Accounted=Accounted in ledger -NotYetAccounted=Not yet accounted in the ledger -ShowTutorial=Show Tutorial -NotReconciled=Not reconciled -WarningRecordWithoutSubledgerAreExcluded=Warning, all operations without subledger account defined are filtered and excluded from this view - -## Admin -BindingOptions=Binding options -ApplyMassCategories=Apply mass categories -AddAccountFromBookKeepingWithNoCategories=Available account not yet in the personalized group -CategoryDeleted=Category for the accounting account has been removed -AccountingJournals=Accounting journals -AccountingJournal=Accounting journal -NewAccountingJournal=New accounting journal -ShowAccountingJournal=Show accounting journal -NatureOfJournal=Nature of Journal -AccountingJournalType1=Miscellaneous operations -AccountingJournalType2=Sales -AccountingJournalType3=Purchases -AccountingJournalType4=Bank -AccountingJournalType5=Expenses report -AccountingJournalType8=Inventory -AccountingJournalType9=Has-new -ErrorAccountingJournalIsAlreadyUse=This journal is already use -AccountingAccountForSalesTaxAreDefinedInto=Note: Accounting account for Sales tax are defined into menu %s - %s -NumberOfAccountancyEntries=Number of entries -NumberOfAccountancyMovements=Number of movements -ACCOUNTING_DISABLE_BINDING_ON_SALES=Disable binding & transfer in accountancy on sales (customer invoices will not be taken into account in accounting) -ACCOUNTING_DISABLE_BINDING_ON_PURCHASES=Disable binding & transfer in accountancy on purchases (vendor invoices will not be taken into account in accounting) -ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS=Disable binding & transfer in accountancy on expense reports (expense reports will not be taken into account in accounting) - -## Export -NotifiedExportDate=Notified export date (modification of the entries will not be possible) -NotifiedValidationDate=Validation of the entries (modification or deletion of the entries will not be possible) -ConfirmExportFile=Confirmation of the generation of the accounting export file ? -ExportDraftJournal=Export draft journal -Modelcsv=Model of export -Selectmodelcsv=Select a model of export -Modelcsv_normal=Classic export -Modelcsv_CEGID=Export for CEGID Expert Comptabilité -Modelcsv_COALA=Export for Sage Coala -Modelcsv_bob50=Export for Sage BOB 50 -Modelcsv_ciel=Export for Sage50, Ciel Compta or Compta Evo. (Format XIMPORT) -Modelcsv_quadratus=Export for Quadratus QuadraCompta -Modelcsv_ebp=Export for EBP -Modelcsv_cogilog=Export for Cogilog -Modelcsv_agiris=Export for Agiris -Modelcsv_LDCompta=Export for LD Compta (v9) (Test) -Modelcsv_LDCompta10=Export for LD Compta (v10 & higher) -Modelcsv_openconcerto=Export for OpenConcerto (Test) -Modelcsv_configurable=Export CSV Configurable -Modelcsv_FEC=Export FEC -Modelcsv_FEC2=Export FEC (With dates generation writing / document reversed) -Modelcsv_Sage50_Swiss=Export for Sage 50 Switzerland -Modelcsv_winfic=Export Winfic - eWinfic - WinSis Compta -Modelcsv_Gestinumv3=Export for Gestinum (v3) -Modelcsv_Gestinumv5Export for Gestinum (v5) -ChartofaccountsId=Chart of accounts Id - -## Tools - Init accounting account on product / service -InitAccountancy=Init accountancy -InitAccountancyDesc=This page can be used to initialize an accounting account on products and services that does not have accounting account defined for sales and purchases. -DefaultBindingDesc=This page can be used to set a default account to use to link transactions record about payment salaries, donation, taxes and vat when no specific accounting account were already set. -DefaultClosureDesc=This page can be used to set parameters used for accounting closures. -Options=Options -OptionModeProductSell=Mode sales -OptionModeProductSellIntra=Mode sales exported in EEC -OptionModeProductSellExport=Mode sales exported in other countries -OptionModeProductBuy=Mode purchases -OptionModeProductBuyIntra=Mode purchases imported in EEC -OptionModeProductBuyExport=Mode purchased imported from other countries -OptionModeProductSellDesc=Show all products with accounting account for sales. -OptionModeProductSellIntraDesc=Show all products with accounting account for sales in EEC. -OptionModeProductSellExportDesc=Show all products with accounting account for other foreign sales. -OptionModeProductBuyDesc=Show all products with accounting account for purchases. -OptionModeProductBuyIntraDesc=Show all products with accounting account for purchases in EEC. -OptionModeProductBuyExportDesc=Show all products with accounting account for other foreign purchases. -CleanFixHistory=Remove accounting code from lines that not exists into charts of account -CleanHistory=Reset all bindings for selected year -PredefinedGroups=Predefined groups -WithoutValidAccount=Without valid dedicated account -WithValidAccount=With valid dedicated account -ValueNotIntoChartOfAccount=This value of accounting account does not exist into chart of account -AccountRemovedFromGroup=Account removed from group -SaleLocal=Local sale -SaleExport=Export sale -SaleEEC=Sale in EEC -SaleEECWithVAT=Sale in EEC with a VAT not null, so we suppose this is NOT an intracommunautary sale and the suggested account is the standard product account. -SaleEECWithoutVATNumber=Sale in EEC with no VAT but the VAT ID of thirdparty is not defined. We fallback on the product account for standard sales. You can fix the VAT ID of thirdparty or the product account if needed. - -## Dictionary -Range=Range of accounting account -Calculated=Calculated -Formula=Formula - -## Error -SomeMandatoryStepsOfSetupWereNotDone=Some mandatory steps of setup was not done, please complete them -ErrorNoAccountingCategoryForThisCountry=No accounting account group available for country %s (See Home - Setup - Dictionaries) -ErrorInvoiceContainsLinesNotYetBounded=You try to journalize some lines of the invoice %s, but some other lines are not yet bounded to accounting account. Journalization of all invoice lines for this invoice are refused. -ErrorInvoiceContainsLinesNotYetBoundedShort=Some lines on invoice are not bound to accounting account. -ExportNotSupported=The export format setuped is not supported into this page -BookeppingLineAlreayExists=Lines already existing into bookkeeping -NoJournalDefined=No journal defined -Binded=Lines bound -ToBind=Lines to bind -UseMenuToSetBindindManualy=Lines not yet bound, use menu %s to make the binding manually - -## Import -ImportAccountingEntries=Accounting entries -ImportAccountingEntriesFECFormat=Accounting entries - FEC format -FECFormatJournalCode=Code journal (JournalCode) -FECFormatJournalLabel=Label journal (JournalLib) -FECFormatEntryNum=Piece number (EcritureNum) -FECFormatEntryDate=Piece date (EcritureDate) -FECFormatGeneralAccountNumber=General account number (CompteNum) -FECFormatGeneralAccountLabel=General account label (CompteLib) -FECFormatSubledgerAccountNumber=Subledger account number (CompAuxNum) -FECFormatSubledgerAccountLabel=Subledger account number (CompAuxLib) -FECFormatPieceRef=Piece ref (PieceRef) -FECFormatPieceDate=Piece date creation (PieceDate) -FECFormatLabelOperation=Label operation (EcritureLib) -FECFormatDebit=Debit (Debit) -FECFormatCredit=Credit (Credit) -FECFormatReconcilableCode=Reconcilable code (EcritureLet) -FECFormatReconcilableDate=Reconcilable date (DateLet) -FECFormatValidateDate=Piece date validated (ValidDate) -FECFormatMulticurrencyAmount=Multicurrency amount (Montantdevise) -FECFormatMulticurrencyCode=Multicurrency code (Idevise) - -DateExport=Date export -WarningReportNotReliable=Warning, this report is not based on the Ledger, so does not contains transaction modified manually in the Ledger. If your journalization is up to date, the bookkeeping view is more accurate. -ExpenseReportJournal=Expense Report Journal -InventoryJournal=Inventory Journal - -NAccounts=%s accounts diff --git a/htdocs/langs/ar_IQ/admin.lang b/htdocs/langs/ar_IQ/admin.lang index f52c28a9da3..052a23ce875 100644 --- a/htdocs/langs/ar_IQ/admin.lang +++ b/htdocs/langs/ar_IQ/admin.lang @@ -1,2161 +1,10 @@ # Dolibarr language file - Source file is en_US - admin -Foundation=Foundation -Version=Version -Publisher=Publisher -VersionProgram=Version program -VersionLastInstall=Initial install version -VersionLastUpgrade=Latest version upgrade -VersionExperimental=Experimental -VersionDevelopment=Development -VersionUnknown=Unknown -VersionRecommanded=Recommended -FileCheck=Fileset Integrity Checks -FileCheckDesc=This tool allows you to check the integrity of files and the setup of your application, comparing each file with the official one. The value of some setup constants may also be checked. You can use this tool to determine if any files have been modified (e.g by a hacker). -FileIntegrityIsStrictlyConformedWithReference=Files integrity is strictly conformed with the reference. -FileIntegrityIsOkButFilesWereAdded=Files integrity check has passed, however some new files have been added. -FileIntegritySomeFilesWereRemovedOrModified=Files integrity check has failed. Some files were modified, removed or added. -GlobalChecksum=Global checksum -MakeIntegrityAnalysisFrom=Make integrity analysis of application files from -LocalSignature=Embedded local signature (less reliable) -RemoteSignature=Remote distant signature (more reliable) -FilesMissing=Missing Files -FilesUpdated=Updated Files -FilesModified=Modified Files -FilesAdded=Added Files -FileCheckDolibarr=Check integrity of application files -AvailableOnlyOnPackagedVersions=The local file for integrity checking is only available when the application is installed from an official package -XmlNotFound=Xml Integrity File of application not found -SessionId=Session ID -SessionSaveHandler=Handler to save sessions -SessionSavePath=Session save location -PurgeSessions=Purge of sessions -ConfirmPurgeSessions=Do you really want to purge all sessions? This will disconnect every user (except yourself). -NoSessionListWithThisHandler=Save session handler configured in your PHP does not allow listing all running sessions. -LockNewSessions=Lock new connections -ConfirmLockNewSessions=Are you sure you want to restrict any new Dolibarr connection to yourself? Only user %s will be able to connect after that. -UnlockNewSessions=Remove connection lock -YourSession=Your session -Sessions=Users Sessions -WebUserGroup=Web server user/group -PermissionsOnFiles=Permissions on files -PermissionsOnFilesInWebRoot=Permissions on files in web root directory -PermissionsOnFile=Permissions on file %s -NoSessionFound=Your PHP configuration seems to not allow listing of active sessions. The directory used to save sessions (%s) may be protected (for example by OS permissions or by PHP directive open_basedir). -DBStoringCharset=Database charset to store data -DBSortingCharset=Database charset to sort data -HostCharset=Host charset -ClientCharset=Client charset -ClientSortingCharset=Client collation -WarningModuleNotActive=Module %s must be enabled -WarningOnlyPermissionOfActivatedModules=Only permissions related to activated modules are shown here. You can activate other modules in the Home->Setup->Modules page. -DolibarrSetup=Dolibarr install or upgrade -InternalUser=Internal user -ExternalUser=External user -InternalUsers=Internal users -ExternalUsers=External users -UserInterface=User interface -GUISetup=Display -SetupArea=Setup -UploadNewTemplate=Upload new template(s) -FormToTestFileUploadForm=Form to test file upload (according to setup) -ModuleMustBeEnabled=The module/application %s must be enabled -ModuleIsEnabled=The module/application %s has been enabled -IfModuleEnabled=Note: yes is effective only if module %s is enabled -RemoveLock=Remove/rename file %s if it exists, to allow usage of the Update/Install tool. -RestoreLock=Restore file %s, with read permission only, to disable any further use of the Update/Install tool. -SecuritySetup=Security setup -PHPSetup=PHP setup -OSSetup=OS setup -SecurityFilesDesc=Define here options related to security about uploading files. -ErrorModuleRequirePHPVersion=Error, this module requires PHP version %s or higher -ErrorModuleRequireDolibarrVersion=Error, this module requires Dolibarr version %s or higher -ErrorDecimalLargerThanAreForbidden=Error, a precision higher than %s is not supported. -DictionarySetup=Dictionary setup -Dictionary=Dictionaries -ErrorReservedTypeSystemSystemAuto=Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record -ErrorCodeCantContainZero=Code can't contain value 0 -DisableJavascript=Disable JavaScript and Ajax functions DisableJavascriptNote=Note: For test or debug purpose. For optimization for blind person or text browsers, you may prefer to use the setup on the profile of user -UseSearchToSelectCompanyTooltip=Also if you have a large number of third parties (> 100 000), you can increase speed by setting constant COMPANY_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. -UseSearchToSelectContactTooltip=Also if you have a large number of third parties (> 100 000), you can increase speed by setting constant CONTACT_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. -DelaiedFullListToSelectCompany=Wait until a key is pressed before loading content of Third Parties combo list.
    This may increase performance if you have a large number of third parties, but it is less convenient. -DelaiedFullListToSelectContact=Wait until a key is pressed before loading content of Contact combo list.
    This may increase performance if you have a large number of contacts, but it is less convenient. -NumberOfKeyToSearch=Number of characters to trigger search: %s -NumberOfBytes=Number of Bytes -SearchString=Search string -NotAvailableWhenAjaxDisabled=Not available when Ajax disabled -AllowToSelectProjectFromOtherCompany=On document of a third party, can choose a project linked to another third party -TimesheetPreventAfterFollowingMonths=Prevent recording time spent after the following number of months -JavascriptDisabled=JavaScript disabled -UsePreviewTabs=Use preview tabs -ShowPreview=Show preview -ShowHideDetails=Show-Hide details -PreviewNotAvailable=Preview not available -ThemeCurrentlyActive=Theme currently active -MySQLTimeZone=TimeZone MySql (database) -TZHasNoEffect=Dates are stored and returned by database server as if they were kept as submitted string. The timezone has effect only when using the UNIX_TIMESTAMP function (that should not be used by Dolibarr, so database TZ should have no effect, even if changed after data was entered). -Space=Space -Table=Table -Fields=Fields -Index=Index -Mask=Mask -NextValue=Next value -NextValueForInvoices=Next value (invoices) -NextValueForCreditNotes=Next value (credit notes) -NextValueForDeposit=Next value (down payment) -NextValueForReplacements=Next value (replacements) -MustBeLowerThanPHPLimit=Note: your PHP configuration currently limits the maximum filesize for upload to %s %s, irrespective of the value of this parameter -NoMaxSizeByPHPLimit=Note: No limit is set in your PHP configuration -MaxSizeForUploadedFiles=Maximum size for uploaded files (0 to disallow any upload) -UseCaptchaCode=Use graphical code (CAPTCHA) on login page -AntiVirusCommand=Full path to antivirus command -AntiVirusCommandExample=Example for ClamAv Daemon (require clamav-daemon): /usr/bin/clamdscan
    Example for ClamWin (very very slow): c:\\Progra~1\\ClamWin\\bin\\clamscan.exe -AntiVirusParam= More parameters on command line -AntiVirusParamExample=Example for ClamAv Daemon: --fdpass
    Example for ClamWin: --database="C:\\Program Files (x86)\\ClamWin\\lib" -ComptaSetup=Accounting module setup -UserSetup=User management setup -MultiCurrencySetup=Multi-currency setup -MenuLimits=Limits and accuracy -MenuIdParent=Parent menu ID -DetailMenuIdParent=ID of parent menu (empty for a top menu) -ParentID=Parent ID -DetailPosition=Sort number to define menu position -AllMenus=All -NotConfigured=Module/Application not configured -Active=Active -SetupShort=Setup -OtherOptions=Other options -OtherSetup=Other Setup -CurrentValueSeparatorDecimal=Decimal separator -CurrentValueSeparatorThousand=Thousand separator -Destination=Destination -IdModule=Module ID -IdPermissions=Permissions ID -LanguageBrowserParameter=Parameter %s -LocalisationDolibarrParameters=Localization parameters -ClientTZ=Client Time Zone (user) -ClientHour=Client time (user) -OSTZ=Server OS Time Zone -PHPTZ=PHP server Time Zone -DaylingSavingTime=Daylight saving time -CurrentHour=PHP Time (server) -CurrentSessionTimeOut=Current session timeout -YouCanEditPHPTZ=To set a different PHP timezone (not required), you can try to add a .htaccess file with a line like this "SetEnv TZ Europe/Paris" -HoursOnThisPageAreOnServerTZ=Warning, in contrary of other screens, hours on this page are not in your local timezone, but of the timezone of the server. -Box=Widget -Boxes=Widgets -MaxNbOfLinesForBoxes=Max. number of lines for widgets -AllWidgetsWereEnabled=All available widgets are enabled -PositionByDefault=Default order -Position=Position -MenusDesc=Menu managers set content of the two menu bars (horizontal and vertical). -MenusEditorDesc=The menu editor allows you to define custom menu entries. Use it carefully to avoid instability and permanently unreachable menu entries.
    Some modules add menu entries (in menu All mostly). If you remove some of these entries by mistake, you can restore them disabling and reenabling the module. -MenuForUsers=Menu for users -LangFile=.lang file -Language_en_US_es_MX_etc=Language (en_US, es_MX, ...) -System=System -SystemInfo=System information -SystemToolsArea=System tools area -SystemToolsAreaDesc=This area provides administration functions. Use the menu to choose the required feature. -Purge=Purge -PurgeAreaDesc=This page allows you to delete all files generated or stored by Dolibarr (temporary files or all files in %s directory). Using this feature is not normally necessary. It is provided as a workaround for users whose Dolibarr is hosted by a provider that does not offer permissions to delete files generated by the web server. -PurgeDeleteLogFile=Delete log files, including %s defined for Syslog module (no risk of losing data) -PurgeDeleteTemporaryFiles=Delete all log and temporary files (no risk of losing data). Parameter can be 'tempfilesold', 'logfiles' or both 'tempfilesold+logfiles'. Note: Deletion of temporary files is done only if the temp directory was created more than 24 hours ago. -PurgeDeleteTemporaryFilesShort=Delete log and temporary files -PurgeDeleteAllFilesInDocumentsDir=Delete all files in directory: %s.
    This will delete all generated documents related to elements (third parties, invoices etc...), files uploaded into the ECM module, database backup dumps and temporary files. -PurgeRunNow=Purge now -PurgeNothingToDelete=No directory or files to delete. -PurgeNDirectoriesDeleted=%s files or directories deleted. -PurgeNDirectoriesFailed=Failed to delete %s files or directories. -PurgeAuditEvents=Purge all security events -ConfirmPurgeAuditEvents=Are you sure you want to purge all security events? All security logs will be deleted, no other data will be removed. -GenerateBackup=Generate backup -Backup=Backup -Restore=Restore -RunCommandSummary=Backup has been launched with the following command -BackupResult=Backup result -BackupFileSuccessfullyCreated=Backup file successfully generated -YouCanDownloadBackupFile=The generated file can now be downloaded -NoBackupFileAvailable=No backup files available. -ExportMethod=Export method -ImportMethod=Import method -ToBuildBackupFileClickHere=To build a backup file, click here. -ImportMySqlDesc=To import a MySQL backup file, you may use phpMyAdmin via your hosting or use the mysql command from the Command line.
    For example: -ImportPostgreSqlDesc=To import a backup file, you must use pg_restore command from command line: -ImportMySqlCommand=%s %s < mybackupfile.sql -ImportPostgreSqlCommand=%s %s mybackupfile.sql -FileNameToGenerate=Filename for backup: -Compression=Compression -CommandsToDisableForeignKeysForImport=Command to disable foreign keys on import -CommandsToDisableForeignKeysForImportWarning=Mandatory if you want to be able to restore your sql dump later -ExportCompatibility=Compatibility of generated export file -ExportUseMySQLQuickParameter=Use the --quick parameter -ExportUseMySQLQuickParameterHelp=The '--quick' parameter helps limit RAM consumption for large tables. -MySqlExportParameters=MySQL export parameters -PostgreSqlExportParameters= PostgreSQL export parameters -UseTransactionnalMode=Use transactional mode -FullPathToMysqldumpCommand=Full path to mysqldump command -FullPathToPostgreSQLdumpCommand=Full path to pg_dump command -AddDropDatabase=Add DROP DATABASE command -AddDropTable=Add DROP TABLE command -ExportStructure=Structure -NameColumn=Name columns -ExtendedInsert=Extended INSERT -NoLockBeforeInsert=No lock commands around INSERT -DelayedInsert=Delayed insert -EncodeBinariesInHexa=Encode binary data in hexadecimal -IgnoreDuplicateRecords=Ignore errors of duplicate record (INSERT IGNORE) -AutoDetectLang=Autodetect (browser language) -FeatureDisabledInDemo=Feature disabled in demo -FeatureAvailableOnlyOnStable=Feature only available on official stable versions -BoxesDesc=Widgets are components showing some information that you can add to personalize some pages. You can choose between showing the widget or not by selecting target page and clicking 'Activate', or by clicking the trashcan to disable it. -OnlyActiveElementsAreShown=Only elements from enabled modules are shown. -ModulesDesc=The modules/applications determine which features are available in the software. Some modules require permissions to be granted to users after activating the module. Click the on/off button %s of each module to enable or disable a module/application. -ModulesDesc2=Click the wheel button %s to configure the module/application. -ModulesMarketPlaceDesc=You can find more modules to download on external websites on the Internet... -ModulesDeployDesc=If permissions on your file system allow it, you can use this tool to deploy an external module. The module will then be visible on the tab %s. -ModulesMarketPlaces=Find external app/modules -ModulesDevelopYourModule=Develop your own app/modules -ModulesDevelopDesc=You may also develop your own module or find a partner to develop one for you. -DOLISTOREdescriptionLong=Instead of switching on www.dolistore.com web site to find an external module, you can use this embedded tool that will perform the search on the external market place for you (may be slow, need an internet access)... -NewModule=New module -FreeModule=Free -CompatibleUpTo=Compatible with version %s -NotCompatible=This module does not seem compatible with your Dolibarr %s (Min %s - Max %s). -CompatibleAfterUpdate=This module requires an update to your Dolibarr %s (Min %s - Max %s). -SeeInMarkerPlace=See in Market place -SeeSetupOfModule=See setup of module %s -SetOptionTo=Set option %s to %s -Updated=Updated -AchatTelechargement=Buy / Download -GoModuleSetupArea=To deploy/install a new module, go to the Module setup area: %s. -DoliStoreDesc=DoliStore, the official market place for Dolibarr ERP/CRM external modules -DoliPartnersDesc=List of companies providing custom-developed modules or features.
    Note: since Dolibarr is an open source application, anyone experienced in PHP programming should be able to develop a module. -WebSiteDesc=External websites for more add-on (non-core) modules... -DevelopYourModuleDesc=Some solutions to develop your own module... -URL=URL -RelativeURL=Relative URL -BoxesAvailable=Widgets available -BoxesActivated=Widgets activated -ActivateOn=Activate on -ActiveOn=Activated on -ActivatableOn=Activatable on -SourceFile=Source file -AvailableOnlyIfJavascriptAndAjaxNotDisabled=Available only if JavaScript is not disabled -Required=Required -UsedOnlyWithTypeOption=Used by some agenda option only -Security=Security -Passwords=Passwords -DoNotStoreClearPassword=Encrypt passwords stored in database (NOT as plain-text). It is strongly recommended to activate this option. -MainDbPasswordFileConfEncrypted=Encrypt database password stored in conf.php. It is strongly recommended to activate this option. -InstrucToEncodePass=To have password encoded into the conf.php file, replace the line
    $dolibarr_main_db_pass="...";
    by
    $dolibarr_main_db_pass="crypted:%s"; -InstrucToClearPass=To have password decoded (clear) into the conf.php file, replace the line
    $dolibarr_main_db_pass="crypted:...";
    by
    $dolibarr_main_db_pass="%s"; -ProtectAndEncryptPdfFiles=Protect generated PDF files. This is NOT recommended as it breaks bulk PDF generation. -ProtectAndEncryptPdfFilesDesc=Protection of a PDF document keeps it available to read and print with any PDF browser. However, editing and copying is not possible anymore. Note that using this feature makes building of a global merged PDFs not working. -Feature=Feature -DolibarrLicense=License -Developpers=Developers/contributors -OfficialWebSite=Dolibarr official web site -OfficialWebSiteLocal=Local web site (%s) -OfficialWiki=Dolibarr documentation / Wiki -OfficialDemo=Dolibarr online demo -OfficialMarketPlace=Official market place for external modules/addons -OfficialWebHostingService=Referenced web hosting services (Cloud hosting) -ReferencedPreferredPartners=Preferred Partners -OtherResources=Other resources -ExternalResources=External Resources -SocialNetworks=Social Networks -SocialNetworkId=Social Network ID -ForDocumentationSeeWiki=For user or developer documentation (Doc, FAQs...),
    take a look at the Dolibarr Wiki:
    %s -ForAnswersSeeForum=For any other questions/help, you can use the Dolibarr forum:
    %s -HelpCenterDesc1=Here are some resources for getting help and support with Dolibarr. -HelpCenterDesc2=Some of these resources are only available in english. -CurrentMenuHandler=Current menu handler -MeasuringUnit=Measuring unit -LeftMargin=Left margin -TopMargin=Top margin -PaperSize=Paper type -Orientation=Orientation -SpaceX=Space X -SpaceY=Space Y -FontSize=Font size -Content=Content -NoticePeriod=Notice period -NewByMonth=New by month -Emails=Emails -EMailsSetup=Emails setup -EMailsDesc=This page allows you to set parameters or options for email sending. -EmailSenderProfiles=Emails sender profiles -EMailsSenderProfileDesc=You can keep this section empty. If you enter some emails here, they will be added to the list of possible senders into the combobox when your write a new email. -MAIN_MAIL_SMTP_PORT=SMTP/SMTPS Port (default value in php.ini: %s) -MAIN_MAIL_SMTP_SERVER=SMTP/SMTPS Host (default value in php.ini: %s) -MAIN_MAIL_SMTP_PORT_NotAvailableOnLinuxLike=SMTP/SMTPS Port (Not defined into PHP on Unix-like systems) -MAIN_MAIL_SMTP_SERVER_NotAvailableOnLinuxLike=SMTP/SMTPS Host (Not defined into PHP on Unix-like systems) -MAIN_MAIL_EMAIL_FROM=Sender email for automatic emails (default value in php.ini: %s) -MAIN_MAIL_ERRORS_TO=Email used for error returns emails (fields 'Errors-To' in emails sent) -MAIN_MAIL_AUTOCOPY_TO= Copy (Bcc) all sent emails to -MAIN_DISABLE_ALL_MAILS=Disable all email sending (for test purposes or demos) -MAIN_MAIL_FORCE_SENDTO=Send all emails to (instead of real recipients, for test purposes) -MAIN_MAIL_ENABLED_USER_DEST_SELECT=Suggest emails of employees (if defined) into the list of predefined recipient when writing a new email -MAIN_MAIL_SENDMODE=Email sending method -MAIN_MAIL_SMTPS_ID=SMTP ID (if sending server requires authentication) -MAIN_MAIL_SMTPS_PW=SMTP Password (if sending server requires authentication) -MAIN_MAIL_EMAIL_TLS=Use TLS (SSL) encryption -MAIN_MAIL_EMAIL_STARTTLS=Use TLS (STARTTLS) encryption -MAIN_MAIL_EMAIL_SMTP_ALLOW_SELF_SIGNED=Authorise les certificats auto-signés -MAIN_MAIL_EMAIL_DKIM_ENABLED=Use DKIM to generate email signature -MAIN_MAIL_EMAIL_DKIM_DOMAIN=Email Domain for use with dkim -MAIN_MAIL_EMAIL_DKIM_SELECTOR=Name of dkim selector -MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY=Private key for dkim signing -MAIN_DISABLE_ALL_SMS=Disable all SMS sending (for test purposes or demos) -MAIN_SMS_SENDMODE=Method to use to send SMS -MAIN_MAIL_SMS_FROM=Default sender phone number for SMS sending -MAIN_MAIL_DEFAULT_FROMTYPE=Default sender email for manual sending (User email or Company email) -UserEmail=User email -CompanyEmail=Company Email -FeatureNotAvailableOnLinux=Feature not available on Unix like systems. Test your sendmail program locally. -FixOnTransifex=Fix the translation on the online translation platform of project -SubmitTranslation=If the translation for this language is not complete or you find errors, you can correct this by editing files in directory langs/%s and submit your change to www.transifex.com/dolibarr-association/dolibarr/ -SubmitTranslationENUS=If translation for this language is not complete or you find errors, you can correct this by editing files into directory langs/%s and submit modified files on dolibarr.org/forum or, if you are a developer, with a PR on github.com/Dolibarr/dolibarr -ModuleSetup=Module setup -ModulesSetup=Modules/Application setup -ModuleFamilyBase=System -ModuleFamilyCrm=Customer Relationship Management (CRM) -ModuleFamilySrm=Vendor Relationship Management (VRM) -ModuleFamilyProducts=Product Management (PM) -ModuleFamilyHr=Human Resource Management (HR) -ModuleFamilyProjects=Projects/Collaborative work -ModuleFamilyOther=Other -ModuleFamilyTechnic=Multi-modules tools -ModuleFamilyExperimental=Experimental modules -ModuleFamilyFinancial=Financial Modules (Accounting/Treasury) -ModuleFamilyECM=Electronic Content Management (ECM) -ModuleFamilyPortal=Websites and other frontal application -ModuleFamilyInterface=Interfaces with external systems -MenuHandlers=Menu handlers -MenuAdmin=Menu editor -DoNotUseInProduction=Do not use in production -ThisIsProcessToFollow=Upgrade procedure: -ThisIsAlternativeProcessToFollow=This is an alternative setup to process manually: -StepNb=Step %s -FindPackageFromWebSite=Find a package that provides the features you need (for example on the official web site %s). -DownloadPackageFromWebSite=Download package (for example from the official web site %s). -UnpackPackageInDolibarrRoot=Unpack/unzip the packaged files into your Dolibarr server directory: %s -UnpackPackageInModulesRoot=To deploy/install an external module, unpack/unzip the packaged files into the server directory dedicated to external modules:
    %s -SetupIsReadyForUse=Module deployment is finished. You must however enable and setup the module in your application by going to the page setup modules: %s. -NotExistsDirect=The alternative root directory is not defined to an existing directory.
    -InfDirAlt=Since version 3, it is possible to define an alternative root directory. This allows you to store, into a dedicated directory, plug-ins and custom templates.
    Just create a directory at the root of Dolibarr (eg: custom).
    -InfDirExample=
    Then declare it in the file conf.php
    $dolibarr_main_url_root_alt='/custom'
    $dolibarr_main_document_root_alt='/path/of/dolibarr/htdocs/custom'
    If these lines are commented with "#", to enable them, just uncomment by removing the "#" character. -YouCanSubmitFile=You can upload the .zip file of module package from here: -CurrentVersion=Dolibarr current version -CallUpdatePage=Browse to the page that updates the database structure and data: %s. -LastStableVersion=Latest stable version -LastActivationDate=Latest activation date -LastActivationAuthor=Latest activation author -LastActivationIP=Latest activation IP -UpdateServerOffline=Update server offline -WithCounter=Manage a counter -GenericMaskCodes=You may enter any numbering mask. In this mask, the following tags can be used:
    {000000} corresponds to a number which will be incremented on each %s. Enter as many zeros as the desired length of the counter. The counter will be completed by zeros from the left in order to have as many zeros as the mask.
    {000000+000} same as the previous one but an offset corresponding to the number to the right of the + sign is applied starting on the first %s.
    {000000@x} same as the previous one but the counter is reset to zero when month x is reached (x between 1 and 12, or 0 to use the early months of fiscal year defined in your configuration, or 99 to reset to zero every month). If this option is used and x is 2 or higher, then the sequence {yy}{mm} or {yyyy}{mm} is also required.
    {dd} day (01 to 31).
    {mm} month (01 to 12).
    {yy}, {yyyy} or {y} year over 2, 4 or 1 numbers.
    -GenericMaskCodes2={cccc} the client code on n characters
    {cccc000} the client code on n characters is followed by a counter dedicated to the customer. This counter dedicated to customer is reset at same time as the global counter.
    {tttt} The code of third party type on n characters (see menu Home - Setup - Dictionary - Types of third parties). If you add this tag, the counter will be different for each type of third party.
    -GenericMaskCodes3=All other characters in the mask will remain intact.
    Spaces are not allowed.
    -GenericMaskCodes3EAN=All other characters in the mask will remain intact (except * or ? in 13th position in EAN13).
    Spaces are not allowed.
    In EAN13, the last character after the last } in 13th position should be * or ? . It will be replaced by the calculated key.
    -GenericMaskCodes4a=Example on the 99th %s of the third party TheCompany, with date 2007-01-31:
    -GenericMaskCodes4b=Example on third party created on 2007-03-01:
    -GenericMaskCodes4c=Example on product created on 2007-03-01:
    -GenericMaskCodes5=ABC{yy}{mm}-{000000} will give ABC0701-000099
    {0000+100@1}-ZZZ/{dd}/XXX will give 0199-ZZZ/31/XXX
    IN{yy}{mm}-{0000}-{t} will give IN0701-0099-A if the type of company is 'Responsable Inscripto' with code for type that is 'A_RI' -GenericNumRefModelDesc=Returns a customizable number according to a defined mask. -ServerAvailableOnIPOrPort=Server is available at address %s on port %s -ServerNotAvailableOnIPOrPort=Server is not available at address %s on port %s -DoTestServerAvailability=Test server connectivity -DoTestSend=Test sending -DoTestSendHTML=Test sending HTML -ErrorCantUseRazIfNoYearInMask=Error, can't use option @ to reset counter each year if sequence {yy} or {yyyy} is not in mask. -ErrorCantUseRazInStartedYearIfNoYearMonthInMask=Error, can't use option @ if sequence {yy}{mm} or {yyyy}{mm} is not in mask. -UMask=UMask parameter for new files on Unix/Linux/BSD/Mac file system. -UMaskExplanation=This parameter allow you to define permissions set by default on files created by Dolibarr on server (during upload for example).
    It must be the octal value (for example, 0666 means read and write for everyone).
    This parameter is useless on a Windows server. -SeeWikiForAllTeam=Take a look at the Wiki page for a list of contributors and their organization -UseACacheDelay= Delay for caching export response in seconds (0 or empty for no cache) DisableLinkToHelpCenter=Hide link "Need help or support" on login page DisableLinkToHelp=Hide link to online help "%s" -AddCRIfTooLong=There is no automatic text wrapping, text that is too long will not display on documents. Please add carriage returns in the text area if needed. -ConfirmPurge=Are you sure you want to execute this purge?
    This will permanently delete all your data files with no way to restore them (ECM files, attached files...). -MinLength=Minimum length -LanguageFilesCachedIntoShmopSharedMemory=Files .lang loaded in shared memory -LanguageFile=Language file -ExamplesWithCurrentSetup=Examples with current configuration -ListOfDirectories=List of OpenDocument templates directories -ListOfDirectoriesForModelGenODT=List of directories containing templates files with OpenDocument format.

    Put here full path of directories.
    Add a carriage return between eah directory.
    To add a directory of the GED module, add here DOL_DATA_ROOT/ecm/yourdirectoryname.

    Files in those directories must end with .odt or .ods. -NumberOfModelFilesFound=Number of ODT/ODS template files found in these directories -ExampleOfDirectoriesForModelGen=Examples of syntax:
    c:\\myapp\\mydocumentdir\\mysubdir
    /home/myapp/mydocumentdir/mysubdir
    DOL_DATA_ROOT/ecm/ecmdir -FollowingSubstitutionKeysCanBeUsed=
    To know how to create your odt document templates, before storing them in those directories, read wiki documentation: -FullListOnOnlineDocumentation=http://wiki.dolibarr.org/index.php/Create_an_ODT_document_template -FirstnameNamePosition=Position of Name/Lastname -DescWeather=The following images will be shown on the dashboard when the number of late actions reach the following values: -KeyForWebServicesAccess=Key to use Web Services (parameter "dolibarrkey" in webservices) -TestSubmitForm=Input test form -ThisForceAlsoTheme=Using this menu manager will also use its own theme whatever the user choice. Also this menu manager specialized for smartphones does not work on all smartphone. Use another menu manager if you experience problems with yours. -ThemeDir=Skins directory -ConnectionTimeout=Connection timeout -ResponseTimeout=Response timeout -SmsTestMessage=Test message from __PHONEFROM__ to __PHONETO__ -ModuleMustBeEnabledFirst=Module %s must be enabled first if you need this feature. -SecurityToken=Key to secure URLs -NoSmsEngine=No SMS sender manager available. A SMS sender manager is not installed with the default distribution because they depend on an external vendor, but you can find some on %s -PDF=PDF -PDFDesc=Global options for PDF generation -PDFOtherDesc=PDF Option specific to some modules -PDFAddressForging=Rules for address section -HideAnyVATInformationOnPDF=Hide all information related to Sales Tax / VAT -PDFRulesForSalesTax=Rules for Sales Tax / VAT -PDFLocaltax=Rules for %s -HideLocalTaxOnPDF=Hide %s rate in column Sale Tax / VAT -HideDescOnPDF=Hide products description -HideRefOnPDF=Hide products ref. -HideDetailsOnPDF=Hide product lines details -PlaceCustomerAddressToIsoLocation=Use french standard position (La Poste) for customer address position -Library=Library -UrlGenerationParameters=Parameters to secure URLs -SecurityTokenIsUnique=Use a unique securekey parameter for each URL -EnterRefToBuildUrl=Enter reference for object %s -GetSecuredUrl=Get calculated URL -ButtonHideUnauthorized=Hide unauthorized action buttons also for internal users (just greyed otherwise) -OldVATRates=Old VAT rate -NewVATRates=New VAT rate -PriceBaseTypeToChange=Modify on prices with base reference value defined on -MassConvert=Launch bulk conversion -PriceFormatInCurrentLanguage=Price Format In Current Language -String=String -String1Line=String (1 line) -TextLong=Long text -TextLongNLines=Long text (n lines) -HtmlText=Html text -Int=Integer -Float=Float -DateAndTime=Date and hour -Unique=Unique -Boolean=Boolean (one checkbox) -ExtrafieldPhone = Phone -ExtrafieldPrice = Price -ExtrafieldMail = Email -ExtrafieldUrl = Url -ExtrafieldSelect = Select list -ExtrafieldSelectList = Select from table -ExtrafieldSeparator=Separator (not a field) -ExtrafieldPassword=Password -ExtrafieldRadio=Radio buttons (one choice only) -ExtrafieldCheckBox=Checkboxes -ExtrafieldCheckBoxFromList=Checkboxes from table -ExtrafieldLink=Link to an object -ComputedFormula=Computed field -ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: $db, $conf, $langs, $mysoc, $user, $object.
    WARNING: Only some properties of $object may be available. If you need a properties not loaded, just fetch yourself the object into your formula like in the second example.
    Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.

    Example of formula:
    $object->id < 10 ? round($object->id / 2, 2): ($object->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)

    Example to reload object
    (($reloadedobj = new Societe($db)) && ($reloadedobj->fetchNoCompute($obj->id ? $obj->id: ($obj->rowid ? $obj->rowid: $object->id)) > 0)) ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5: '-1'

    Other example of formula to force load of object and its parent object:
    (($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref: 'Parent project not found' -Computedpersistent=Store computed field -ComputedpersistentDesc=Computed extra fields will be stored in the database, however, the value will only be recalculated when the object of this field is changed. If the computed field depends on other objects or global data this value might be wrong!! -ExtrafieldParamHelpPassword=Leaving this field blank means this value will be stored without encryption (field must be only hidden with star on screen).
    Set 'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retrieve original value) -ExtrafieldParamHelpselect=List of values must be lines with format key,value (where key can't be '0')

    for example:
    1,value1
    2,value2
    code3,value3
    ...

    In order to have the list depending on another complementary attribute list:
    1,value1|options_parent_list_code:parent_key
    2,value2|options_parent_list_code:parent_key

    In order to have the list depending on another list:
    1,value1|parent_list_code:parent_key
    2,value2|parent_list_code:parent_key -ExtrafieldParamHelpcheckbox=List of values must be lines with format key,value (where key can't be '0')

    for example:
    1,value1
    2,value2
    3,value3
    ... -ExtrafieldParamHelpradio=List of values must be lines with format key,value (where key can't be '0')

    for example:
    1,value1
    2,value2
    3,value3
    ... -ExtrafieldParamHelpsellist=List of values comes from a table
    Syntax: table_name:label_field:id_field::filtersql
    Example: c_typent:libelle:id::filtersql

    - id_field is necessarly a primary int key
    - filtersql is a SQL condition. It can be a simple test (eg active=1) to display only active value
    You can also use $ID$ in filter which is the current id of current object
    To use a SELECT into the filter use the keyword $SEL$ to bypass anti-injection protection.
    if you want to filter on extrafields use syntax extra.fieldcode=... (where field code is the code of extrafield)

    In order to have the list depending on another complementary attribute list:
    c_typent:libelle:id:options_parent_list_code|parent_column:filter

    In order to have the list depending on another list:
    c_typent:libelle:id:parent_list_code|parent_column:filter -ExtrafieldParamHelpchkbxlst=List of values comes from a table
    Syntax: table_name:label_field:id_field::filtersql
    Example: c_typent:libelle:id::filtersql

    filter can be a simple test (eg active=1) to display only active value
    You can also use $ID$ in filter witch is the current id of current object
    To do a SELECT in filter use $SEL$
    if you want to filter on extrafields use syntax extra.fieldcode=... (where field code is the code of extrafield)

    In order to have the list depending on another complementary attribute list:
    c_typent:libelle:id:options_parent_list_code|parent_column:filter

    In order to have the list depending on another list:
    c_typent:libelle:id:parent_list_code|parent_column:filter -ExtrafieldParamHelplink=Parameters must be ObjectName:Classpath
    Syntax: ObjectName:Classpath -ExtrafieldParamHelpSeparator=Keep empty for a simple separator
    Set this to 1 for a collapsing separator (open by default for new session, then status is kept for each user session)
    Set this to 2 for a collapsing separator (collapsed by default for new session, then status is kept fore each user session) -LibraryToBuildPDF=Library used for PDF generation -LocalTaxDesc=Some countries may apply two or three taxes on each invoice line. If this is the case, choose the type for the second and third tax and its rate. Possible type are:
    1: local tax apply on products and services without vat (localtax is calculated on amount without tax)
    2: local tax apply on products and services including vat (localtax is calculated on amount + main tax)
    3: local tax apply on products without vat (localtax is calculated on amount without tax)
    4: local tax apply on products including vat (localtax is calculated on amount + main vat)
    5: local tax apply on services without vat (localtax is calculated on amount without tax)
    6: local tax apply on services including vat (localtax is calculated on amount + tax) -SMS=SMS -LinkToTestClickToDial=Enter a phone number to call to show a link to test the ClickToDial url for user %s -RefreshPhoneLink=Refresh link -LinkToTest=Clickable link generated for user %s (click phone number to test) -KeepEmptyToUseDefault=Keep empty to use default value -KeepThisEmptyInMostCases=In most cases, you can keep this field empy. -DefaultLink=Default link -SetAsDefault=Set as default -ValueOverwrittenByUserSetup=Warning, this value may be overwritten by user specific setup (each user can set his own clicktodial url) -ExternalModule=External module -InstalledInto=Installed into directory %s -BarcodeInitForThirdparties=Mass barcode init for third-parties -BarcodeInitForProductsOrServices=Mass barcode init or reset for products or services -CurrentlyNWithoutBarCode=Currently, you have %s record on %s %s without barcode defined. -InitEmptyBarCode=Init value for next %s empty records -EraseAllCurrentBarCode=Erase all current barcode values -ConfirmEraseAllCurrentBarCode=Are you sure you want to erase all current barcode values? -AllBarcodeReset=All barcode values have been removed -NoBarcodeNumberingTemplateDefined=No numbering barcode template enabled in the Barcode module setup. -EnableFileCache=Enable file cache -ShowDetailsInPDFPageFoot=Add more details into footer, such as company address or manager names (in addition to professional ids, company capital and VAT number). -NoDetails=No additional details in footer -DisplayCompanyInfo=Display company address -DisplayCompanyManagers=Display manager names -DisplayCompanyInfoAndManagers=Display company address and manager names -EnableAndSetupModuleCron=If you want to have this recurring invoice generated automatically, module *%s* must be enabled and correctly setup. Otherwise, generation of invoices must be done manually from this template using the *Create* button. Note that even if you enabled automatic generation, you can still safely launch manual generation. Generation of duplicates for the same period is not possible. -ModuleCompanyCodeCustomerAquarium=%s followed by customer code for a customer accounting code -ModuleCompanyCodeSupplierAquarium=%s followed by vendor code for a vendor accounting code -ModuleCompanyCodePanicum=Return an empty accounting code. -ModuleCompanyCodeDigitaria=Returns a compound accounting code according to the name of the third party. The code consists of a prefix that can be defined in the first position followed by the number of characters defined in the third party code. -ModuleCompanyCodeCustomerDigitaria=%s followed by the truncated customer name by the number of characters: %s for the customer accounting code. -ModuleCompanyCodeSupplierDigitaria=%s followed by the truncated supplier name by the number of characters: %s for the supplier accounting code. -Use3StepsApproval=By default, Purchase Orders need to be created and approved by 2 different users (one step/user to create and one step/user to approve. Note that if user has both permission to create and approve, one step/user will be enough). You can ask with this option to introduce a third step/user approval, if amount is higher than a dedicated value (so 3 steps will be necessary: 1=validation, 2=first approval and 3=second approval if amount is enough).
    Set this to empty if one approval (2 steps) is enough, set it to a very low value (0.1) if a second approval (3 steps) is always required. -UseDoubleApproval=Use a 3 steps approval when amount (without tax) is higher than... -WarningPHPMail=WARNING: The setup to send emails from the application is using the default generic setup. It is often better to setup outgoing emails to use the email server of your Email Service Provider instead of the default setup for several reasons: -WarningPHPMailA=- Using the server of the Email Service Provider increases the trustability of your email, so it increases the deliverablity without being flagged as SPAM -WarningPHPMailB=- Some Email Service Providers (like Yahoo) do not allow you to send an email from another server than their own server. Your current setup uses the server of the application to send email and not the server of your email provider, so some recipients (the one compatible with the restrictive DMARC protocol), will ask your email provider if they can accept your email and some email providers (like Yahoo) may respond "no" because the server is not theirs, so few of your sent Emails may not be accepted for delivery (be careful also of your email provider's sending quota). -WarningPHPMailC=- Using the SMTP server of your own Email Service Provider to send emails is also interesting so all emails sent from application will also be saved into your "Sent" directory of your mailbox. -WarningPHPMailD=If the method 'PHP Mail' is really the method you would like to use, you can remove this warning by adding the constant MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP to 1 in Home - Setup - Other. -WarningPHPMail2=If your email SMTP provider need to restrict email client to some IP addresses (very rare), this is the IP address of the mail user agent (MUA) for your ERP CRM application: %s. -WarningPHPMailSPF=If the domain name in your sender email address is protected by a SPF record (ask you domain name registar), you must add the following IPs in the SPF record of the DNS of your domain: %s. -ClickToShowDescription=Click to show description -DependsOn=This module needs the module(s) -RequiredBy=This module is required by module(s) -TheKeyIsTheNameOfHtmlField=This is the name of the HTML field. Technical knowledge is required to read the content of the HTML page to get the key name of a field. -PageUrlForDefaultValues=You must enter the relative path of the page URL. If you include parameters in URL, the default values will be effective if all parameters are set to same value. -PageUrlForDefaultValuesCreate=
    Example:
    For the form to create a new third party, it is %s.
    For URL of external modules installed into custom directory, do not include the "custom/", so use path like mymodule/mypage.php and not custom/mymodule/mypage.php.
    If you want default value only if url has some parameter, you can use %s -PageUrlForDefaultValuesList=
    Example:
    For the page that lists third parties, it is %s.
    For URL of external modules installed into custom directory, do not include the "custom/" so use a path like mymodule/mypagelist.php and not custom/mymodule/mypagelist.php.
    If you want default value only if url has some parameter, you can use %s -AlsoDefaultValuesAreEffectiveForActionCreate=Also note that overwritting default values for form creation works only for pages that were correctly designed (so with parameter action=create or presend...) -EnableDefaultValues=Enable customization of default values -EnableOverwriteTranslation=Enable usage of overwritten translation -GoIntoTranslationMenuToChangeThis=A translation has been found for the key with this code. To change this value, you must edit it from Home-Setup-translation. -WarningSettingSortOrder=Warning, setting a default sort order may result in a technical error when going on the list page if field is an unknown field. If you experience such an error, come back to this page to remove the default sort order and restore default behavior. -Field=Field -ProductDocumentTemplates=Document templates to generate product document -FreeLegalTextOnExpenseReports=Free legal text on expense reports -WatermarkOnDraftExpenseReports=Watermark on draft expense reports -AttachMainDocByDefault=Set this to 1 if you want to attach main document to email by default (if applicable) -FilesAttachedToEmail=Attach file -SendEmailsReminders=Send agenda reminders by emails -davDescription=Setup a WebDAV server -DAVSetup=Setup of module DAV -DAV_ALLOW_PRIVATE_DIR=Enable the generic private directory (WebDAV dedicated directory named "private" - login required) -DAV_ALLOW_PRIVATE_DIRTooltip=The generic private directory is a WebDAV directory anybody can access with its application login/pass. -DAV_ALLOW_PUBLIC_DIR=Enable the generic public directory (WebDAV dedicated directory named "public" - no login required) -DAV_ALLOW_PUBLIC_DIRTooltip=The generic public directory is a WebDAV directory anybody can access (in read and write mode), with no authorization required (login/password account). -DAV_ALLOW_ECM_DIR=Enable the DMS/ECM private directory (root directory of the DMS/ECM module - login required) -DAV_ALLOW_ECM_DIRTooltip=The root directory where all files are manually uploaded when using the DMS/ECM module. Similarly as access from the web interface, you will need a valid login/password with adecuate permissions to access it. -# Modules -Module0Name=Users & Groups -Module0Desc=Users / Employees and Groups management -Module1Name=Third Parties -Module1Desc=Companies and contacts management (customers, prospects...) -Module2Name=Commercial -Module2Desc=Commercial management -Module10Name=Accounting (simplified) -Module10Desc=Simple accounting reports (journals, turnover) based on database content. Does not use any ledger table. -Module20Name=Proposals -Module20Desc=Commercial proposal management -Module22Name=Mass Emailings -Module22Desc=Manage bulk emailing -Module23Name=Energy -Module23Desc=Monitoring the consumption of energies -Module25Name=Sales Orders -Module25Desc=Sales order management -Module30Name=Invoices -Module30Desc=Management of invoices and credit notes for customers. Management of invoices and credit notes for suppliers -Module40Name=Vendors -Module40Desc=Vendors and purchase management (purchase orders and billing of supplier invoices) -Module42Name=Debug Logs -Module42Desc=Logging facilities (file, syslog, ...). Such logs are for technical/debug purposes. -Module43Name=Debug Bar -Module43Desc=A tool for developper adding a debug bar in your browser. -Module49Name=Editors -Module49Desc=Editor management -Module50Name=Products -Module50Desc=Management of Products -Module51Name=Mass mailings -Module51Desc=Mass paper mailing management -Module52Name=Stocks -Module52Desc=Stock management -Module53Name=Services -Module53Desc=Management of Services -Module54Name=Contracts/Subscriptions -Module54Desc=Management of contracts (services or recurring subscriptions) -Module55Name=Barcodes -Module55Desc=Barcode or QR code management -Module56Name=Payment by credit transfer -Module56Desc=Management of payment of suppliers by Credit Transfer orders. It includes generation of SEPA file for European countries. -Module57Name=Payments by Direct Debit -Module57Desc=Management of Direct Debit orders. It includes generation of SEPA file for European countries. -Module58Name=ClickToDial -Module58Desc=Integration of a ClickToDial system (Asterisk, ...) -Module60Name=Stickers -Module60Desc=Management of stickers -Module70Name=Interventions -Module70Desc=Intervention management -Module75Name=Expense and trip notes -Module75Desc=Expense and trip notes management -Module80Name=Shipments -Module80Desc=Shipments and delivery note management -Module85Name=Banks & Cash -Module85Desc=Management of bank or cash accounts -Module100Name=External Site -Module100Desc=Add a link to an external website as a main menu icon. Website is shown in a frame under the top menu. -Module105Name=Mailman and SPIP -Module105Desc=Mailman or SPIP interface for member module -Module200Name=LDAP -Module200Desc=LDAP directory synchronization -Module210Name=PostNuke -Module210Desc=PostNuke integration -Module240Name=Data exports -Module240Desc=Tool to export Dolibarr data (with assistance) -Module250Name=Data imports -Module250Desc=Tool to import data into Dolibarr (with assistance) -Module310Name=Members -Module310Desc=Foundation members management -Module320Name=RSS Feed -Module320Desc=Add a RSS feed to Dolibarr pages -Module330Name=Bookmarks & Shortcuts -Module330Desc=Create shortcuts, always accessible, to the internal or external pages to which you frequently access -Module400Name=Projects or Leads -Module400Desc=Management of projects, leads/opportunities and/or tasks. You can also assign any element (invoice, order, proposal, intervention, ...) to a project and get a transversal view from the project view. -Module410Name=Webcalendar -Module410Desc=Webcalendar integration -Module500Name=Taxes & Special Expenses -Module500Desc=Management of other expenses (sale taxes, social or fiscal taxes, dividends, ...) -Module510Name=Salaries -Module510Desc=Record and track employee payments -Module520Name=Loans -Module520Desc=Management of loans -Module600Name=Notifications on business event -Module600Desc=Send email notifications triggered by a business event: per user (setup defined on each user), per third-party contacts (setup defined on each third party) or by specific emails -Module600Long=Note that this module sends emails in real-time when a specific business event occurs. If you are looking for a feature to send email reminders for agenda events, go into the setup of module Agenda. -Module610Name=Product Variants -Module610Desc=Creation of product variants (color, size etc.) -Module700Name=Donations -Module700Desc=Donation management -Module770Name=Expense Reports -Module770Desc=Manage expense reports claims (transportation, meal, ...) -Module1120Name=Vendor Commercial Proposals -Module1120Desc=Request vendor commercial proposal and prices -Module1200Name=Mantis -Module1200Desc=Mantis integration -Module1520Name=Document Generation -Module1520Desc=Mass email document generation -Module1780Name=Tags/Categories -Module1780Desc=Create tags/category (products, customers, suppliers, contacts or members) -Module2000Name=WYSIWYG editor -Module2000Desc=Allow text fields to be edited/formatted using CKEditor (html) -Module2200Name=Dynamic Prices -Module2200Desc=Use maths expressions for auto-generation of prices -Module2300Name=Scheduled jobs -Module2300Desc=Scheduled jobs management (alias cron or chrono table) -Module2400Name=Events/Agenda -Module2400Desc=Track events. Log automatic events for tracking purposes or record manual events or meetings. This is the principal module for good Customer or Vendor Relationship Management. -Module2500Name=DMS / ECM -Module2500Desc=Document Management System / Electronic Content Management. Automatic organization of your generated or stored documents. Share them when you need. -Module2600Name=API/Web services (SOAP server) -Module2600Desc=Enable the Dolibarr SOAP server providing API services -Module2610Name=API/Web services (REST server) -Module2610Desc=Enable the Dolibarr REST server providing API services -Module2660Name=Call WebServices (SOAP client) -Module2660Desc=Enable the Dolibarr web services client (Can be used to push data/requests to external servers. Only Purchase orders are currently supported.) -Module2700Name=Gravatar -Module2700Desc=Use online Gravatar service (www.gravatar.com) to show photo of users/members (found with their emails). Needs Internet access -Module2800Desc=FTP Client -Module2900Name=GeoIPMaxmind -Module2900Desc=GeoIP Maxmind conversions capabilities -Module3200Name=Unalterable Archives -Module3200Desc=Enable an unalterable log of business events. Events are archived in real-time. The log is a read-only table of chained events that can be exported. This module may be mandatory for some countries. -Module3400Name=Social Networks -Module3400Desc=Enable Social Networks fields into third parties and addresses (skype, twitter, facebook, ...). -Module4000Name=HRM -Module4000Desc=Human resources management (management of department, employee contracts and feelings) -Module5000Name=Multi-company -Module5000Desc=Allows you to manage multiple companies -Module6000Name=Inter-modules Workflow -Module6000Desc=Workflow management between different modules (automatic creation of object and/or automatic status change) -Module10000Name=Websites -Module10000Desc=Create websites (public) with a WYSIWYG editor. This is a webmaster or developer oriented CMS (it is better to know HTML and CSS language). Just setup your web server (Apache, Nginx, ...) to point to the dedicated Dolibarr directory to have it online on the internet with your own domain name. -Module20000Name=Leave Request Management -Module20000Desc=Define and track employee leave requests -Module39000Name=Product Lots -Module39000Desc=Lots, serial numbers, eat-by/sell-by date management for products -Module40000Name=Multicurrency -Module40000Desc=Use alternative currencies in prices and documents -Module50000Name=PayBox -Module50000Desc=Offer customers a PayBox online payment page (credit/debit cards). This can be used to allow your customers to make ad-hoc payments or payments related to a specific Dolibarr object (invoice, order etc...) -Module50100Name=POS SimplePOS -Module50100Desc=Point of Sale module SimplePOS (simple POS). -Module50150Name=POS TakePOS -Module50150Desc=Point of Sale module TakePOS (touchscreen POS, for shops, bars or restaurants). -Module50200Name=Paypal -Module50200Desc=Offer customers a PayPal online payment page (PayPal account or credit/debit cards). This can be used to allow your customers to make ad-hoc payments or payments related to a specific Dolibarr object (invoice, order etc...) -Module50300Name=Stripe -Module50300Desc=Offer customers a Stripe online payment page (credit/debit cards). This can be used to allow your customers to make ad-hoc payments or payments related to a specific Dolibarr object (invoice, order etc...) -Module50400Name=Accounting (double entry) -Module50400Desc=Accounting management (double entries, support General and Subsidiary Ledgers). Export the ledger in several other accounting software formats. -Module54000Name=PrintIPP -Module54000Desc=Direct print (without opening the documents) using Cups IPP interface (Printer must be visible from server, and CUPS must be installed on server). -Module55000Name=Poll, Survey or Vote -Module55000Desc=Create online polls, surveys or votes (like Doodle, Studs, RDVz etc...) -Module59000Name=Margins -Module59000Desc=Module to follow margins -Module60000Name=Commissions -Module60000Desc=Module to manage commissions -Module62000Name=Incoterms -Module62000Desc=Add features to manage Incoterms -Module63000Name=Resources -Module63000Desc=Manage resources (printers, cars, rooms, ...) for allocating to events -Permission11=Read customer invoices -Permission12=Create/modify customer invoices -Permission13=Invalidate customer invoices -Permission14=Validate customer invoices -Permission15=Send customer invoices by email -Permission16=Create payments for customer invoices -Permission19=Delete customer invoices -Permission21=Read commercial proposals -Permission22=Create/modify commercial proposals -Permission24=Validate commercial proposals -Permission25=Send commercial proposals -Permission26=Close commercial proposals -Permission27=Delete commercial proposals -Permission28=Export commercial proposals -Permission31=Read products -Permission32=Create/modify products -Permission34=Delete products -Permission36=See/manage hidden products -Permission38=Export products -Permission39=Ignore minimum price -Permission41=Read projects and tasks (shared project and projects I'm contact for). Can also enter time consumed, for me or my hierarchy, on assigned tasks (Timesheet) -Permission42=Create/modify projects (shared project and projects I'm contact for). Can also create tasks and assign users to project and tasks -Permission44=Delete projects (shared project and projects I'm contact for) -Permission45=Export projects -Permission61=Read interventions -Permission62=Create/modify interventions -Permission64=Delete interventions -Permission67=Export interventions -Permission68=Send interventions by email -Permission69=Validate interventions -Permission70=Invalidate interventions -Permission71=Read members -Permission72=Create/modify members -Permission74=Delete members -Permission75=Setup types of membership -Permission76=Export data -Permission78=Read subscriptions -Permission79=Create/modify subscriptions -Permission81=Read customers orders -Permission82=Create/modify customers orders -Permission84=Validate customers orders -Permission86=Send customers orders -Permission87=Close customers orders -Permission88=Cancel customers orders -Permission89=Delete customers orders -Permission91=Read social or fiscal taxes and vat -Permission92=Create/modify social or fiscal taxes and vat -Permission93=Delete social or fiscal taxes and vat -Permission94=Export social or fiscal taxes -Permission95=Read reports -Permission101=Read sendings -Permission102=Create/modify sendings -Permission104=Validate sendings -Permission105=Send sendings by email -Permission106=Export sendings -Permission109=Delete sendings -Permission111=Read financial accounts -Permission112=Create/modify/delete and compare transactions -Permission113=Setup financial accounts (create, manage categories) -Permission114=Reconcile transactions -Permission115=Export transactions and account statements -Permission116=Transfers between accounts -Permission117=Manage checks dispatching -Permission121=Read third parties linked to user -Permission122=Create/modify third parties linked to user -Permission125=Delete third parties linked to user -Permission126=Export third parties -Permission141=Read all projects and tasks (also private projects for which I am not a contact) -Permission142=Create/modify all projects and tasks (also private projects for which I am not a contact) -Permission144=Delete all projects and tasks (also private projects i am not contact for) -Permission146=Read providers -Permission147=Read stats -Permission151=Read direct debit payment orders -Permission152=Create/modify a direct debit payment orders -Permission153=Send/Transmit direct debit payment orders -Permission154=Record Credits/Rejections of direct debit payment orders -Permission161=Read contracts/subscriptions -Permission162=Create/modify contracts/subscriptions -Permission163=Activate a service/subscription of a contract -Permission164=Disable a service/subscription of a contract -Permission165=Delete contracts/subscriptions -Permission167=Export contracts -Permission171=Read trips and expenses (yours and your subordinates) -Permission172=Create/modify trips and expenses -Permission173=Delete trips and expenses -Permission174=Read all trips and expenses -Permission178=Export trips and expenses -Permission180=Read suppliers -Permission181=Read purchase orders -Permission182=Create/modify purchase orders -Permission183=Validate purchase orders -Permission184=Approve purchase orders -Permission185=Order or cancel purchase orders -Permission186=Receive purchase orders -Permission187=Close purchase orders -Permission188=Cancel purchase orders -Permission192=Create lines -Permission193=Cancel lines -Permission194=Read the bandwidth lines -Permission202=Create ADSL connections -Permission203=Order connections orders -Permission204=Order connections -Permission205=Manage connections -Permission206=Read connections -Permission211=Read Telephony -Permission212=Order lines -Permission213=Activate line -Permission214=Setup Telephony -Permission215=Setup providers -Permission221=Read emailings -Permission222=Create/modify emailings (topic, recipients...) -Permission223=Validate emailings (allows sending) -Permission229=Delete emailings -Permission237=View recipients and info -Permission238=Manually send mailings -Permission239=Delete mailings after validation or sent -Permission241=Read categories -Permission242=Create/modify categories -Permission243=Delete categories -Permission244=See the contents of the hidden categories -Permission251=Read other users and groups -PermissionAdvanced251=Read other users -Permission252=Read permissions of other users -Permission253=Create/modify other users, groups and permissions -PermissionAdvanced253=Create/modify internal/external users and permissions -Permission254=Create/modify external users only -Permission255=Modify other users password -Permission256=Delete or disable other users -Permission262=Extend access to all third parties AND their objects (not only third parties for which the user is a sale representative).
    Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc.).
    Not effective for projects (only rules on project permissions, visibility and assignment matters). -Permission263=Extend access to all third parties WITHOUT their objects (not only third parties for which the user is a sale representative).
    Not effective for external users (always limited to themselves for proposals, orders, invoices, contracts, etc.).
    Not effective for projects (only rules on project permissions, visibility and assignment matters). -Permission271=Read CA -Permission272=Read invoices -Permission273=Issue invoices -Permission281=Read contacts -Permission282=Create/modify contacts -Permission283=Delete contacts -Permission286=Export contacts -Permission291=Read tariffs -Permission292=Set permissions on the tariffs -Permission293=Modify customer's tariffs -Permission300=Read barcodes -Permission301=Create/modify barcodes -Permission302=Delete barcodes -Permission311=Read services -Permission312=Assign service/subscription to contract -Permission331=Read bookmarks -Permission332=Create/modify bookmarks -Permission333=Delete bookmarks -Permission341=Read its own permissions -Permission342=Create/modify his own user information -Permission343=Modify his own password -Permission344=Modify its own permissions -Permission351=Read groups -Permission352=Read groups permissions -Permission353=Create/modify groups -Permission354=Delete or disable groups -Permission358=Export users -Permission401=Read discounts -Permission402=Create/modify discounts -Permission403=Validate discounts -Permission404=Delete discounts -Permission430=Use Debug Bar -Permission511=Read salaries and payments (yours and subordinates) -Permission512=Create/modify salaries and payments -Permission514=Delete salaries and payments -Permission517=Read salaries and payments everybody -Permission519=Export salaries -Permission520=Read Loans -Permission522=Create/modify loans -Permission524=Delete loans -Permission525=Access loan calculator -Permission527=Export loans -Permission531=Read services -Permission532=Create/modify services -Permission534=Delete services -Permission536=See/manage hidden services -Permission538=Export services -Permission561=Read payment orders by credit transfer -Permission562=Create/modify payment order by credit transfer -Permission563=Send/Transmit payment order by credit transfer -Permission564=Record Debits/Rejections of credit transfer -Permission601=Read stickers -Permission602=Create/modify stickers -Permission609=Delete stickers -Permission650=Read Bills of Materials -Permission651=Create/Update Bills of Materials -Permission652=Delete Bills of Materials -Permission660=Read Manufacturing Order (MO) -Permission661=Create/Update Manufacturing Order (MO) -Permission662=Delete Manufacturing Order (MO) -Permission701=Read donations -Permission702=Create/modify donations -Permission703=Delete donations -Permission771=Read expense reports (yours and your subordinates) -Permission772=Create/modify expense reports -Permission773=Delete expense reports -Permission774=Read all expense reports (even for user not subordinates) -Permission775=Approve expense reports -Permission776=Pay expense reports -Permission777=Read expense reports of everybody -Permission778=Create/modify expense reports of everybody -Permission779=Export expense reports -Permission1001=Read stocks -Permission1002=Create/modify warehouses -Permission1003=Delete warehouses -Permission1004=Read stock movements -Permission1005=Create/modify stock movements -Permission1101=Read delivery receipts -Permission1102=Create/modify delivery receipts -Permission1104=Validate delivery receipts -Permission1109=Delete delivery receipts -Permission1121=Read supplier proposals -Permission1122=Create/modify supplier proposals -Permission1123=Validate supplier proposals -Permission1124=Send supplier proposals -Permission1125=Delete supplier proposals -Permission1126=Close supplier price requests -Permission1181=Read suppliers -Permission1182=Read purchase orders -Permission1183=Create/modify purchase orders -Permission1184=Validate purchase orders -Permission1185=Approve purchase orders -Permission1186=Order purchase orders -Permission1187=Acknowledge receipt of purchase orders -Permission1188=Delete purchase orders -Permission1189=Check/Uncheck a purchase order reception -Permission1190=Approve (second approval) purchase orders -Permission1191=Export supplier orders and their attributes -Permission1201=Get result of an export -Permission1202=Create/Modify an export -Permission1231=Read vendor invoices -Permission1232=Create/modify vendor invoices -Permission1233=Validate vendor invoices -Permission1234=Delete vendor invoices -Permission1235=Send vendor invoices by email -Permission1236=Export vendor invoices, attributes and payments -Permission1237=Export purchase orders and their details -Permission1251=Run mass imports of external data into database (data load) -Permission1321=Export customer invoices, attributes and payments -Permission1322=Reopen a paid bill -Permission1421=Export sales orders and attributes -Permission1521=Read documents -Permission1522=Delete documents -Permission2401=Read actions (events or tasks) linked to his user account (if owner of event or just assigned to) -Permission2402=Create/modify actions (events or tasks) linked to his user account (if owner of event) -Permission2403=Delete actions (events or tasks) linked to his user account (if owner of event) -Permission2411=Read actions (events or tasks) of others -Permission2412=Create/modify actions (events or tasks) of others -Permission2413=Delete actions (events or tasks) of others -Permission2414=Export actions/tasks of others -Permission2501=Read/Download documents -Permission2502=Download documents -Permission2503=Submit or delete documents -Permission2515=Setup documents directories -Permission2801=Use FTP client in read mode (browse and download only) -Permission2802=Use FTP client in write mode (delete or upload files) -Permission3200=Read archived events and fingerprints -Permission3301=Generate new modules -Permission4001=See employees -Permission4002=Create employees -Permission4003=Delete employees -Permission4004=Export employees -Permission10001=Read website content -Permission10002=Create/modify website content (html and javascript content) -Permission10003=Create/modify website content (dynamic php code). Dangerous, must be reserved to restricted developers. -Permission10005=Delete website content -Permission20001=Read leave requests (your leave and those of your subordinates) -Permission20002=Create/modify your leave requests (your leave and those of your subordinates) -Permission20003=Delete leave requests -Permission20004=Read all leave requests (even of user not subordinates) -Permission20005=Create/modify leave requests for everybody (even of user not subordinates) -Permission20006=Admin leave requests (setup and update balance) -Permission20007=Approve leave requests -Permission23001=Read Scheduled job -Permission23002=Create/update Scheduled job -Permission23003=Delete Scheduled job -Permission23004=Execute Scheduled job -Permission50101=Use Point of Sale (SimplePOS) -Permission50151=Use Point of Sale (TakePOS) -Permission50152=Edit sales lines -Permission50153=Edit ordered sales lines -Permission50201=Read transactions -Permission50202=Import transactions -Permission50330=Read objects of Zapier -Permission50331=Create/Update objects of Zapier -Permission50332=Delete objects of Zapier -Permission50401=Bind products and invoices with accounting accounts -Permission50411=Read operations in ledger -Permission50412=Write/Edit operations in ledger -Permission50414=Delete operations in ledger -Permission50415=Delete all operations by year and journal in ledger -Permission50418=Export operations of the ledger -Permission50420=Report and export reports (turnover, balance, journals, ledger) -Permission50430=Define fiscal periods. Validate transactions and close fiscal periods. -Permission50440=Manage chart of accounts, setup of accountancy -Permission51001=Read assets -Permission51002=Create/Update assets -Permission51003=Delete assets -Permission51005=Setup types of asset -Permission54001=Print -Permission55001=Read polls -Permission55002=Create/modify polls -Permission59001=Read commercial margins -Permission59002=Define commercial margins -Permission59003=Read every user margin -Permission63001=Read resources -Permission63002=Create/modify resources -Permission63003=Delete resources -Permission63004=Link resources to agenda events -Permission64001=Allow direct printing -Permission67000=Allow printing of receipts -Permission68001=Read intracomm report -Permission68002=Create/modify intracomm report -Permission68004=Delete intracomm report -Permission941601=Read receipts -Permission941602=Create and modify receipts -Permission941603=Validate receipts -Permission941604=Send receipts by email -Permission941605=Export receipts -Permission941606=Delete receipts -DictionaryCompanyType=Third-party types -DictionaryCompanyJuridicalType=Third-party legal entities -DictionaryProspectLevel=Prospect potential level for companies -DictionaryProspectContactLevel=Prospect potential level for contacts -DictionaryCanton=States/Provinces -DictionaryRegion=Regions -DictionaryCountry=Countries -DictionaryCurrency=Currencies -DictionaryCivility=Honorific titles -DictionaryActions=Types of agenda events -DictionarySocialContributions=Types of social or fiscal taxes -DictionaryVAT=VAT Rates or Sales Tax Rates -DictionaryRevenueStamp=Amount of tax stamps -DictionaryPaymentConditions=Payment Terms -DictionaryPaymentModes=Payment Modes -DictionaryTypeContact=Contact/Address types -DictionaryTypeOfContainer=Website - Type of website pages/containers -DictionaryEcotaxe=Ecotax (WEEE) -DictionaryPaperFormat=Paper formats -DictionaryFormatCards=Card formats -DictionaryFees=Expense report - Types of expense report lines -DictionarySendingMethods=Shipping methods -DictionaryStaff=Number of Employees -DictionaryAvailability=Delivery delay DictionaryOrderMethods=Ordering methods -DictionarySource=Origin of proposals/orders -DictionaryAccountancyCategory=Personalized groups for reports -DictionaryAccountancysystem=Models for chart of accounts -DictionaryAccountancyJournal=Accounting journals -DictionaryEMailTemplates=Email Templates -DictionaryUnits=Units -DictionaryMeasuringUnits=Measuring Units -DictionarySocialNetworks=Social Networks -DictionaryProspectStatus=Prospect status for companies -DictionaryProspectContactStatus=Prospect status for contacts -DictionaryHolidayTypes=Leave - Types of leave -DictionaryOpportunityStatus=Lead status for project/lead -DictionaryExpenseTaxCat=Expense report - Transportation categories -DictionaryExpenseTaxRange=Expense report - Range by transportation category -DictionaryTransportMode=Intracomm report - Transport mode -DictionaryBatchStatus=Product lot/serial Quality Control status -TypeOfUnit=Type of unit -SetupSaved=Setup saved -SetupNotSaved=Setup not saved -BackToModuleList=Back to Module list -BackToDictionaryList=Back to Dictionaries list -TypeOfRevenueStamp=Type of tax stamp -VATManagement=Sales Tax Management -VATIsUsedDesc=By default when creating prospects, invoices, orders etc. the Sales Tax rate follows the active standard rule:
    If the seller is not subject to Sales tax, then Sales tax defaults to 0. End of rule.
    If the (seller's country = buyer's country), then the Sales tax by default equals the Sales tax of the product in the seller's country. End of rule.
    If the seller and buyer are both in the European Community and goods are transport-related products (haulage, shipping, airline), the default VAT is 0. This rule is dependant on the seller's country - please consult with your accountant. The VAT should be paid by the buyer to the customs office in their country and not to the seller. End of rule.
    If the seller and buyer are both in the European Community and the buyer is not a company (with a registered intra-Community VAT number) then the VAT defaults to the VAT rate of the seller's country. End of rule.
    If the seller and buyer are both in the European Community and the buyer is a company (with a registered intra-Community VAT number), then the VAT is 0 by default. End of rule.
    In any other case the proposed default is Sales tax=0. End of rule. -VATIsNotUsedDesc=By default the proposed Sales tax is 0 which can be used for cases like associations, individuals or small companies. -VATIsUsedExampleFR=In France, it means companies or organizations having a real fiscal system (Simplified real or normal real). A system in which VAT is declared. -VATIsNotUsedExampleFR=In France, it means associations that are non Sales tax declared or companies, organizations or liberal professions that have chosen the micro enterprise fiscal system (Sales tax in franchise) and paid a franchise Sales tax without any Sales tax declaration. This choice will display the reference "Non applicable Sales tax - art-293B of CGI" on invoices. -##### Local Taxes ##### -TypeOfSaleTaxes=Type of sales tax -LTRate=Rate -LocalTax1IsNotUsed=Do not use second tax -LocalTax1IsUsedDesc=Use a second type of tax (other than first one) -LocalTax1IsNotUsedDesc=Do not use other type of tax (other than first one) -LocalTax1Management=Second type of tax -LocalTax1IsUsedExample= -LocalTax1IsNotUsedExample= -LocalTax2IsNotUsed=Do not use third tax -LocalTax2IsUsedDesc=Use a third type of tax (other than first one) -LocalTax2IsNotUsedDesc=Do not use other type of tax (other than first one) -LocalTax2Management=Third type of tax -LocalTax2IsUsedExample= -LocalTax2IsNotUsedExample= -LocalTax1ManagementES=RE Management -LocalTax1IsUsedDescES=The RE rate by default when creating prospects, invoices, orders etc. follow the active standard rule:
    If the buyer is not subjected to RE, RE by default=0. End of rule.
    If the buyer is subjected to RE then the RE by default. End of rule.
    -LocalTax1IsNotUsedDescES=By default the proposed RE is 0. End of rule. -LocalTax1IsUsedExampleES=In Spain they are professionals subject to some specific sections of the Spanish IAE. -LocalTax1IsNotUsedExampleES=In Spain they are professional and societies and subject to certain sections of the Spanish IAE. -LocalTax2ManagementES=IRPF Management -LocalTax2IsUsedDescES=The IRPF rate by default when creating prospects, invoices, orders etc. follow the active standard rule:
    If the seller is not subjected to IRPF, then IRPF by default=0. End of rule.
    If the seller is subjected to IRPF then the IRPF by default. End of rule.
    -LocalTax2IsNotUsedDescES=By default the proposed IRPF is 0. End of rule. -LocalTax2IsUsedExampleES=In Spain, freelancers and independent professionals who provide services and companies who have chosen the tax system of modules. -LocalTax2IsNotUsedExampleES=In Spain they are businesses not subject to tax system of modules. -RevenueStampDesc=The "tax stamp" or "revenue stamp" is a fixed tax you per invoice (It does not depend on amount of invoice). It can also be a percent tax but using the second or third type of tax is better for percent taxes as tax stamps does not provide any reporting. Only few countries uses this type of tax. -UseRevenueStamp=Use a tax stamp -UseRevenueStampExample=The value of tax stamp is defined by default into the setup of dictionaries (%s - %s - %s) -CalcLocaltax=Reports on local taxes -CalcLocaltax1=Sales - Purchases -CalcLocaltax1Desc=Local Taxes reports are calculated with the difference between localtaxes sales and localtaxes purchases -CalcLocaltax2=Purchases -CalcLocaltax2Desc=Local Taxes reports are the total of localtaxes purchases -CalcLocaltax3=Sales -CalcLocaltax3Desc=Local Taxes reports are the total of localtaxes sales -NoLocalTaxXForThisCountry=According to the setup of taxes (See %s - %s - %s), your country does not need to use such type of tax -LabelUsedByDefault=Label used by default if no translation can be found for code -LabelOnDocuments=Label on documents -LabelOrTranslationKey=Label or translation key -ValueOfConstantKey=Value of a configuration constant -ConstantIsOn=Option %s is on -NbOfDays=No. of days -AtEndOfMonth=At end of month -CurrentNext=Current/Next -Offset=Offset -AlwaysActive=Always active -Upgrade=Upgrade -MenuUpgrade=Upgrade / Extend -AddExtensionThemeModuleOrOther=Deploy/install external app/module -WebServer=Web server -DocumentRootServer=Web server's root directory -DataRootServer=Data files directory -IP=IP -Port=Port -VirtualServerName=Virtual server name -OS=OS -PhpWebLink=Web-Php link -Server=Server -Database=Database -DatabaseServer=Database host -DatabaseName=Database name -DatabasePort=Database port -DatabaseUser=Database user -DatabasePassword=Database password -Tables=Tables -TableName=Table name -NbOfRecord=No. of records -Host=Server -DriverType=Driver type -SummarySystem=System information summary -SummaryConst=List of all Dolibarr setup parameters -MenuCompanySetup=Company/Organization -DefaultMenuManager= Standard menu manager -DefaultMenuSmartphoneManager=Smartphone menu manager -Skin=Skin theme -DefaultSkin=Default skin theme -MaxSizeList=Max length for list -DefaultMaxSizeList=Default max length for lists -DefaultMaxSizeShortList=Default max length for short lists (i.e. in customer card) -MessageOfDay=Message of the day -MessageLogin=Login page message -LoginPage=Login page -BackgroundImageLogin=Background image -PermanentLeftSearchForm=Permanent search form on left menu -DefaultLanguage=Default language -EnableMultilangInterface=Enable multilanguage support for customer or vendor relationships -EnableShowLogo=Show the company logo in the menu -CompanyInfo=Company/Organization -CompanyIds=Company/Organization identities -CompanyName=Name -CompanyAddress=Address -CompanyZip=Zip -CompanyTown=Town -CompanyCountry=Country -CompanyCurrency=Main currency -CompanyObject=Object of the company -IDCountry=ID country -Logo=Logo -LogoDesc=Main logo of company. Will be used into generated documents (PDF, ...) -LogoSquarred=Logo (squarred) -LogoSquarredDesc=Must be a squarred icon (width = height). This logo will be used as the favorite icon or other need like for the top menu bar (if not disabled into display setup). -DoNotSuggestPaymentMode=Do not suggest -NoActiveBankAccountDefined=No active bank account defined -OwnerOfBankAccount=Owner of bank account %s -BankModuleNotActive=Bank accounts module not enabled -ShowBugTrackLink=Define the link "%s" (empty to not display this link, 'github' for the link to the Dolibarr project or define directly an url 'https://...') -Alerts=Alerts -DelaysOfToleranceBeforeWarning=Delay before displaying a warning alert for: -DelaysOfToleranceDesc=Set the delay before an alert icon %s is shown onscreen for the late element. -Delays_MAIN_DELAY_ACTIONS_TODO=Planned events (agenda events) not completed -Delays_MAIN_DELAY_PROJECT_TO_CLOSE=Project not closed in time -Delays_MAIN_DELAY_TASKS_TODO=Planned task (project tasks) not completed -Delays_MAIN_DELAY_ORDERS_TO_PROCESS=Order not processed -Delays_MAIN_DELAY_SUPPLIER_ORDERS_TO_PROCESS=Purchase order not processed -Delays_MAIN_DELAY_PROPALS_TO_CLOSE=Proposal not closed -Delays_MAIN_DELAY_PROPALS_TO_BILL=Proposal not billed -Delays_MAIN_DELAY_NOT_ACTIVATED_SERVICES=Service to activate -Delays_MAIN_DELAY_RUNNING_SERVICES=Expired service -Delays_MAIN_DELAY_SUPPLIER_BILLS_TO_PAY=Unpaid vendor invoice -Delays_MAIN_DELAY_CUSTOMER_BILLS_UNPAYED=Unpaid customer invoice -Delays_MAIN_DELAY_TRANSACTIONS_TO_CONCILIATE=Pending bank reconciliation -Delays_MAIN_DELAY_MEMBERS=Delayed membership fee -Delays_MAIN_DELAY_CHEQUES_TO_DEPOSIT=Check deposit not done -Delays_MAIN_DELAY_EXPENSEREPORTS=Expense report to approve -Delays_MAIN_DELAY_HOLIDAYS=Leave requests to approve -SetupDescription1=Before starting to use Dolibarr some initial parameters must be defined and modules enabled/configured. -SetupDescription2=The following two sections are mandatory (the two first entries in the Setup menu): -SetupDescription3=%s -> %s

    Basic parameters used to customize the default behavior of your application (e.g for country-related features). -SetupDescription4=%s -> %s

    This software is a suite of many modules/applications. The modules related to your needs must be enabled and configured. Menu entries will appears with the activation of these modules. -SetupDescription5=Other Setup menu entries manage optional parameters. -SetupDescriptionLink=%s - %s -SetupDescription3b=Basic parameters used to customize the default behavior of your application (e.g for country-related features). -SetupDescription4b=This software is a suite of many modules/applications. The modules related to your needs must be enabled and configured. Menu entries will appears with the activation of these modules. -AuditedSecurityEvents=Security events that are audited -NoSecurityEventsAreAduited=No security events are audited. You can enable them from menu %s -Audit=Security events -InfoDolibarr=About Dolibarr -InfoBrowser=About Browser -InfoOS=About OS -InfoWebServer=About Web Server -InfoDatabase=About Database -InfoPHP=About PHP -InfoPerf=About Performances -InfoSecurity=About Security -BrowserName=Browser name -BrowserOS=Browser OS -ListOfSecurityEvents=List of Dolibarr security events -SecurityEventsPurged=Security events purged -LogEventDesc=Enable logging for specific security events. Administrators the log via menu %s - %s. Warning, this feature can generate a large amount of data in the database. -AreaForAdminOnly=Setup parameters can be set by administrator users only. -SystemInfoDesc=System information is miscellaneous technical information you get in read only mode and visible for administrators only. -SystemAreaForAdminOnly=This area is available to administrator users only. Dolibarr user permissions cannot change this restriction. -CompanyFundationDesc=Edit the information of your company/organization. Click on "%s" button at the bottom of the page when done. -AccountantDesc=If you have an external accountant/bookkeeper, you can edit here its information. -AccountantFileNumber=Accountant code -DisplayDesc=Parameters affecting the look and behaviour of Dolibarr can be modified here. -AvailableModules=Available app/modules -ToActivateModule=To activate modules, go on setup Area (Home->Setup->Modules). -SessionTimeOut=Time out for session -SessionExplanation=This number guarantees that the session will never expire before this delay, if the session cleaner is done by Internal PHP session cleaner (and nothing else). Internal PHP session cleaner does not guarantee that the session will expire after this delay. It will expire, after this delay, and when the session cleaner is run, so every %s/%s access, but only during access made by other sessions (if value is 0, it means clearing of session is done only by an external process).
    Note: on some servers with an external session cleaning mechanism (cron under debian, ubuntu ...), the sessions can be destroyed after a period defined by an external setup, no matter what the value entered here is. -SessionsPurgedByExternalSystem=Sessions on this server seems to be cleaned by an external mechanism (cron under debian, ubuntu ...), probably every %s seconds (= value of parameter session.gc_maxlifetime), so changing the value here has no effect. You must ask the server administrator to change session delay. -TriggersAvailable=Available triggers -TriggersDesc=Triggers are files that will modify the behavior of Dolibarr workflow once copied into the directory htdocs/core/triggers. They realize new actions, activated on Dolibarr events (new company creation, invoice validation, ...). -TriggerDisabledByName=Triggers in this file are disabled by the -NORUN suffix in their name. -TriggerDisabledAsModuleDisabled=Triggers in this file are disabled as module %s is disabled. -TriggerAlwaysActive=Triggers in this file are always active, whatever are the activated Dolibarr modules. -TriggerActiveAsModuleActive=Triggers in this file are active as module %s is enabled. -GeneratedPasswordDesc=Choose the method to be used for auto-generated passwords. -DictionaryDesc=Insert all reference data. You can add your values to the default. -ConstDesc=This page allows you to edit (override) parameters not available in other pages. These are mostly reserved parameters for developers/advanced troubleshooting only. -MiscellaneousDesc=All other security related parameters are defined here. -LimitsSetup=Limits/Precision setup -LimitsDesc=You can define limits, precisions and optimizations used by Dolibarr here -MAIN_MAX_DECIMALS_UNIT=Max. decimals for unit prices -MAIN_MAX_DECIMALS_TOT=Max. decimals for total prices -MAIN_MAX_DECIMALS_SHOWN=Max. decimals for prices shown on screen. Add an ellipsis ... after this parameter (e.g. "2...") if you want to see "..." suffixed to the truncated price. -MAIN_ROUNDING_RULE_TOT=Step of rounding range (for countries where rounding is done on something other than base 10. For example, put 0.05 if rounding is done by 0.05 steps) -UnitPriceOfProduct=Net unit price of a product -TotalPriceAfterRounding=Total price (excl/vat/incl tax) after rounding -ParameterActiveForNextInputOnly=Parameter effective for next input only -NoEventOrNoAuditSetup=No security event has been logged. This is normal if Audit has not been enabled in the "Setup - Security - Events" page. -NoEventFoundWithCriteria=No security event has been found for this search criteria. -SeeLocalSendMailSetup=See your local sendmail setup -BackupDesc=A complete backup of a Dolibarr installation requires two steps. -BackupDesc2=Backup the contents of the "documents" directory (%s) containing all uploaded and generated files. This will also include all the dump files generated in Step 1. This operation may last several minutes. -BackupDesc3=Backup the structure and contents of your database (%s) into a dump file. For this, you can use the following assistant. -BackupDescX=The archived directory should be stored in a secure place. -BackupDescY=The generated dump file should be stored in a secure place. -BackupPHPWarning=Backup cannot be guaranteed with this method. Previous one recommended. -RestoreDesc=To restore a Dolibarr backup, two steps are required. -RestoreDesc2=Restore the backup file (zip file for example) of the "documents" directory to a new Dolibarr installation or into this current documents directory (%s). -RestoreDesc3=Restore the database structure and data from a backup dump file into the database of the new Dolibarr installation or into the database of this current installation (%s). Warning, once the restore is complete, you must use a login/password, that existed from the backup time/installation to connect again.
    To restore a backup database into this current installation, you can follow this assistant. -RestoreMySQL=MySQL import -ForcedToByAModule=This rule is forced to %s by an activated module -ValueIsForcedBySystem=This value is forced by the system. You can't change it. -PreviousDumpFiles=Existing backup files -PreviousArchiveFiles=Existing archive files -WeekStartOnDay=First day of the week -RunningUpdateProcessMayBeRequired=Running the upgrade process seems to be required (Program version %s differs from Database version %s) -YouMustRunCommandFromCommandLineAfterLoginToUser=You must run this command from command line after login to a shell with user %s or you must add -W option at end of command line to provide %s password. -YourPHPDoesNotHaveSSLSupport=SSL functions not available in your PHP -DownloadMoreSkins=More skins to download -SimpleNumRefModelDesc=Returns the reference number in the format %syymm-nnnn where yy is the year, mm is the month and nnnn is a sequential auto-incrementing number with no reset -SimpleNumRefNoDateModelDesc=Returns the reference number in the format %s-nnnn where nnnn is a sequential auto-incrementing number with no reset -ShowProfIdInAddress=Show professional ID with addresses -ShowVATIntaInAddress=Hide intra-Community VAT number -TranslationUncomplete=Partial translation -MAIN_DISABLE_METEO=Disable meteorological view -MeteoStdMod=Standard mode -MeteoStdModEnabled=Standard mode enabled -MeteoPercentageMod=Percentage mode -MeteoPercentageModEnabled=Percentage mode enabled -MeteoUseMod=Click to use %s -TestLoginToAPI=Test login to API -ProxyDesc=Some features of Dolibarr require internet access. Define here the internet connection parameters such as access through a proxy server if necessary. -ExternalAccess=External/Internet Access -MAIN_PROXY_USE=Use a proxy server (otherwise access is direct to the internet) -MAIN_PROXY_HOST=Proxy server: Name/Address -MAIN_PROXY_PORT=Proxy server: Port -MAIN_PROXY_USER=Proxy server: Login/User -MAIN_PROXY_PASS=Proxy server: Password -DefineHereComplementaryAttributes=Define any additional / custom attributes that must be added to: %s -ExtraFields=Complementary attributes -ExtraFieldsLines=Complementary attributes (lines) -ExtraFieldsLinesRec=Complementary attributes (templates invoices lines) -ExtraFieldsSupplierOrdersLines=Complementary attributes (order lines) -ExtraFieldsSupplierInvoicesLines=Complementary attributes (invoice lines) -ExtraFieldsThirdParties=Complementary attributes (third party) -ExtraFieldsContacts=Complementary attributes (contacts/address) -ExtraFieldsMember=Complementary attributes (member) -ExtraFieldsMemberType=Complementary attributes (member type) -ExtraFieldsCustomerInvoices=Complementary attributes (invoices) -ExtraFieldsCustomerInvoicesRec=Complementary attributes (templates invoices) -ExtraFieldsSupplierOrders=Complementary attributes (orders) -ExtraFieldsSupplierInvoices=Complementary attributes (invoices) -ExtraFieldsProject=Complementary attributes (projects) -ExtraFieldsProjectTask=Complementary attributes (tasks) -ExtraFieldsSalaries=Complementary attributes (salaries) -ExtraFieldHasWrongValue=Attribute %s has a wrong value. -AlphaNumOnlyLowerCharsAndNoSpace=only alphanumericals and lower case characters without space -SendmailOptionNotComplete=Warning, on some Linux systems, to send email from your email, sendmail execution setup must contains option -ba (parameter mail.force_extra_parameters into your php.ini file). If some recipients never receive emails, try to edit this PHP parameter with mail.force_extra_parameters = -ba). -PathToDocuments=Path to documents -PathDirectory=Directory -SendmailOptionMayHurtBuggedMTA=Feature to send mails using method "PHP mail direct" will generate a mail message that might not be parsed correctly by some receiving mail servers. The result is that some mails can't be read by people hosted by those bugged platforms. This is the case for some Internet providers (Ex: Orange in France). This is not a problem with Dolibarr or PHP but with the receiving mail server. You can however add an option MAIN_FIX_FOR_BUGGED_MTA to 1 in Setup - Other to modify Dolibarr to avoid this. However, you may experience problems with other servers that strictly use the SMTP standard. The other solution (recommended) is to use the method "SMTP socket library" which has no disadvantages. -TranslationSetup=Setup of translation -TranslationKeySearch=Search a translation key or string -TranslationOverwriteKey=Overwrite a translation string -TranslationDesc=How to set the display language:
    * Default/Systemwide: menu Home -> Setup -> Display
    * Per user: Click on the username at the top of the screen and modify the User Display Setup tab on the user card. -TranslationOverwriteDesc=You can also override strings filling the following table. Choose your language from "%s" dropdown, insert the translation key string into "%s" and your new translation into "%s" -TranslationOverwriteDesc2=You can use the other tab to help you know which translation key to use -TranslationString=Translation string -CurrentTranslationString=Current translation string -WarningAtLeastKeyOrTranslationRequired=A search criteria is required at least for key or translation string -NewTranslationStringToShow=New translation string to show -OriginalValueWas=The original translation is overwritten. Original value was:

    %s -TransKeyWithoutOriginalValue=You forced a new translation for the translation key '%s' that does not exist in any language files -TitleNumberOfActivatedModules=Activated modules -TotalNumberOfActivatedModules=Activated modules: %s / %s -YouMustEnableOneModule=You must at least enable 1 module -ClassNotFoundIntoPathWarning=Class %s not found in PHP path -YesInSummer=Yes in summer -OnlyFollowingModulesAreOpenedToExternalUsers=Note, only the following modules are available to external users (irrespective of the permissions of such users) and only if permissions are granted:
    -SuhosinSessionEncrypt=Session storage encrypted by Suhosin -ConditionIsCurrently=Condition is currently %s -YouUseBestDriver=You use driver %s which is the best driver currently available. -YouDoNotUseBestDriver=You use driver %s but driver %s is recommended. -NbOfObjectIsLowerThanNoPb=You have only %s %s in the database. This does not require any particular optimization. -ComboListOptim=Combo list loading optimization -SearchOptim=Search optimization -YouHaveXObjectUseComboOptim=You have %s %s in the database. You can go into setup of module to enable loading of combo list on key pressed event. -YouHaveXObjectUseSearchOptim=You have %s %s in the database. You can add the constant %s to 1 in Home-Setup-Other. -YouHaveXObjectUseSearchOptimDesc=This limits the search to the beginning of strings which makes it possible for the database to use indexes and you should get an immediate response. -YouHaveXObjectAndSearchOptimOn=You have %s %s in the database and constant %s is set to %s in Home-Setup-Other. -BrowserIsOK=You are using the %s web browser. This browser is ok for security and performance. -BrowserIsKO=You are using the %s web browser. This browser is known to be a bad choice for security, performance and reliability. We recommend using Firefox, Chrome, Opera or Safari. -PHPModuleLoaded=PHP component %s is loaded -PreloadOPCode=Preloaded OPCode is used -AddRefInList=Display Customer/Vendor ref. info list (select list or combobox) and most of hyperlink.
    Third Parties will appear with a name format of "CC12345 - SC45678 - The Big Company corp." instead of "The Big Company corp". -AddAdressInList=Display Customer/Vendor adress info list (select list or combobox)
    Third Parties will appear with a name format of "The Big Company corp. - 21 jump street 123456 Big town - USA" instead of "The Big Company corp". -AddEmailPhoneTownInContactList=Display Contact email (or phones if not defined) and town info list (select list or combobox)
    Contacts will appear with a name format of "Dupond Durand - dupond.durand@email.com - Paris" or "Dupond Durand - 06 07 59 65 66 - Paris" instead of "Dupond Durand". -AskForPreferredShippingMethod=Ask for preferred shipping method for Third Parties. -FieldEdition=Edition of field %s -FillThisOnlyIfRequired=Example: +2 (fill only if timezone offset problems are experienced) -GetBarCode=Get barcode -NumberingModules=Numbering models -DocumentModules=Document models -##### Module password generation -PasswordGenerationStandard=Return a password generated according to internal Dolibarr algorithm: %s characters containing shared numbers and characters in lowercase. -PasswordGenerationNone=Do not suggest a generated password. Password must be typed in manually. -PasswordGenerationPerso=Return a password according to your personally defined configuration. -SetupPerso=According to your configuration -PasswordPatternDesc=Password pattern description -##### Users setup ##### -RuleForGeneratedPasswords=Rules to generate and validate passwords -DisableForgetPasswordLinkOnLogonPage=Do not show the "Password Forgotten" link on the Login page -UsersSetup=Users module setup -UserMailRequired=Email required to create a new user -UserHideInactive=Hide inactive users from all combo lists of users (Not recommended: this may means you won't be able to filter or search on old users on some pages) -UsersDocModules=Document templates for documents generated from user record -GroupsDocModules=Document templates for documents generated from a group record -##### HRM setup ##### -HRMSetup=HRM module setup -##### Company setup ##### -CompanySetup=Companies module setup -CompanyCodeChecker=Options for automatic generation of customer/vendor codes -AccountCodeManager=Options for automatic generation of customer/vendor accounting codes -NotificationsDesc=Email notifications can be sent automatically for some Dolibarr events.
    Recipients of notifications can be defined: -NotificationsDescUser=* per user, one user at a time. -NotificationsDescContact=* per third-party contacts (customers or vendors), one contact at a time. -NotificationsDescGlobal=* or by setting global email addresses in this setup page. -ModelModules=Document Templates -DocumentModelOdt=Generate documents from OpenDocument templates (.ODT / .ODS files from LibreOffice, OpenOffice, KOffice, TextEdit,...) -WatermarkOnDraft=Watermark on draft document -JSOnPaimentBill=Activate feature to autofill payment lines on payment form -CompanyIdProfChecker=Rules for Professional IDs -MustBeUnique=Must be unique? -MustBeMandatory=Mandatory to create third parties (if VAT number or type of company defined) ? -MustBeInvoiceMandatory=Mandatory to validate invoices? -TechnicalServicesProvided=Technical services provided -#####DAV ##### -WebDAVSetupDesc=This is the link to access the WebDAV directory. It contains a "public" dir open to any user knowing the URL (if public directory access allowed) and a "private" directory that needs an existing login account/password for access. -WebDavServer=Root URL of %s server: %s -##### Webcal setup ##### -WebCalUrlForVCalExport=An export link to %s format is available at following link: %s -##### Invoices ##### -BillsSetup=Invoices module setup -BillsNumberingModule=Invoices and credit notes numbering model -BillsPDFModules=Invoice documents models -BillsPDFModulesAccordindToInvoiceType=Invoice documents models according to invoice type -PaymentsPDFModules=Payment documents models -ForceInvoiceDate=Force invoice date to validation date -SuggestedPaymentModesIfNotDefinedInInvoice=Suggested payments mode on invoice by default if not defined on the invoice -SuggestPaymentByRIBOnAccount=Suggest payment by withdrawal on account -SuggestPaymentByChequeToAddress=Suggest payment by check to -FreeLegalTextOnInvoices=Free text on invoices -WatermarkOnDraftInvoices=Watermark on draft invoices (none if empty) -PaymentsNumberingModule=Payments numbering model -SuppliersPayment=Vendor payments -SupplierPaymentSetup=Vendor payments setup -##### Proposals ##### -PropalSetup=Commercial proposals module setup -ProposalsNumberingModules=Commercial proposal numbering models -ProposalsPDFModules=Commercial proposal documents models -SuggestedPaymentModesIfNotDefinedInProposal=Suggested payments mode on proposal by default if not defined on the proposal -FreeLegalTextOnProposal=Free text on commercial proposals -WatermarkOnDraftProposal=Watermark on draft commercial proposals (none if empty) -BANK_ASK_PAYMENT_BANK_DURING_PROPOSAL=Ask for bank account destination of proposal -##### SupplierProposal ##### -SupplierProposalSetup=Price requests suppliers module setup -SupplierProposalNumberingModules=Price requests suppliers numbering models -SupplierProposalPDFModules=Price requests suppliers documents models -FreeLegalTextOnSupplierProposal=Free text on price requests suppliers -WatermarkOnDraftSupplierProposal=Watermark on draft price requests suppliers (none if empty) -BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_PROPOSAL=Ask for bank account destination of price request -WAREHOUSE_ASK_WAREHOUSE_DURING_ORDER=Ask for Warehouse Source for order -##### Suppliers Orders ##### -BANK_ASK_PAYMENT_BANK_DURING_SUPPLIER_ORDER=Ask for bank account destination of purchase order -##### Orders ##### -SuggestedPaymentModesIfNotDefinedInOrder=Suggested payments mode on sale order by default if not defined on the order -OrdersSetup=Sales Orders management setup -OrdersNumberingModules=Orders numbering models -OrdersModelModule=Order documents models -FreeLegalTextOnOrders=Free text on orders -WatermarkOnDraftOrders=Watermark on draft orders (none if empty) -ShippableOrderIconInList=Add an icon in Orders list which indicate if order is shippable -BANK_ASK_PAYMENT_BANK_DURING_ORDER=Ask for bank account destination of order -##### Interventions ##### -InterventionsSetup=Interventions module setup -FreeLegalTextOnInterventions=Free text on intervention documents -FicheinterNumberingModules=Intervention numbering models -TemplatePDFInterventions=Intervention card documents models -WatermarkOnDraftInterventionCards=Watermark on intervention card documents (none if empty) -##### Contracts ##### -ContractsSetup=Contracts/Subscriptions module setup -ContractsNumberingModules=Contracts numbering modules -TemplatePDFContracts=Contracts documents models -FreeLegalTextOnContracts=Free text on contracts -WatermarkOnDraftContractCards=Watermark on draft contracts (none if empty) -##### Members ##### -MembersSetup=Members module setup -MemberMainOptions=Main options -AdherentLoginRequired= Manage a Login for each member -AdherentMailRequired=Email required to create a new member -MemberSendInformationByMailByDefault=Checkbox to send mail confirmation to members (validation or new subscription) is on by default -MemberCreateAnExternalUserForSubscriptionValidated=Create an external user login for each new member subscription validated -VisitorCanChooseItsPaymentMode=Visitor can choose from available payment modes -MEMBER_REMINDER_EMAIL=Enable automatic reminder by email of expired subscriptions. Note: Module %s must be enabled and correctly setup to send reminders. -MembersDocModules=Document templates for documents generated from member record -##### LDAP setup ##### -LDAPSetup=LDAP Setup -LDAPGlobalParameters=Global parameters -LDAPUsersSynchro=Users -LDAPGroupsSynchro=Groups -LDAPContactsSynchro=Contacts -LDAPMembersSynchro=Members -LDAPMembersTypesSynchro=Members types -LDAPSynchronization=LDAP synchronisation -LDAPFunctionsNotAvailableOnPHP=LDAP functions are not available on your PHP -LDAPToDolibarr=LDAP -> Dolibarr -DolibarrToLDAP=Dolibarr -> LDAP -LDAPNamingAttribute=Key in LDAP -LDAPSynchronizeUsers=Organization of users in LDAP -LDAPSynchronizeGroups=Organization of groups in LDAP -LDAPSynchronizeContacts=Organization of contacts in LDAP -LDAPSynchronizeMembers=Organization of foundation's members in LDAP -LDAPSynchronizeMembersTypes=Organization of foundation's members types in LDAP -LDAPPrimaryServer=Primary server -LDAPSecondaryServer=Secondary server -LDAPServerPort=Server port -LDAPServerPortExample=Default port: 389 -LDAPServerProtocolVersion=Protocol version -LDAPServerUseTLS=Use TLS LDAPServerUseTLSExample=Your LDAP server use TLS -LDAPServerDn=Server DN -LDAPAdminDn=Administrator DN -LDAPAdminDnExample=Complete DN (ex: cn=admin,dc=example,dc=com or cn=Administrator,cn=Users,dc=example,dc=com for active directory) -LDAPPassword=Administrator password -LDAPUserDn=Users' DN -LDAPUserDnExample=Complete DN (ex: ou=users,dc=example,dc=com) -LDAPGroupDn=Groups' DN -LDAPGroupDnExample=Complete DN (ex: ou=groups,dc=example,dc=com) -LDAPServerExample=Server address (ex: localhost, 192.168.0.2, ldaps://ldap.example.com/) -LDAPServerDnExample=Complete DN (ex: dc=example,dc=com) -LDAPDnSynchroActive=Users and groups synchronization -LDAPDnSynchroActiveExample=LDAP to Dolibarr or Dolibarr to LDAP synchronization -LDAPDnContactActive=Contacts' synchronization -LDAPDnContactActiveExample=Activated/Unactivated synchronization -LDAPDnMemberActive=Members' synchronization -LDAPDnMemberActiveExample=Activated/Unactivated synchronization -LDAPDnMemberTypeActive=Members types' synchronization -LDAPDnMemberTypeActiveExample=Activated/Unactivated synchronization -LDAPContactDn=Dolibarr contacts' DN -LDAPContactDnExample=Complete DN (ex: ou=contacts,dc=example,dc=com) -LDAPMemberDn=Dolibarr members DN -LDAPMemberDnExample=Complete DN (ex: ou=members,dc=example,dc=com) -LDAPMemberObjectClassList=List of objectClass -LDAPMemberObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) -LDAPMemberTypeDn=Dolibarr members types DN -LDAPMemberTypepDnExample=Complete DN (ex: ou=memberstypes,dc=example,dc=com) -LDAPMemberTypeObjectClassList=List of objectClass -LDAPMemberTypeObjectClassListExample=List of objectClass defining record attributes (ex: top,groupOfUniqueNames) -LDAPUserObjectClassList=List of objectClass -LDAPUserObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) -LDAPGroupObjectClassList=List of objectClass -LDAPGroupObjectClassListExample=List of objectClass defining record attributes (ex: top,groupOfUniqueNames) -LDAPContactObjectClassList=List of objectClass -LDAPContactObjectClassListExample=List of objectClass defining record attributes (ex: top,inetOrgPerson or top,user for active directory) -LDAPTestConnect=Test LDAP connection -LDAPTestSynchroContact=Test contacts synchronization -LDAPTestSynchroUser=Test user synchronization -LDAPTestSynchroGroup=Test group synchronization -LDAPTestSynchroMember=Test member synchronization -LDAPTestSynchroMemberType=Test member type synchronization -LDAPTestSearch= Test a LDAP search -LDAPSynchroOK=Synchronization test successful -LDAPSynchroKO=Failed synchronization test -LDAPSynchroKOMayBePermissions=Failed synchronization test. Check that the connection to the server is correctly configured and allows LDAP updates -LDAPTCPConnectOK=TCP connect to LDAP server successful (Server=%s, Port=%s) -LDAPTCPConnectKO=TCP connect to LDAP server failed (Server=%s, Port=%s) -LDAPBindOK=Connect/Authenticate to LDAP server successful (Server=%s, Port=%s, Admin=%s, Password=%s) -LDAPBindKO=Connect/Authenticate to LDAP server failed (Server=%s, Port=%s, Admin=%s, Password=%s) -LDAPSetupForVersion3=LDAP server configured for version 3 -LDAPSetupForVersion2=LDAP server configured for version 2 -LDAPDolibarrMapping=Dolibarr Mapping -LDAPLdapMapping=LDAP Mapping -LDAPFieldLoginUnix=Login (unix) -LDAPFieldLoginExample=Example: uid -LDAPFilterConnection=Search filter -LDAPFilterConnectionExample=Example: &(objectClass=inetOrgPerson) -LDAPGroupFilterExample=Example: &(objectClass=groupOfUsers) -LDAPFieldLoginSamba=Login (samba, activedirectory) -LDAPFieldLoginSambaExample=Example: samaccountname -LDAPFieldFullname=Full name -LDAPFieldFullnameExample=Example: cn -LDAPFieldPasswordNotCrypted=Password not encrypted -LDAPFieldPasswordCrypted=Password encrypted -LDAPFieldPasswordExample=Example: userPassword -LDAPFieldCommonNameExample=Example: cn -LDAPFieldName=Name -LDAPFieldNameExample=Example: sn -LDAPFieldFirstName=First name -LDAPFieldFirstNameExample=Example: givenName -LDAPFieldMail=Email address -LDAPFieldMailExample=Example: mail -LDAPFieldPhone=Professional phone number -LDAPFieldPhoneExample=Example: telephonenumber -LDAPFieldHomePhone=Personal phone number -LDAPFieldHomePhoneExample=Example: homephone -LDAPFieldMobile=Cellular phone -LDAPFieldMobileExample=Example: mobile -LDAPFieldFax=Fax number -LDAPFieldFaxExample=Example: facsimiletelephonenumber -LDAPFieldAddress=Street -LDAPFieldAddressExample=Example: street -LDAPFieldZip=Zip -LDAPFieldZipExample=Example: postalcode -LDAPFieldTown=Town -LDAPFieldTownExample=Example: l -LDAPFieldCountry=Country -LDAPFieldDescription=Description -LDAPFieldDescriptionExample=Example: description -LDAPFieldNotePublic=Public Note -LDAPFieldNotePublicExample=Example: publicnote -LDAPFieldGroupMembers= Group members -LDAPFieldGroupMembersExample= Example: uniqueMember -LDAPFieldBirthdate=Birthdate -LDAPFieldCompany=Company -LDAPFieldCompanyExample=Example: o -LDAPFieldSid=SID -LDAPFieldSidExample=Example: objectsid -LDAPFieldEndLastSubscription=Date of subscription end -LDAPFieldTitle=Job position -LDAPFieldTitleExample=Example: title -LDAPFieldGroupid=Group id -LDAPFieldGroupidExample=Exemple : gidnumber -LDAPFieldUserid=User id -LDAPFieldUseridExample=Exemple : uidnumber -LDAPFieldHomedirectory=Home directory -LDAPFieldHomedirectoryExample=Exemple : homedirectory -LDAPFieldHomedirectoryprefix=Home directory prefix -LDAPSetupNotComplete=LDAP setup not complete (go on others tabs) -LDAPNoUserOrPasswordProvidedAccessIsReadOnly=No administrator or password provided. LDAP access will be anonymous and in read only mode. -LDAPDescContact=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr contacts. -LDAPDescUsers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr users. -LDAPDescGroups=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr groups. -LDAPDescMembers=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members module. -LDAPDescMembersTypes=This page allows you to define LDAP attributes name in LDAP tree for each data found on Dolibarr members types. -LDAPDescValues=Example values are designed for OpenLDAP with following loaded schemas: core.schema, cosine.schema, inetorgperson.schema). If you use thoose values and OpenLDAP, modify your LDAP config file slapd.conf to have all thoose schemas loaded. -ForANonAnonymousAccess=For an authenticated access (for a write access for example) -PerfDolibarr=Performance setup/optimizing report -YouMayFindPerfAdviceHere=This page provides some checks or advice related to performance. -NotInstalled=Not installed. -NotSlowedDownByThis=Not slowed down by this. -NotRiskOfLeakWithThis=Not risk of leak with this. -ApplicativeCache=Applicative cache -MemcachedNotAvailable=No applicative cache found. You can enhance performance by installing a cache server Memcached and a module able to use this cache server.
    More information here http://wiki.dolibarr.org/index.php/Module_MemCached_EN.
    Note that a lot of web hosting provider does not provide such cache server. -MemcachedModuleAvailableButNotSetup=Module memcached for applicative cache found but setup of module is not complete. -MemcachedAvailableAndSetup=Module memcached dedicated to use memcached server is enabled. -OPCodeCache=OPCode cache -NoOPCodeCacheFound=No OPCode cache found. Maybe you are using an OPCode cache other than XCache or eAccelerator (good), or maybe you don't have OPCode cache (very bad). -HTTPCacheStaticResources=HTTP cache for static resources (css, img, javascript) -FilesOfTypeCached=Files of type %s are cached by HTTP server -FilesOfTypeNotCached=Files of type %s are not cached by HTTP server -FilesOfTypeCompressed=Files of type %s are compressed by HTTP server -FilesOfTypeNotCompressed=Files of type %s are not compressed by HTTP server -CacheByServer=Cache by server -CacheByServerDesc=For example using the Apache directive "ExpiresByType image/gif A2592000" -CacheByClient=Cache by browser -CompressionOfResources=Compression of HTTP responses -CompressionOfResourcesDesc=For example using the Apache directive "AddOutputFilterByType DEFLATE" -TestNotPossibleWithCurrentBrowsers=Such an automatic detection is not possible with current browsers -DefaultValuesDesc=Here you may define the default value you wish to use when creating a new record, and/or default filters or the sort order when you list records. -DefaultCreateForm=Default values (to use on forms) -DefaultSearchFilters=Default search filters -DefaultSortOrder=Default sort orders -DefaultFocus=Default focus fields -DefaultMandatory=Mandatory form fields -##### Products ##### -ProductSetup=Products module setup -ServiceSetup=Services module setup -ProductServiceSetup=Products and Services modules setup -NumberOfProductShowInSelect=Maximum number of products to show in combo select lists (0=no limit) -ViewProductDescInFormAbility=Display product descriptions in forms (otherwise shown in a tooltip popup) -DoNotAddProductDescAtAddLines=Do not add product description (from product card) on submit add lines on forms -OnProductSelectAddProductDesc=How to use the description of the products when adding a product as a line of a document -AutoFillFormFieldBeforeSubmit=Auto fill the description input field with the description of product -DoNotAutofillButAutoConcat=Do not autofill the input field with description of product. Description of the product will be concatenated to the entered description automatically. -DoNotUseDescriptionOfProdut=Description of the product will never be included into the description of lines of documents -MergePropalProductCard=Activate in product/service Attached Files tab an option to merge product PDF document to proposal PDF azur if product/service is in the proposal -ViewProductDescInThirdpartyLanguageAbility=Display products descriptions in forms in the language of the third party (otherwise in the language of the user) -UseSearchToSelectProductTooltip=Also if you have a large number of products (> 100 000), you can increase speed by setting constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. -UseSearchToSelectProduct=Wait until you press a key before loading content of product combo list (This may increase performance if you have a large number of products, but it is less convenient) -SetDefaultBarcodeTypeProducts=Default barcode type to use for products -SetDefaultBarcodeTypeThirdParties=Default barcode type to use for third parties -UseUnits=Define a unit of measure for Quantity during order, proposal or invoice lines edition -ProductCodeChecker= Module for product code generation and checking (product or service) -ProductOtherConf= Product / Service configuration -IsNotADir=is not a directory! -##### Syslog ##### -SyslogSetup=Logs module setup -SyslogOutput=Logs outputs -SyslogFacility=Facility -SyslogLevel=Level -SyslogFilename=File name and path -YouCanUseDOL_DATA_ROOT=You can use DOL_DATA_ROOT/dolibarr.log for a log file in Dolibarr "documents" directory. You can set a different path to store this file. -ErrorUnknownSyslogConstant=Constant %s is not a known Syslog constant -OnlyWindowsLOG_USER=On Windows, only the LOG_USER facility will be supported -CompressSyslogs=Compression and backup of debug log files (generated by module Log for debug) -SyslogFileNumberOfSaves=Number of backup logs to keep -ConfigureCleaningCronjobToSetFrequencyOfSaves=Configure cleaning scheduled job to set log backup frequency -##### Donations ##### -DonationsSetup=Donation module setup -DonationsReceiptModel=Template of donation receipt -##### Barcode ##### -BarcodeSetup=Barcode setup -PaperFormatModule=Print format module -BarcodeEncodeModule=Barcode encoding type -CodeBarGenerator=Barcode generator -ChooseABarCode=No generator defined -FormatNotSupportedByGenerator=Format not supported by this generator -BarcodeDescEAN8=Barcode of type EAN8 -BarcodeDescEAN13=Barcode of type EAN13 -BarcodeDescUPC=Barcode of type UPC -BarcodeDescISBN=Barcode of type ISBN -BarcodeDescC39=Barcode of type C39 -BarcodeDescC128=Barcode of type C128 -BarcodeDescDATAMATRIX=Barcode of type Datamatrix -BarcodeDescQRCODE=Barcode of type QR code -GenbarcodeLocation=Bar code generation command line tool (used by internal engine for some bar code types). Must be compatible with "genbarcode".
    For example: /usr/local/bin/genbarcode -BarcodeInternalEngine=Internal engine -BarCodeNumberManager=Manager to auto define barcode numbers -##### Prelevements ##### -WithdrawalsSetup=Setup of module Direct Debit payments -##### ExternalRSS ##### -ExternalRSSSetup=External RSS imports setup -NewRSS=New RSS Feed -RSSUrl=RSS URL -RSSUrlExample=An interesting RSS feed -##### Mailing ##### -MailingSetup=EMailing module setup -MailingEMailFrom=Sender email (From) for emails sent by emailing module -MailingEMailError=Return Email (Errors-to) for emails with errors -MailingDelay=Seconds to wait after sending next message -##### Notification ##### -NotificationSetup=Email Notification module setup -NotificationEMailFrom=Sender email (From) for emails sent by the Notifications module -FixedEmailTarget=Recipient -##### Sendings ##### -SendingsSetup=Shipping module setup -SendingsReceiptModel=Sending receipt model -SendingsNumberingModules=Sendings numbering modules -SendingsAbility=Support shipping sheets for customer deliveries -NoNeedForDeliveryReceipts=In most cases, shipping sheets are used both as sheets for customer deliveries (list of products to send) and sheets that are received and signed by customer. Hence the product deliveries receipt is a duplicated feature and is rarely activated. -FreeLegalTextOnShippings=Free text on shipments -##### Deliveries ##### -DeliveryOrderNumberingModules=Products deliveries receipt numbering module -DeliveryOrderModel=Products deliveries receipt model -DeliveriesOrderAbility=Support products deliveries receipts -FreeLegalTextOnDeliveryReceipts=Free text on delivery receipts -##### FCKeditor ##### -AdvancedEditor=Advanced editor -ActivateFCKeditor=Activate advanced editor for: FCKeditorForCompany=WYSIWIG creation/edition of elements description and note (except products/services) FCKeditorForProduct=WYSIWIG creation/edition of products/services description and note -FCKeditorForProductDetails=WYSIWIG creation/edition of products details lines for all entities (proposals, orders, invoices, etc...). Warning: Using this option for this case is seriously not recommended as it can create problems with special characters and page formatting when building PDF files. -FCKeditorForMailing= WYSIWIG creation/edition for mass eMailings (Tools->eMailing) -FCKeditorForUserSignature=WYSIWIG creation/edition of user signature -FCKeditorForMail=WYSIWIG creation/edition for all mail (except Tools->eMailing) -FCKeditorForTicket=WYSIWIG creation/edition for tickets -##### Stock ##### -StockSetup=Stock module setup -IfYouUsePointOfSaleCheckModule=If you use the Point of Sale module (POS) provided by default or an external module, this setup may be ignored by your POS module. Most POS modules are designed by default to create an invoice immediately and decrease stock irrespective of the options here. So if you need or not to have a stock decrease when registering a sale from your POS, check also your POS module setup. -##### Menu ##### -MenuDeleted=Menu deleted -Menu=Menu -Menus=Menus -TreeMenuPersonalized=Personalized menus -NotTopTreeMenuPersonalized=Personalized menus not linked to a top menu entry -NewMenu=New menu -MenuHandler=Menu handler -MenuModule=Source module -HideUnauthorizedMenu=Hide unauthorized menus also for internal users (just greyed otherwise) -DetailId=Id menu -DetailMenuHandler=Menu handler where to show new menu -DetailMenuModule=Module name if menu entry come from a module -DetailType=Type of menu (top or left) -DetailTitre=Menu label or label code for translation -DetailUrl=URL where menu send you (Absolute URL link or external link with http://) -DetailEnabled=Condition to show or not entry -DetailRight=Condition to display unauthorized grey menus -DetailLangs=Lang file name for label code translation -DetailUser=Intern / Extern / All -Target=Target -DetailTarget=Target for links (_blank top opens a new window) -DetailLevel=Level (-1:top menu, 0:header menu, >0 menu and sub menu) -ModifMenu=Menu change -DeleteMenu=Delete menu entry -ConfirmDeleteMenu=Are you sure you want to delete menu entry %s? -FailedToInitializeMenu=Failed to initialize menu -##### Tax ##### -TaxSetup=Taxes, social or fiscal taxes and dividends module setup -OptionVatMode=VAT due -OptionVATDefault=Standard basis -OptionVATDebitOption=Accrual basis -OptionVatDefaultDesc=VAT is due:
    - on delivery of goods (based on invoice date)
    - on payments for services -OptionVatDebitOptionDesc=VAT is due:
    - on delivery of goods (based on invoice date)
    - on invoice (debit) for services -OptionPaymentForProductAndServices=Cash basis for products and services -OptionPaymentForProductAndServicesDesc=VAT is due:
    - on payment for goods
    - on payments for services -SummaryOfVatExigibilityUsedByDefault=Time of VAT eligibility by default according to chosen option: -OnDelivery=On delivery -OnPayment=On payment -OnInvoice=On invoice -SupposedToBePaymentDate=Payment date used -SupposedToBeInvoiceDate=Invoice date used -Buy=Buy -Sell=Sell -InvoiceDateUsed=Invoice date used -YourCompanyDoesNotUseVAT=Your company has been defined to not use VAT (Home - Setup - Company/Organization), so there is no VAT options to setup. -AccountancyCode=Accounting Code -AccountancyCodeSell=Sale account. code -AccountancyCodeBuy=Purchase account. code -CREATE_NEW_VAT_WITHOUT_AUTO_PAYMENT=Keep the checkbox “Automatically create the payment” empty by default when creating a new tax -##### Agenda ##### -AgendaSetup=Events and agenda module setup -PasswordTogetVCalExport=Key to authorize export link -SecurityKey = Security Key -PastDelayVCalExport=Do not export event older than -AGENDA_USE_EVENT_TYPE=Use events types (managed in menu Setup -> Dictionaries -> Type of agenda events) -AGENDA_USE_EVENT_TYPE_DEFAULT=Automatically set this default value for type of event in event create form -AGENDA_DEFAULT_FILTER_TYPE=Automatically set this type of event in search filter of agenda view -AGENDA_DEFAULT_FILTER_STATUS=Automatically set this status for events in search filter of agenda view -AGENDA_DEFAULT_VIEW=Which view do you want to open by default when selecting menu Agenda -AGENDA_REMINDER_BROWSER=Enable event reminder on user's browser (When remind date is reached, a popup is shown by the browser. Each user can disable such notifications from its browser notification setup). -AGENDA_REMINDER_BROWSER_SOUND=Enable sound notification -AGENDA_REMINDER_EMAIL=Enable event reminder by emails (remind option/delay can be defined on each event). -AGENDA_REMINDER_EMAIL_NOTE=Note: The frequency of the scheduled job %s must be enough to be sure that the remind are sent at the correct moment. -AGENDA_SHOW_LINKED_OBJECT=Show linked object into agenda view -##### Clicktodial ##### -ClickToDialSetup=Click To Dial module setup -ClickToDialUrlDesc=Url called when a click on phone picto is done. In URL, you can use tags
    __PHONETO__ that will be replaced with the phone number of person to call
    __PHONEFROM__ that will be replaced with phone number of calling person (yours)
    __LOGIN__ that will be replaced with clicktodial login (defined on user card)
    __PASS__ that will be replaced with clicktodial password (defined on user card). -ClickToDialDesc=This module change phone numbers, when using a desktop computer, into clickable links. A click will call the number. This can be used to start the phone call when using a soft phone on your desktop or when using a CTI system based on SIP protocol for example. Note: When using a smartphone, phone numbers are always clickable. -ClickToDialUseTelLink=Use just a link "tel:" on phone numbers -ClickToDialUseTelLinkDesc=Use this method if your users have a softphone or a software interface, installed on the same computer as the browser, and called when you click on a link starting with "tel:" in your browser. If you need a link that start with "sip:" or a full server solution (no need of local software installation), you must set this to "No" and fill the next field. -##### Point Of Sale (CashDesk) ##### -CashDesk=Point of Sale -CashDeskSetup=Point of Sales module setup -CashDeskThirdPartyForSell=Default generic third party to use for sales -CashDeskBankAccountForSell=Default account to use to receive cash payments -CashDeskBankAccountForCheque=Default account to use to receive payments by check -CashDeskBankAccountForCB=Default account to use to receive payments by credit cards -CashDeskBankAccountForSumup=Default bank account to use to receive payments by SumUp -CashDeskDoNotDecreaseStock=Disable stock decrease when a sale is done from Point of Sale (if "no", stock decrease is done for each sale done from POS, irrespective of the option set in module Stock). -CashDeskIdWareHouse=Force and restrict warehouse to use for stock decrease -StockDecreaseForPointOfSaleDisabled=Stock decrease from Point of Sale disabled -StockDecreaseForPointOfSaleDisabledbyBatch=Stock decrease in POS is not compatible with module Serial/Lot management (currently active) so stock decrease is disabled. -CashDeskYouDidNotDisableStockDecease=You did not disable stock decrease when making a sale from Point of Sale. Hence a warehouse is required. -CashDeskForceDecreaseStockLabel=Stock decrease for batch products was forced. -CashDeskForceDecreaseStockDesc=Decrease first by the oldest eatby and sellby dates. -CashDeskReaderKeyCodeForEnter=Key code for "Enter" defined in barcode reader (Example: 13) -##### Bookmark ##### -BookmarkSetup=Bookmark module setup -BookmarkDesc=This module allows you to manage bookmarks. You can also add shortcuts to any Dolibarr pages or external web sites on your left menu. -NbOfBoomarkToShow=Maximum number of bookmarks to show in left menu -##### WebServices ##### -WebServicesSetup=Webservices module setup -WebServicesDesc=By enabling this module, Dolibarr become a web service server to provide miscellaneous web services. -WSDLCanBeDownloadedHere=WSDL descriptor files of provided services can be download here -EndPointIs=SOAP clients must send their requests to the Dolibarr endpoint available at URL -##### API #### -ApiSetup=API module setup -ApiDesc=By enabling this module, Dolibarr become a REST server to provide miscellaneous web services. -ApiProductionMode=Enable production mode (this will activate use of a cache for services management) -ApiExporerIs=You can explore and test the APIs at URL -OnlyActiveElementsAreExposed=Only elements from enabled modules are exposed -ApiKey=Key for API -WarningAPIExplorerDisabled=The API explorer has been disabled. API explorer is not required to provide API services. It is a tool for developer to find/test REST APIs. If you need this tool, go into setup of module API REST to activate it. -##### Bank ##### -BankSetupModule=Bank module setup -FreeLegalTextOnChequeReceipts=Free text on check receipts -BankOrderShow=Display order of bank accounts for countries using "detailed bank number" -BankOrderGlobal=General -BankOrderGlobalDesc=General display order -BankOrderES=Spanish -BankOrderESDesc=Spanish display order -ChequeReceiptsNumberingModule=Check Receipts Numbering Module -##### Multicompany ##### -MultiCompanySetup=Multi-company module setup -##### Suppliers ##### -SuppliersSetup=Vendor module setup -SuppliersCommandModel=Complete template of Purchase Order -SuppliersCommandModelMuscadet=Complete template of Purchase Order (old implementation of cornas template) -SuppliersInvoiceModel=Complete template of Vendor Invoice -SuppliersInvoiceNumberingModel=Vendor invoices numbering models -IfSetToYesDontForgetPermission=If set to a non null value, don't forget to provide permissions to groups or users allowed for the second approval -##### GeoIPMaxmind ##### -GeoIPMaxmindSetup=GeoIP Maxmind module setup -PathToGeoIPMaxmindCountryDataFile=Path to file containing Maxmind ip to country translation.
    Examples:
    /usr/local/share/GeoIP/GeoIP.dat
    /usr/share/GeoIP/GeoIP.dat
    /usr/share/GeoIP/GeoLite2-Country.mmdb -NoteOnPathLocation=Note that your ip to country data file must be inside a directory your PHP can read (Check your PHP open_basedir setup and filesystem permissions). -YouCanDownloadFreeDatFileTo=You can download a free demo version of the Maxmind GeoIP country file at %s. -YouCanDownloadAdvancedDatFileTo=You can also download a more complete version, with updates, of the Maxmind GeoIP country file at %s. -TestGeoIPResult=Test of a conversion IP -> country -##### Projects ##### -ProjectsNumberingModules=Projects numbering module -ProjectsSetup=Project module setup -ProjectsModelModule=Project reports document model -TasksNumberingModules=Tasks numbering module -TaskModelModule=Tasks reports document model -UseSearchToSelectProject=Wait until a key is pressed before loading content of Project combo list.
    This may improve performance if you have a large number of projects, but it is less convenient. -##### ECM (GED) ##### -##### Fiscal Year ##### -AccountingPeriods=Accounting periods -AccountingPeriodCard=Accounting period -NewFiscalYear=New accounting period -OpenFiscalYear=Open accounting period -CloseFiscalYear=Close accounting period -DeleteFiscalYear=Delete accounting period -ConfirmDeleteFiscalYear=Are you sure to delete this accounting period? -ShowFiscalYear=Show accounting period -AlwaysEditable=Can always be edited -MAIN_APPLICATION_TITLE=Force visible name of application (warning: setting your own name here may break autofill login feature when using DoliDroid mobile application) -NbMajMin=Minimum number of uppercase characters -NbNumMin=Minimum number of numeric characters -NbSpeMin=Minimum number of special characters -NbIteConsecutive=Maximum number of repeating same characters -NoAmbiCaracAutoGeneration=Do not use ambiguous characters ("1","l","i","|","0","O") for automatic generation -SalariesSetup=Setup of module salaries -SortOrder=Sort order -Format=Format -TypePaymentDesc=0:Customer payment type, 1:Vendor payment type, 2:Both customers and suppliers payment type -IncludePath=Include path (defined into variable %s) -ExpenseReportsSetup=Setup of module Expense Reports -TemplatePDFExpenseReports=Document templates to generate expense report document -ExpenseReportsRulesSetup=Setup of module Expense Reports - Rules -ExpenseReportNumberingModules=Expense reports numbering module -NoModueToManageStockIncrease=No module able to manage automatic stock increase has been activated. Stock increase will be done on manual input only. -YouMayFindNotificationsFeaturesIntoModuleNotification=You may find options for email notifications by enabling and configuring the module "Notification". -ListOfNotificationsPerUser=List of automatic notifications per user* -ListOfNotificationsPerUserOrContact=List of possible automatic notifications (on business event) available per user* or per contact** -ListOfFixedNotifications=List of automatic fixed notifications -GoOntoUserCardToAddMore=Go to the tab "Notifications" of a user to add or remove notifications for users -GoOntoContactCardToAddMore=Go to the tab "Notifications" of a third party to add or remove notifications for contacts/addresses -Threshold=Threshold -BackupDumpWizard=Wizard to build the database dump file -BackupZipWizard=Wizard to build the archive of documents directory -SomethingMakeInstallFromWebNotPossible=Installation of external module is not possible from the web interface for the following reason: -SomethingMakeInstallFromWebNotPossible2=For this reason, process to upgrade described here is a manual process only a privileged user may perform. -InstallModuleFromWebHasBeenDisabledByFile=Install of external module from application has been disabled by your administrator. You must ask him to remove the file %s to allow this feature. -ConfFileMustContainCustom=Installing or building an external module from application need to save the module files into directory %s. To have this directory processed by Dolibarr, you must setup your conf/conf.php to add the 2 directive lines:
    $dolibarr_main_url_root_alt='/custom';
    $dolibarr_main_document_root_alt='%s/custom'; -HighlightLinesOnMouseHover=Highlight table lines when mouse move passes over -HighlightLinesColor=Highlight color of the line when the mouse passes over (use 'ffffff' for no highlight) -HighlightLinesChecked=Highlight color of the line when it is checked (use 'ffffff' for no highlight) -TextTitleColor=Text color of Page title -LinkColor=Color of links -PressF5AfterChangingThis=Press CTRL+F5 on keyboard or clear your browser cache after changing this value to have it effective -NotSupportedByAllThemes=Will works with core themes, may not be supported by external themes -BackgroundColor=Background color -TopMenuBackgroundColor=Background color for Top menu -TopMenuDisableImages=Hide images in Top menu -LeftMenuBackgroundColor=Background color for Left menu -BackgroundTableTitleColor=Background color for Table title line -BackgroundTableTitleTextColor=Text color for Table title line -BackgroundTableTitleTextlinkColor=Text color for Table title link line -BackgroundTableLineOddColor=Background color for odd table lines -BackgroundTableLineEvenColor=Background color for even table lines -MinimumNoticePeriod=Minimum notice period (Your leave request must be done before this delay) -NbAddedAutomatically=Number of days added to counters of users (automatically) each month -EnterAnyCode=This field contains a reference to identify the line. Enter any value of your choice, but without special characters. -Enter0or1=Enter 0 or 1 -UnicodeCurrency=Enter here between braces, list of byte number that represent the currency symbol. For example: for $, enter [36] - for brazil real R$ [82,36] - for €, enter [8364] -ColorFormat=The RGB color is in HEX format, eg: FF0000 -PictoHelp=Icon name in dolibarr format ('image.png' if into the current theme directory, 'image.png@nom_du_module' if into the directory /img/ of a module) -PositionIntoComboList=Position of line into combo lists SellTaxRate=Sale tax rate -RecuperableOnly=Yes for VAT "Not Perceived but Recoverable" dedicated for some state in France. Keep value to "No" in all other cases. -UrlTrackingDesc=If the provider or transport service offers a page or web site to check the status of your shipments, you may enter it here. You can use the key {TRACKID} in the URL parameters so the system will replace it with the tracking number the user entered into the shipment card. -OpportunityPercent=When you create a lead, you will define an estimated amount of project/lead. According to status of the lead, this amount may be multiplied by this rate to evaluate a total amount all your leads may generate. Value is a percentage (between 0 and 100). TemplateForElement=This template record is dedicated to which element -TypeOfTemplate=Type of template -TemplateIsVisibleByOwnerOnly=Template is visible to owner only -VisibleEverywhere=Visible everywhere -VisibleNowhere=Visible nowhere -FixTZ=TimeZone fix -FillFixTZOnlyIfRequired=Example: +2 (fill only if problem experienced) -ExpectedChecksum=Expected Checksum -CurrentChecksum=Current Checksum -ExpectedSize=Expected size -CurrentSize=Current size -ForcedConstants=Required constant values -MailToSendProposal=Customer proposals -MailToSendOrder=Sales orders -MailToSendInvoice=Customer invoices -MailToSendShipment=Shipments -MailToSendIntervention=Interventions -MailToSendSupplierRequestForQuotation=Quotation request -MailToSendSupplierOrder=Purchase orders -MailToSendSupplierInvoice=Vendor invoices -MailToSendContract=Contracts -MailToSendReception=Receptions -MailToThirdparty=Third parties -MailToMember=Members -MailToUser=Users -MailToProject=Projects -MailToTicket=Tickets -ByDefaultInList=Show by default on list view -YouUseLastStableVersion=You use the latest stable version -TitleExampleForMajorRelease=Example of message you can use to announce this major release (feel free to use it on your web sites) -TitleExampleForMaintenanceRelease=Example of message you can use to announce this maintenance release (feel free to use it on your web sites) -ExampleOfNewsMessageForMajorRelease=Dolibarr ERP & CRM %s is available. Version %s is a major release with a lot of new features for both users and developers. You can download it from the download area of https://www.dolibarr.org portal (subdirectory Stable versions). You can read ChangeLog for complete list of changes. -ExampleOfNewsMessageForMaintenanceRelease=Dolibarr ERP & CRM %s is available. Version %s is a maintenance version, so contains only bug fixes. We recommend all users to upgrade to this version. A maintenance release does not introduce new features or changes to the database. You may download it from the download area of https://www.dolibarr.org portal (subdirectory Stable versions). You can read the ChangeLog for complete list of changes. -MultiPriceRuleDesc=When option "Several levels of prices per product/service" is enabled, you can define different prices (one per price level) for each product. To save you time, here you may enter a rule to autocalculate a price for each level based on the price of the first level, so you will have to only enter a price for the first level for each product. This page is designed to save you time but is useful only if your prices for each level are relative to first level. You can ignore this page in most cases. -ModelModulesProduct=Templates for product documents -WarehouseModelModules=Templates for documents of warehouses -ToGenerateCodeDefineAutomaticRuleFirst=To be able to generate codes automatically, you must first define a manager to auto-define the barcode number. -SeeSubstitutionVars=See * note for list of possible substitution variables -SeeChangeLog=See ChangeLog file (english only) -AllPublishers=All publishers -UnknownPublishers=Unknown publishers -AddRemoveTabs=Add or remove tabs -AddDataTables=Add object tables -AddDictionaries=Add dictionaries tables -AddData=Add objects or dictionaries data -AddBoxes=Add widgets -AddSheduledJobs=Add scheduled jobs -AddHooks=Add hooks -AddTriggers=Add triggers -AddMenus=Add menus -AddPermissions=Add permissions -AddExportProfiles=Add export profiles -AddImportProfiles=Add import profiles -AddOtherPagesOrServices=Add other pages or services -AddModels=Add document or numbering templates -AddSubstitutions=Add keys substitutions -DetectionNotPossible=Detection not possible -UrlToGetKeyToUseAPIs=Url to get token to use API (once token has been received it is saved in database user table and must be provided on each API call) -ListOfAvailableAPIs=List of available APIs -activateModuleDependNotSatisfied=Module "%s" depends on module "%s", that is missing, so module "%1$s" may not work correctly. Please install module "%2$s" or disable module "%1$s" if you want to be safe from any surprise -CommandIsNotInsideAllowedCommands=The command you are trying to run is not in the list of allowed commands defined in parameter $dolibarr_main_restrict_os_commands in the conf.php file. -LandingPage=Landing page -SamePriceAlsoForSharedCompanies=If you use a multicompany module, with the choice "Single price", the price will also be the same for all companies if products are shared between environments -ModuleEnabledAdminMustCheckRights=Module has been activated. Permissions for activated module(s) were given to admin users only. You may need to grant permissions to other users or groups manually if necessary. -UserHasNoPermissions=This user has no permissions defined -TypeCdr=Use "None" if the date of payment term is date of invoice plus a delta in days (delta is field "%s")
    Use "At end of month", if, after delta, the date must be increased to reach the end of month (+ an optional "%s" in days)
    Use "Current/Next" to have payment term date being the first Nth of the month after delta (delta is field "%s", N is stored into field "%s") -BaseCurrency=Reference currency of the company (go into setup of company to change this) -WarningNoteModuleInvoiceForFrenchLaw=This module %s is compliant with French laws (Loi Finance 2016). -WarningNoteModulePOSForFrenchLaw=This module %s is compliant with French laws (Loi Finance 2016) because module Non Reversible Logs is automatically activated. -WarningInstallationMayBecomeNotCompliantWithLaw=You are trying to install module %s that is an external module. Activating an external module means you trust the publisher of that module and that you are sure that this module does not adversely impact the behavior of your application, and is compliant with laws of your country (%s). If the module introduces an illegal feature, you become responsible for the use of illegal software. -MAIN_PDF_MARGIN_LEFT=Left margin on PDF -MAIN_PDF_MARGIN_RIGHT=Right margin on PDF -MAIN_PDF_MARGIN_TOP=Top margin on PDF -MAIN_PDF_MARGIN_BOTTOM=Bottom margin on PDF -MAIN_DOCUMENTS_LOGO_HEIGHT=Height for logo on PDF -MAIN_GENERATE_PROPOSALS_WITH_PICTURE=Add picture on proposal line -PROPOSAL_PDF_HIDE_PAYMENTTERM=Hide payments conditions -PROPOSAL_PDF_HIDE_PAYMENTMODE=Hide payment mode -MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING=Add electronic sign in PDF -NothingToSetup=There is no specific setup required for this module. -SetToYesIfGroupIsComputationOfOtherGroups=Set this to yes if this group is a computation of other groups -EnterCalculationRuleIfPreviousFieldIsYes=Enter calculation rule if previous field was set to Yes.
    For example:
    CODEGRP1+CODEGRP2 -SeveralLangugeVariatFound=Several language variants found -RemoveSpecialChars=Remove special characters -COMPANY_AQUARIUM_CLEAN_REGEX=Regex filter to clean value (COMPANY_AQUARIUM_CLEAN_REGEX) -COMPANY_DIGITARIA_CLEAN_REGEX=Regex filter to clean value (COMPANY_DIGITARIA_CLEAN_REGEX) -COMPANY_DIGITARIA_UNIQUE_CODE=Duplicate not allowed -GDPRContact=Data Protection Officer (DPO, Data Privacy or GDPR contact) -GDPRContactDesc=If you store data about European companies/citizens, you can name the contact who is responsible for the General Data Protection Regulation here -HelpOnTooltip=Help text to show on tooltip -HelpOnTooltipDesc=Put text or a translation key here for the text to show in a tooltip when this field appears in a form -YouCanDeleteFileOnServerWith=You can delete this file on the server with Command Line:
    %s -ChartLoaded=Chart of account loaded -SocialNetworkSetup=Setup of module Social Networks -EnableFeatureFor=Enable features for %s -VATIsUsedIsOff=Note: The option to use Sales Tax or VAT has been set to Off in the menu %s - %s, so Sales tax or Vat used will always be 0 for sales. -SwapSenderAndRecipientOnPDF=Swap sender and recipient address position on PDF documents -FeatureSupportedOnTextFieldsOnly=Warning, feature supported on text fields and combo lists only. Also an URL parameter action=create or action=edit must be set OR page name must end with 'new.php' to trigger this feature. -EmailCollector=Email collector -EmailCollectorDescription=Add a scheduled job and a setup page to scan regularly email boxes (using IMAP protocol) and record emails received into your application, at the right place and/or create some records automatically (like leads). -NewEmailCollector=New Email Collector -EMailHost=Host of email IMAP server -MailboxSourceDirectory=Mailbox source directory -MailboxTargetDirectory=Mailbox target directory -EmailcollectorOperations=Operations to do by collector -EmailcollectorOperationsDesc=Operations are executed from top to bottom order -MaxEmailCollectPerCollect=Max number of emails collected per collect -CollectNow=Collect now -ConfirmCloneEmailCollector=Are you sure you want to clone the Email collector %s ? -DateLastCollectResult=Date of latest collect try -DateLastcollectResultOk=Date of latest collect success -LastResult=Latest result -EmailCollectorConfirmCollectTitle=Email collect confirmation -EmailCollectorConfirmCollect=Do you want to run the collection for this collector now ? -NoNewEmailToProcess=No new email (matching filters) to process -NothingProcessed=Nothing done -XEmailsDoneYActionsDone=%s emails qualified, %s emails successfully processed (for %s record/actions done) -RecordEvent=Record email event -CreateLeadAndThirdParty=Create lead (and third party if necessary) -CreateTicketAndThirdParty=Create ticket (and link to third party if it was loaded by a previous operation) -CodeLastResult=Latest result code -NbOfEmailsInInbox=Number of emails in source directory -LoadThirdPartyFromName=Load third party searching on %s (load only) -LoadThirdPartyFromNameOrCreate=Load third party searching on %s (create if not found) -WithDolTrackingID=Message from a conversation initiated by a first email sent from Dolibarr -WithoutDolTrackingID=Message from a conversation initiated by a first email NOT sent from Dolibarr -WithDolTrackingIDInMsgId=Message sent from Dolibarr -WithoutDolTrackingIDInMsgId=Message NOT sent from Dolibarr -CreateCandidature=Create job application -FormatZip=Zip -MainMenuCode=Menu entry code (mainmenu) -ECMAutoTree=Show automatic ECM tree -OperationParamDesc=Define the values to use for the object of the action, or how to extract values. For example:
    objproperty1=SET:the value to set
    objproperty2=SET:a value with replacement of __objproperty1__
    objproperty3=SETIFEMPTY:value used if objproperty3 is not already defined
    objproperty4=EXTRACT:HEADER:X-Myheaderkey:\\s*([^\\s]*)
    options_myextrafield1=EXTRACT:SUBJECT:([^\n]*)
    object.objproperty5=EXTRACT:BODY:My company name is\\s([^\\s]*)

    Use a ; char as separator to extract or set several properties. -OpeningHours=Opening hours -OpeningHoursDesc=Enter here the regular opening hours of your company. -ResourceSetup=Configuration of Resource module -UseSearchToSelectResource=Use a search form to choose a resource (rather than a drop-down list). -DisabledResourceLinkUser=Disable feature to link a resource to users -DisabledResourceLinkContact=Disable feature to link a resource to contacts -EnableResourceUsedInEventCheck=Enable feature to check if a resource is in use in an event -ConfirmUnactivation=Confirm module reset -OnMobileOnly=On small screen (smartphone) only -DisableProspectCustomerType=Disable the "Prospect + Customer" third party type (so third party must be "Prospect" or "Customer", but can't be both) -MAIN_OPTIMIZEFORTEXTBROWSER=Simplify interface for blind person -MAIN_OPTIMIZEFORTEXTBROWSERDesc=Enable this option if you are a blind person, or if you use the application from a text browser like Lynx or Links. -MAIN_OPTIMIZEFORCOLORBLIND=Change interface's color for color blind person -MAIN_OPTIMIZEFORCOLORBLINDDesc=Enable this option if you are a color blind person, in some case interface will change color setup to increase contrast. -Protanopia=Protanopia -Deuteranopes=Deuteranopes -Tritanopes=Tritanopes -ThisValueCanOverwrittenOnUserLevel=This value can be overwritten by each user from its user page - tab '%s' -DefaultCustomerType=Default thirdparty type for "New customer" creation form -ABankAccountMustBeDefinedOnPaymentModeSetup=Note: The bank account must be defined on the module of each payment mode (Paypal, Stripe, ...) to have this feature working. -RootCategoryForProductsToSell=Root category of products to sell -RootCategoryForProductsToSellDesc=If defined, only products inside this category or childs of this category will be available in the Point Of Sale -DebugBar=Debug Bar -DebugBarDesc=Toolbar that comes with a plenty of tools to simplify debugging -DebugBarSetup=DebugBar Setup -GeneralOptions=General Options -LogsLinesNumber=Number of lines to show on logs tab -UseDebugBar=Use the debug bar -DEBUGBAR_LOGS_LINES_NUMBER=Number of last log lines to keep in console -WarningValueHigherSlowsDramaticalyOutput=Warning, higher values slows dramaticaly output -ModuleActivated=Module %s is activated and slows the interface -ModuleActivatedWithTooHighLogLevel=Module %s is activated with a too high logging level (try to use a lower level for better performances and security) -ModuleSyslogActivatedButLevelNotTooVerbose=Module %s is activated and log level (%s) is correct (not too verbose) -IfYouAreOnAProductionSetThis=If you are on a production environment, you should set this property to %s. -AntivirusEnabledOnUpload=Antivirus enabled on uploaded files -SomeFilesOrDirInRootAreWritable=Some files or directories are not in a read-only mode -EXPORTS_SHARE_MODELS=Export models are share with everybody -ExportSetup=Setup of module Export -ImportSetup=Setup of module Import -InstanceUniqueID=Unique ID of the instance -SmallerThan=Smaller than -LargerThan=Larger than -IfTrackingIDFoundEventWillBeLinked=Note that If a tracking ID of an object is found into email, or if the email is an answer of an email aready collected and linked to an object, the created event will be automatically linked to the known related object. -WithGMailYouCanCreateADedicatedPassword=With a GMail account, if you enabled the 2 steps validation, it is recommanded to create a dedicated second password for the application instead of using your own account passsword from https://myaccount.google.com/. -EmailCollectorTargetDir=It may be a desired behaviour to move the email into another tag/directory when it was processed successfully. Just set name of directory here to use this feature (Do NOT use special characters in name). Note that you must also use a read/write login account. -EmailCollectorLoadThirdPartyHelp=You can use this action to use the email content to find and load an existing thirdparty in your database. The found (or created) thirdparty will be used for following actions that need it.
    For example, if you want to create a thirdparty with a name extracted a string 'Name: name to find' found into the body, use sender email as email, you can set the parameter field like this:
    'email=HEADER:^From:(.*);name=EXTRACT:BODY:Name:\\s([^\\s]*);client=SET:2;'
    -EndPointFor=End point for %s : %s -DeleteEmailCollector=Delete email collector -ConfirmDeleteEmailCollector=Are you sure you want to delete this email collector? -RecipientEmailsWillBeReplacedWithThisValue=Recipient emails will be always replaced with this value -AtLeastOneDefaultBankAccountMandatory=At least 1 default bank account must be defined -RESTRICT_ON_IP=Allow access to some host IP only (wildcard not allowed, use space between values). Empty means every hosts can access. -IPListExample=127.0.0.1 192.168.0.2 [::1] -BaseOnSabeDavVersion=Based on the library SabreDAV version -NotAPublicIp=Not a public IP -MakeAnonymousPing=Make an anonymous Ping '+1' to the Dolibarr foundation server (done 1 time only after installation) to allow the foundation to count the number of Dolibarr installation. -FeatureNotAvailableWithReceptionModule=Feature not available when module Reception is enabled -EmailTemplate=Template for email -EMailsWillHaveMessageID=Emails will have a tag 'References' matching this syntax -PDF_SHOW_PROJECT=Show project on document -ShowProjectLabel=Project Label -PDF_USE_ALSO_LANGUAGE_CODE=If you want to have some texts in your PDF duplicated in 2 different languages in the same generated PDF, you must set here this second language so generated PDF will contains 2 different languages in same page, the one chosen when generating PDF and this one (only few PDF templates support this). Keep empty for 1 language per PDF. -FafaIconSocialNetworksDesc=Enter here the code of a FontAwesome icon. If you don't know what is FontAwesome, you can use the generic value fa-address-book. -RssNote=Note: Each RSS feed definition provides a widget that you must enable to have it available in dashboard -JumpToBoxes=Jump to Setup -> Widgets -MeasuringUnitTypeDesc=Use here a value like "size", "surface", "volume", "weight", "time" -MeasuringScaleDesc=The scale is the number of places you have to move the decimal part to match the default reference unit. For "time" unit type, it is the number of seconds. Values between 80 and 99 are reserved values. -TemplateAdded=Template added -TemplateUpdated=Template updated -TemplateDeleted=Template deleted -MailToSendEventPush=Event reminder email -SwitchThisForABetterSecurity=Switching this value to %s is recommended for more security -DictionaryProductNature= Nature of product -CountryIfSpecificToOneCountry=Country (if specific to a given country) -YouMayFindSecurityAdviceHere=You may find security advisory here -ModuleActivatedMayExposeInformation=This PHP extension may expose sensitive data. If you don't need it, disable it. -ModuleActivatedDoNotUseInProduction=A module designed for the development has been enabled. Do not enable it on a production environment. -CombinationsSeparator=Separator character for product combinations -SeeLinkToOnlineDocumentation=See link to online documention on top menu for examples -SHOW_SUBPRODUCT_REF_IN_PDF=If the feature "%s" of module %s is used, show details of subproducts of a kit on PDF. -AskThisIDToYourBank=Contact your bank to get this ID -AdvancedModeOnly=Permision available in Advanced permission mode only -ConfFileIsReadableOrWritableByAnyUsers=The conf file is readable or writable by any users. Give permission to web server user and group only. -MailToSendEventOrganization=Event Organization -MailToPartnership=Partnership -AGENDA_EVENT_DEFAULT_STATUS=Default event status when creating a event from the form -YouShouldDisablePHPFunctions=You should disable PHP functions -IfCLINotRequiredYouShouldDisablePHPFunctions=Except if you need to run system commands in custom code, you shoud disable PHP functions -PHPFunctionsRequiredForCLI=For shell purpose (like scheduled job backup or running an anitivurs program), you must keep PHP functions -NoWritableFilesFoundIntoRootDir=No writable files or directories of the common programs were found into your root directory (Good) -RecommendedValueIs=Recommended: %s -Recommended=Recommended -NotRecommended=Not recommended -ARestrictedPath=A restricted path -CheckForModuleUpdate=Check for external modules updates -CheckForModuleUpdateHelp=This action will connect to editors of external modules to check if a new version is available. -ModuleUpdateAvailable=An update is available -NoExternalModuleWithUpdate=No updates found for external modules -SwaggerDescriptionFile=Swagger API description file (for use with redoc for example) -YouEnableDeprecatedWSAPIsUseRESTAPIsInstead=You enabled deprecated WS API. You should use REST API instead. -RandomlySelectedIfSeveral=Randomly selected if several pictures are available -DatabasePasswordObfuscated=Database password is obfuscated in conf file -DatabasePasswordNotObfuscated=Database password is NOT obfuscated in conf file -APIsAreNotEnabled=APIs modules are not enabled -YouShouldSetThisToOff=You should set this to 0 or off -InstallAndUpgradeLockedBy=Install and upgrades are locked by the file %s -OldImplementation=Old implementation diff --git a/htdocs/langs/ar_IQ/agenda.lang b/htdocs/langs/ar_IQ/agenda.lang deleted file mode 100644 index a1183841b00..00000000000 --- a/htdocs/langs/ar_IQ/agenda.lang +++ /dev/null @@ -1,172 +0,0 @@ -# Dolibarr language file - Source file is en_US - agenda -IdAgenda=ID event -Actions=Events -Agenda=Agenda -TMenuAgenda=Agenda -Agendas=Agendas -LocalAgenda=Default calendar -ActionsOwnedBy=Event owned by -ActionsOwnedByShort=Owner -AffectedTo=Assigned to -Event=Event -Events=Events -EventsNb=Number of events -ListOfActions=List of events -EventReports=Event reports -Location=Location -ToUserOfGroup=Event assigned to any user in the group -EventOnFullDay=Event on all day(s) -MenuToDoActions=All incomplete events -MenuDoneActions=All terminated events -MenuToDoMyActions=My incomplete events -MenuDoneMyActions=My terminated events -ListOfEvents=List of events (default calendar) -ActionsAskedBy=Events reported by -ActionsToDoBy=Events assigned to -ActionsDoneBy=Events done by -ActionAssignedTo=Event assigned to -ViewCal=Month view -ViewDay=Day view -ViewWeek=Week view -ViewPerUser=Per user view -ViewPerType=Per type view -AutoActions= Automatic filling -AgendaAutoActionDesc= Here you may define events which you want Dolibarr to create automatically in Agenda. If nothing is checked, only manual actions will be included in logs and displayed in Agenda. Automatic tracking of business actions done on objects (validation, status change) will not be saved. -AgendaSetupOtherDesc= This page provides options to allow the export of your Dolibarr events into an external calendar (Thunderbird, Google Calendar etc...) -AgendaExtSitesDesc=This page allows to declare external sources of calendars to see their events into Dolibarr agenda. -ActionsEvents=Events for which Dolibarr will create an action in agenda automatically -EventRemindersByEmailNotEnabled=Event reminders by email was not enabled into %s module setup. -##### Agenda event labels ##### -NewCompanyToDolibarr=Third party %s created -COMPANY_MODIFYInDolibarr=Third party %s modified -COMPANY_DELETEInDolibarr=Third party %s deleted -ContractValidatedInDolibarr=Contract %s validated -CONTRACT_DELETEInDolibarr=Contract %s deleted -PropalClosedSignedInDolibarr=Proposal %s signed -PropalClosedRefusedInDolibarr=Proposal %s refused -PropalValidatedInDolibarr=Proposal %s validated -PropalClassifiedBilledInDolibarr=Proposal %s classified billed -InvoiceValidatedInDolibarr=Invoice %s validated -InvoiceValidatedInDolibarrFromPos=Invoice %s validated from POS -InvoiceBackToDraftInDolibarr=Invoice %s go back to draft status -InvoiceDeleteDolibarr=Invoice %s deleted -InvoicePaidInDolibarr=Invoice %s changed to paid -InvoiceCanceledInDolibarr=Invoice %s canceled -MemberValidatedInDolibarr=Member %s validated -MemberModifiedInDolibarr=Member %s modified -MemberResiliatedInDolibarr=Member %s terminated -MemberDeletedInDolibarr=Member %s deleted -MemberSubscriptionAddedInDolibarr=Subscription %s for member %s added -MemberSubscriptionModifiedInDolibarr=Subscription %s for member %s modified -MemberSubscriptionDeletedInDolibarr=Subscription %s for member %s deleted -ShipmentValidatedInDolibarr=Shipment %s validated -ShipmentClassifyClosedInDolibarr=Shipment %s classified billed -ShipmentUnClassifyCloseddInDolibarr=Shipment %s classified re-open -ShipmentBackToDraftInDolibarr=Shipment %s go back to draft status -ShipmentDeletedInDolibarr=Shipment %s deleted -ReceptionValidatedInDolibarr=Reception %s validated -OrderCreatedInDolibarr=Order %s created -OrderValidatedInDolibarr=Order %s validated -OrderDeliveredInDolibarr=Order %s classified delivered -OrderCanceledInDolibarr=Order %s canceled -OrderBilledInDolibarr=Order %s classified billed -OrderApprovedInDolibarr=Order %s approved -OrderRefusedInDolibarr=Order %s refused -OrderBackToDraftInDolibarr=Order %s go back to draft status -ProposalSentByEMail=Commercial proposal %s sent by email -ContractSentByEMail=Contract %s sent by email -OrderSentByEMail=Sales order %s sent by email -InvoiceSentByEMail=Customer invoice %s sent by email -SupplierOrderSentByEMail=Purchase order %s sent by email -ORDER_SUPPLIER_DELETEInDolibarr=Purchase order %s deleted -SupplierInvoiceSentByEMail=Vendor invoice %s sent by email -ShippingSentByEMail=Shipment %s sent by email -ShippingValidated= Shipment %s validated -InterventionSentByEMail=Intervention %s sent by email -ProposalDeleted=Proposal deleted -OrderDeleted=Order deleted -InvoiceDeleted=Invoice deleted -DraftInvoiceDeleted=Draft invoice deleted -CONTACT_CREATEInDolibarr=Contact %s created -CONTACT_MODIFYInDolibarr=Contact %s modified -CONTACT_DELETEInDolibarr=Contact %s deleted -PRODUCT_CREATEInDolibarr=Product %s created -PRODUCT_MODIFYInDolibarr=Product %s modified -PRODUCT_DELETEInDolibarr=Product %s deleted -HOLIDAY_CREATEInDolibarr=Request for leave %s created -HOLIDAY_MODIFYInDolibarr=Request for leave %s modified -HOLIDAY_APPROVEInDolibarr=Request for leave %s approved -HOLIDAY_VALIDATEInDolibarr=Request for leave %s validated -HOLIDAY_DELETEInDolibarr=Request for leave %s deleted -EXPENSE_REPORT_CREATEInDolibarr=Expense report %s created -EXPENSE_REPORT_VALIDATEInDolibarr=Expense report %s validated -EXPENSE_REPORT_APPROVEInDolibarr=Expense report %s approved -EXPENSE_REPORT_DELETEInDolibarr=Expense report %s deleted -EXPENSE_REPORT_REFUSEDInDolibarr=Expense report %s refused -PROJECT_CREATEInDolibarr=Project %s created -PROJECT_MODIFYInDolibarr=Project %s modified -PROJECT_DELETEInDolibarr=Project %s deleted -TICKET_CREATEInDolibarr=Ticket %s created -TICKET_MODIFYInDolibarr=Ticket %s modified -TICKET_ASSIGNEDInDolibarr=Ticket %s assigned -TICKET_CLOSEInDolibarr=Ticket %s closed -TICKET_DELETEInDolibarr=Ticket %s deleted -BOM_VALIDATEInDolibarr=BOM validated -BOM_UNVALIDATEInDolibarr=BOM unvalidated -BOM_CLOSEInDolibarr=BOM disabled -BOM_REOPENInDolibarr=BOM reopen -BOM_DELETEInDolibarr=BOM deleted -MRP_MO_VALIDATEInDolibarr=MO validated -MRP_MO_UNVALIDATEInDolibarr=MO set to draft status -MRP_MO_PRODUCEDInDolibarr=MO produced -MRP_MO_DELETEInDolibarr=MO deleted -MRP_MO_CANCELInDolibarr=MO canceled -PAIDInDolibarr=%s paid -##### End agenda events ##### -AgendaModelModule=Document templates for event -DateActionStart=Start date -DateActionEnd=End date -AgendaUrlOptions1=You can also add following parameters to filter output: -AgendaUrlOptions3=logina=%s to restrict output to actions owned by a user %s. -AgendaUrlOptionsNotAdmin=logina=!%s to restrict output to actions not owned by user %s. -AgendaUrlOptions4=logint=%s to restrict output to actions assigned to user %s (owner and others). -AgendaUrlOptionsProject=project=__PROJECT_ID__ to restrict output to actions linked to project __PROJECT_ID__. -AgendaUrlOptionsNotAutoEvent=notactiontype=systemauto to exclude automatic events. -AgendaUrlOptionsIncludeHolidays=includeholidays=1 to include events of holidays. -AgendaShowBirthdayEvents=Birthdays of contacts -AgendaHideBirthdayEvents=Hide birthdays of contacts -Busy=Busy -ExportDataset_event1=List of agenda events -DefaultWorkingDays=Default working days range in week (Example: 1-5, 1-6) -DefaultWorkingHours=Default working hours in day (Example: 9-18) -# External Sites ical -ExportCal=Export calendar -ExtSites=Import external calendars -ExtSitesEnableThisTool=Show external calendars (defined in global setup) in Agenda. Does not affect external calendars defined by users. -ExtSitesNbOfAgenda=Number of calendars -AgendaExtNb=Calendar no. %s -ExtSiteUrlAgenda=URL to access .ical file -ExtSiteNoLabel=No Description -VisibleTimeRange=Visible time range -VisibleDaysRange=Visible days range -AddEvent=Create event -MyAvailability=My availability -ActionType=Event type -DateActionBegin=Start event date -ConfirmCloneEvent=Are you sure you want to clone the event %s? -RepeatEvent=Repeat event -OnceOnly=Once only -EveryWeek=Every week -EveryMonth=Every month -DayOfMonth=Day of month -DayOfWeek=Day of week -DateStartPlusOne=Date start + 1 hour -SetAllEventsToTodo=Set all events to todo -SetAllEventsToInProgress=Set all events to in progress -SetAllEventsToFinished=Set all events to finished -ReminderTime=Reminder period before the event -TimeType=Duration type -ReminderType=Callback type -AddReminder=Create an automatic reminder notification for this event -ErrorReminderActionCommCreation=Error creating the reminder notification for this event -BrowserPush=Browser Popup Notification diff --git a/htdocs/langs/ar_IQ/assets.lang b/htdocs/langs/ar_IQ/assets.lang deleted file mode 100644 index afafc98503f..00000000000 --- a/htdocs/langs/ar_IQ/assets.lang +++ /dev/null @@ -1,67 +0,0 @@ -# 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 . - -# -# Generic -# -Assets = Assets -NewAsset = New asset -AccountancyCodeAsset = Accounting code (asset) -AccountancyCodeDepreciationAsset = Accounting code (depreciation asset account) -AccountancyCodeDepreciationExpense = Accounting code (depreciation expense account) -NewAssetType=New asset type -AssetsTypeSetup=Asset type setup -AssetTypeModified=Asset type modified -AssetType=Asset type -AssetsLines=Assets -DeleteType=Delete -DeleteAnAssetType=Delete an asset type -ConfirmDeleteAssetType=Are you sure you want to delete this asset type? -ShowTypeCard=Show type '%s' - -# Module label 'ModuleAssetsName' -ModuleAssetsName = Assets -# Module description 'ModuleAssetsDesc' -ModuleAssetsDesc = Assets description - -# -# Admin page -# -AssetsSetup = Assets setup -Settings = Settings -AssetsSetupPage = Assets setup page -ExtraFieldsAssetsType = Complementary attributes (Asset type) -AssetsType=Asset type -AssetsTypeId=Asset type id -AssetsTypeLabel=Asset type label -AssetsTypes=Assets types - -# -# Menu -# -MenuAssets = Assets -MenuNewAsset = New asset -MenuTypeAssets = Type assets -MenuListAssets = List -MenuNewTypeAssets = New -MenuListTypeAssets = List - -# -# Module -# -Asset=Asset -NewAssetType=New asset type -NewAsset=New asset -ConfirmDeleteAsset=Are you sure you want to delete this asset ? diff --git a/htdocs/langs/ar_IQ/banks.lang b/htdocs/langs/ar_IQ/banks.lang deleted file mode 100644 index a0b7942d446..00000000000 --- a/htdocs/langs/ar_IQ/banks.lang +++ /dev/null @@ -1,184 +0,0 @@ -# Dolibarr language file - Source file is en_US - banks -Bank=Bank -MenuBankCash=Banks | Cash -MenuVariousPayment=Miscellaneous payments -MenuNewVariousPayment=New Miscellaneous payment -BankName=Bank name -FinancialAccount=Account -BankAccount=Bank account -BankAccounts=Bank accounts -BankAccountsAndGateways=Bank accounts | Gateways -ShowAccount=Show Account -AccountRef=Financial account ref -AccountLabel=Financial account label -CashAccount=Cash account -CashAccounts=Cash accounts -CurrentAccounts=Current accounts -SavingAccounts=Savings accounts -ErrorBankLabelAlreadyExists=Financial account label already exists -BankBalance=Balance -BankBalanceBefore=Balance before -BankBalanceAfter=Balance after -BalanceMinimalAllowed=Minimum allowed balance -BalanceMinimalDesired=Minimum desired balance -InitialBankBalance=Initial balance -EndBankBalance=End balance -CurrentBalance=Current balance -FutureBalance=Future balance -ShowAllTimeBalance=Show balance from start -AllTime=From start -Reconciliation=Reconciliation -RIB=Bank Account Number -IBAN=IBAN number -BIC=BIC/SWIFT code -SwiftValid=BIC/SWIFT valid -SwiftVNotalid=BIC/SWIFT not valid -IbanValid=BAN valid -IbanNotValid=BAN not valid -StandingOrders=Direct debit orders -StandingOrder=Direct debit order -PaymentByDirectDebit=Payment by direct debit -PaymentByBankTransfers=Payments by credit transfer -PaymentByBankTransfer=Payment by credit transfer -AccountStatement=Account statement -AccountStatementShort=Statement -AccountStatements=Account statements -LastAccountStatements=Last account statements -IOMonthlyReporting=Monthly reporting -BankAccountDomiciliation=Bank address -BankAccountCountry=Account country -BankAccountOwner=Account owner name -BankAccountOwnerAddress=Account owner address -RIBControlError=Integrity check of values failed. This means the information for this account number is not complete or is incorrect (check country, numbers and IBAN). -CreateAccount=Create account -NewBankAccount=New account -NewFinancialAccount=New financial account -MenuNewFinancialAccount=New financial account -EditFinancialAccount=Edit account -LabelBankCashAccount=Bank or cash label -AccountType=Account type -BankType0=Savings account -BankType1=Current or credit card account -BankType2=Cash account -AccountsArea=Accounts area -AccountCard=Account card -DeleteAccount=Delete account -ConfirmDeleteAccount=Are you sure you want to delete this account? -Account=Account -BankTransactionByCategories=Bank entries by categories -BankTransactionForCategory=Bank entries for category %s -RemoveFromRubrique=Remove link with category -RemoveFromRubriqueConfirm=Are you sure you want to remove link between the entry and the category? -ListBankTransactions=List of bank entries -IdTransaction=Transaction ID -BankTransactions=Bank entries -BankTransaction=Bank entry -ListTransactions=List entries -ListTransactionsByCategory=List entries/category -TransactionsToConciliate=Entries to reconcile -TransactionsToConciliateShort=To reconcile -Conciliable=Can be reconciled -Conciliate=Reconcile -Conciliation=Reconciliation -SaveStatementOnly=Save statement only -ReconciliationLate=Reconciliation late -IncludeClosedAccount=Include closed accounts -OnlyOpenedAccount=Only open accounts -AccountToCredit=Account to credit -AccountToDebit=Account to debit -DisableConciliation=Disable reconciliation feature for this account -ConciliationDisabled=Reconciliation feature disabled -LinkedToAConciliatedTransaction=Linked to a conciliated entry -StatusAccountOpened=Open -StatusAccountClosed=Closed -AccountIdShort=Number -LineRecord=Transaction -AddBankRecord=Add entry -AddBankRecordLong=Add entry manually -Conciliated=Reconciled -ConciliatedBy=Reconciled by -DateConciliating=Reconcile date -BankLineConciliated=Entry reconciled with bank receipt -Reconciled=Reconciled -NotReconciled=Not reconciled -CustomerInvoicePayment=Customer payment -SupplierInvoicePayment=Vendor payment -SubscriptionPayment=Subscription payment -WithdrawalPayment=Debit payment order -SocialContributionPayment=Social/fiscal tax payment -BankTransfer=Credit transfer -BankTransfers=Credit transfers -MenuBankInternalTransfer=Internal transfer -TransferDesc=Use internal transfer to transfer from one account to another, the application will write two records: a debit in the source account and a credit in the target account. The same amount, label and date will be used for this transaction. -TransferFrom=From -TransferTo=To -TransferFromToDone=A transfer from %s to %s of %s %s has been recorded. -CheckTransmitter=Sender -ValidateCheckReceipt=Validate this check receipt? -ConfirmValidateCheckReceipt=Are you sure that you want to submit this check receipt for validation? No changes will be possible once validated. -DeleteCheckReceipt=Delete this check receipt? -ConfirmDeleteCheckReceipt=Are you sure you want to delete this check receipt? -BankChecks=Bank checks -BankChecksToReceipt=Checks awaiting deposit -BankChecksToReceiptShort=Checks awaiting deposit -ShowCheckReceipt=Show check deposit receipt -NumberOfCheques=No. of check -DeleteTransaction=Delete entry -ConfirmDeleteTransaction=Are you sure you want to delete this entry? -ThisWillAlsoDeleteBankRecord=This will also delete generated bank entry -BankMovements=Movements -PlannedTransactions=Planned entries -Graph=Graphs -ExportDataset_banque_1=Bank entries and account statement -ExportDataset_banque_2=Deposit slip -TransactionOnTheOtherAccount=Transaction on the other account -PaymentNumberUpdateSucceeded=Payment number updated successfully -PaymentNumberUpdateFailed=Payment number could not be updated -PaymentDateUpdateSucceeded=Payment date updated successfully -PaymentDateUpdateFailed=Payment date could not be updated -Transactions=Transactions -BankTransactionLine=Bank entry -AllAccounts=All bank and cash accounts -BackToAccount=Back to account -ShowAllAccounts=Show for all accounts -FutureTransaction=Future transaction. Unable to reconcile. -SelectChequeTransactionAndGenerate=Select/filter the checks which are to be included in the check deposit receipt. Then, click on "Create". -InputReceiptNumber=Choose the bank statement related with the conciliation. Use a sortable numeric value: YYYYMM or YYYYMMDD -EventualyAddCategory=Eventually, specify a category in which to classify the records -ToConciliate=To reconcile? -ThenCheckLinesAndConciliate=Then, check the lines present in the bank statement and click -DefaultRIB=Default BAN -AllRIB=All BAN -LabelRIB=BAN Label -NoBANRecord=No BAN record -DeleteARib=Delete BAN record -ConfirmDeleteRib=Are you sure you want to delete this BAN record? -RejectCheck=Check returned -ConfirmRejectCheck=Are you sure you want to mark this check as rejected? -RejectCheckDate=Date the check was returned -CheckRejected=Check returned -CheckRejectedAndInvoicesReopened=Check returned and invoices re-open -BankAccountModelModule=Document templates for bank accounts -DocumentModelSepaMandate=Template of SEPA mandate. Useful for European countries in EEC only. -DocumentModelBan=Template to print a page with BAN information. -NewVariousPayment=New miscellaneous payment -VariousPayment=Miscellaneous payment -VariousPayments=Miscellaneous payments -ShowVariousPayment=Show miscellaneous payment -AddVariousPayment=Add miscellaneous payment -VariousPaymentId=Miscellaneous payment ID -VariousPaymentLabel=Miscellaneous payment label -ConfirmCloneVariousPayment=Confirm the clone of a miscellaneous payment -SEPAMandate=SEPA mandate -YourSEPAMandate=Your SEPA mandate -FindYourSEPAMandate=This is your SEPA mandate to authorize our company to make direct debit order to your bank. Return it signed (scan of the signed document) or send it by mail to -AutoReportLastAccountStatement=Automatically fill the field 'number of bank statement' with last statement number when making reconciliation -CashControl=POS cash desk control -NewCashFence=New cash desk opening or closing -BankColorizeMovement=Colorize movements -BankColorizeMovementDesc=If this function is enable, you can choose specific background color for debit or credit movements -BankColorizeMovementName1=Background color for debit movement -BankColorizeMovementName2=Background color for credit movement -IfYouDontReconcileDisableProperty=If you don't make the bank reconciliations on some bank accounts, disable the property "%s" on them to remove this warning. -NoBankAccountDefined=No bank account defined -NoRecordFoundIBankcAccount=No record found in bank account. Commonly, this occurs when a record has been deleted manually from the list of transaction in the bank account (for example during a reconciliation of the bank account). Another reason is that the payment was recorded when the module "%s" was disabled. diff --git a/htdocs/langs/ar_IQ/bills.lang b/htdocs/langs/ar_IQ/bills.lang index 7b8c997d2e6..a1d32f56bd5 100644 --- a/htdocs/langs/ar_IQ/bills.lang +++ b/htdocs/langs/ar_IQ/bills.lang @@ -1,593 +1,2 @@ # Dolibarr language file - Source file is en_US - bills -Bill=Invoice -Bills=Invoices -BillsCustomers=Customer invoices -BillsCustomer=Customer invoice -BillsSuppliers=Vendor invoices -BillsCustomersUnpaid=Unpaid customer invoices -BillsCustomersUnpaidForCompany=Unpaid customer invoices for %s -BillsSuppliersUnpaid=Unpaid vendor invoices -BillsSuppliersUnpaidForCompany=Unpaid vendors invoices for %s -BillsLate=Late payments -BillsStatistics=Customers invoices statistics -BillsStatisticsSuppliers=Vendors invoices statistics -DisabledBecauseDispatchedInBookkeeping=Disabled because invoice was dispatched into bookkeeping -DisabledBecauseNotLastInvoice=Disabled because invoice is not erasable. Some invoices were recorded after this one and it will create holes in the counter. -DisabledBecauseNotErasable=Disabled because cannot be erased -InvoiceStandard=Standard invoice -InvoiceStandardAsk=Standard invoice -InvoiceStandardDesc=This kind of invoice is the common invoice. -InvoiceDeposit=Down payment invoice -InvoiceDepositAsk=Down payment invoice -InvoiceDepositDesc=This kind of invoice is done when a down payment has been received. -InvoiceProForma=Proforma invoice -InvoiceProFormaAsk=Proforma invoice -InvoiceProFormaDesc=Proforma invoice is an image of a true invoice but has no accountancy value. -InvoiceReplacement=Replacement invoice -InvoiceReplacementAsk=Replacement invoice for invoice -InvoiceReplacementDesc=Replacement invoice is used to completely replace an invoice with no payment already received.

    Note: Only invoices with no payment on it can be replaced. If the invoice you replace is not yet closed, it will be automatically closed to 'abandoned'. -InvoiceAvoir=Credit note -InvoiceAvoirAsk=Credit note to correct invoice -InvoiceAvoirDesc=The credit note is a negative invoice used to correct the fact that an invoice shows an amount that differs from the amount actually paid (eg the customer paid too much by mistake, or will not pay the complete amount since some products were returned). -invoiceAvoirWithLines=Create Credit Note with lines from the origin invoice -invoiceAvoirWithPaymentRestAmount=Create Credit Note with remaining unpaid of origin invoice -invoiceAvoirLineWithPaymentRestAmount=Credit Note for remaining unpaid amount -ReplaceInvoice=Replace invoice %s -ReplacementInvoice=Replacement invoice -ReplacedByInvoice=Replaced by invoice %s -ReplacementByInvoice=Replaced by invoice -CorrectInvoice=Correct invoice %s -CorrectionInvoice=Correction invoice -UsedByInvoice=Used to pay invoice %s -ConsumedBy=Consumed by -NotConsumed=Not consumed -NoReplacableInvoice=No replaceable invoices -NoInvoiceToCorrect=No invoice to correct -InvoiceHasAvoir=Was source of one or several credit notes -CardBill=Invoice card -PredefinedInvoices=Predefined Invoices -Invoice=Invoice -PdfInvoiceTitle=Invoice -Invoices=Invoices -InvoiceLine=Invoice line -InvoiceCustomer=Customer invoice -CustomerInvoice=Customer invoice -CustomersInvoices=Customer invoices -SupplierInvoice=Vendor invoice -SuppliersInvoices=Vendor invoices -SupplierInvoiceLines=Vendor invoice lines -SupplierBill=Vendor invoice -SupplierBills=Vendor invoices -Payment=Payment -PaymentBack=Refund -CustomerInvoicePaymentBack=Refund -Payments=Payments -PaymentsBack=Refunds -paymentInInvoiceCurrency=in invoices currency -PaidBack=Paid back -DeletePayment=Delete payment -ConfirmDeletePayment=Are you sure you want to delete this payment? -ConfirmConvertToReduc=Do you want to convert this %s into an available credit? -ConfirmConvertToReduc2=The amount will be saved among all discounts and could be used as a discount for a current or a future invoice for this customer. -ConfirmConvertToReducSupplier=Do you want to convert this %s into an available credit? -ConfirmConvertToReducSupplier2=The amount will be saved among all discounts and could be used as a discount for a current or a future invoice for this vendor. -SupplierPayments=Vendor payments -ReceivedPayments=Received payments -ReceivedCustomersPayments=Payments received from customers -PayedSuppliersPayments=Payments paid to vendors -ReceivedCustomersPaymentsToValid=Received customers payments to validate -PaymentsReportsForYear=Payments reports for %s -PaymentsReports=Payments reports -PaymentsAlreadyDone=Payments already done -PaymentsBackAlreadyDone=Refunds already done -PaymentRule=Payment rule -PaymentMode=Payment Type -DefaultPaymentMode=Default Payment Type -DefaultBankAccount=Default Bank Account -PaymentTypeDC=Debit/Credit Card -PaymentTypePP=PayPal -IdPaymentMode=Payment Type (id) -CodePaymentMode=Payment Type (code) -LabelPaymentMode=Payment Type (label) -PaymentModeShort=Payment Type -PaymentTerm=Payment Term -PaymentConditions=Payment Terms -PaymentConditionsShort=Payment Terms -PaymentAmount=Payment amount -PaymentHigherThanReminderToPay=Payment higher than reminder to pay -HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay.
    Edit your entry, otherwise confirm and consider creating a credit note for the excess received for each overpaid invoice. -HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay.
    Edit your entry, otherwise confirm and consider creating a credit note for the excess paid for each overpaid invoice. -ClassifyPaid=Classify 'Paid' -ClassifyUnPaid=Classify 'Unpaid' -ClassifyPaidPartially=Classify 'Paid partially' -ClassifyCanceled=Classify 'Abandoned' -ClassifyClosed=Classify 'Closed' -ClassifyUnBilled=Classify 'Unbilled' -CreateBill=Create Invoice -CreateCreditNote=Create credit note -AddBill=Create invoice or credit note -AddToDraftInvoices=Add to draft invoice -DeleteBill=Delete invoice -SearchACustomerInvoice=Search for a customer invoice -SearchASupplierInvoice=Search for a vendor invoice -CancelBill=Cancel an invoice -SendRemindByMail=Send reminder by email -DoPayment=Enter payment -DoPaymentBack=Enter refund -ConvertToReduc=Mark as credit available -ConvertExcessReceivedToReduc=Convert excess received into available credit -ConvertExcessPaidToReduc=Convert excess paid into available discount -EnterPaymentReceivedFromCustomer=Enter payment received from customer -EnterPaymentDueToCustomer=Make payment due to customer -DisabledBecauseRemainderToPayIsZero=Disabled because remaining unpaid is zero -PriceBase=Base price -BillStatus=Invoice status -StatusOfGeneratedInvoices=Status of generated invoices -BillStatusDraft=Draft (needs to be validated) -BillStatusPaid=Paid -BillStatusPaidBackOrConverted=Credit note refund or marked as credit available -BillStatusConverted=Paid (ready for consumption in final invoice) -BillStatusCanceled=Abandoned -BillStatusValidated=Validated (needs to be paid) -BillStatusStarted=Started -BillStatusNotPaid=Not paid -BillStatusNotRefunded=Not refunded -BillStatusClosedUnpaid=Closed (unpaid) -BillStatusClosedPaidPartially=Paid (partially) -BillShortStatusDraft=Draft -BillShortStatusPaid=Paid -BillShortStatusPaidBackOrConverted=Refunded or converted -Refunded=Refunded -BillShortStatusConverted=Paid -BillShortStatusCanceled=Abandoned -BillShortStatusValidated=Validated -BillShortStatusStarted=Started -BillShortStatusNotPaid=Not paid -BillShortStatusNotRefunded=Not refunded -BillShortStatusClosedUnpaid=Closed -BillShortStatusClosedPaidPartially=Paid (partially) -PaymentStatusToValidShort=To validate -ErrorVATIntraNotConfigured=Intra-Community VAT number not yet defined -ErrorNoPaiementModeConfigured=No default payment type defined. Go to Invoice module setup to fix this. -ErrorCreateBankAccount=Create a bank account, then go to Setup panel of Invoice module to define payment types -ErrorBillNotFound=Invoice %s does not exist -ErrorInvoiceAlreadyReplaced=Error, you tried to validate an invoice to replace invoice %s. But this one has already been replaced by invoice %s. -ErrorDiscountAlreadyUsed=Error, discount already used -ErrorInvoiceAvoirMustBeNegative=Error, correct invoice must have a negative amount -ErrorInvoiceOfThisTypeMustBePositive=Error, this type of invoice must have an amount excluding tax positive (or null) -ErrorCantCancelIfReplacementInvoiceNotValidated=Error, can't cancel an invoice that has been replaced by another invoice that is still in draft status -ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved=This part or another is already used so discount series cannot be removed. -BillFrom=From -BillTo=To -ActionsOnBill=Actions on invoice -RecurringInvoiceTemplate=Template / Recurring invoice -NoQualifiedRecurringInvoiceTemplateFound=No recurring template invoice qualified for generation. -FoundXQualifiedRecurringInvoiceTemplate=Found %s recurring template invoice(s) qualified for generation. -NotARecurringInvoiceTemplate=Not a recurring template invoice -NewBill=New invoice -LastBills=Latest %s invoices -LatestTemplateInvoices=Latest %s template invoices -LatestCustomerTemplateInvoices=Latest %s customer template invoices -LatestSupplierTemplateInvoices=Latest %s vendor template invoices -LastCustomersBills=Latest %s customer invoices -LastSuppliersBills=Latest %s vendor invoices -AllBills=All invoices -AllCustomerTemplateInvoices=All template invoices -OtherBills=Other invoices -DraftBills=Draft invoices -CustomersDraftInvoices=Customer draft invoices -SuppliersDraftInvoices=Vendor draft invoices -Unpaid=Unpaid -ErrorNoPaymentDefined=Error No payment defined -ConfirmDeleteBill=Are you sure you want to delete this invoice? -ConfirmValidateBill=Are you sure you want to validate this invoice with reference %s? -ConfirmUnvalidateBill=Are you sure you want to change invoice %s to draft status? -ConfirmClassifyPaidBill=Are you sure you want to change invoice %s to status paid? -ConfirmCancelBill=Are you sure you want to cancel invoice %s? -ConfirmCancelBillQuestion=Why do you want to classify this invoice 'abandoned'? -ConfirmClassifyPaidPartially=Are you sure you want to change invoice %s to status paid? -ConfirmClassifyPaidPartiallyQuestion=This invoice has not been paid completely. What is the reason for closing this invoice? -ConfirmClassifyPaidPartiallyReasonAvoir=Remaining unpaid (%s %s) is a discount granted because payment was made before term. I regularize the VAT with a credit note. -ConfirmClassifyPaidPartiallyReasonDiscount=Remaining unpaid (%s %s) is a discount granted because payment was made before term. -ConfirmClassifyPaidPartiallyReasonDiscountNoVat=Remaining unpaid (%s %s) is a discount granted because payment was made before term. I accept to lose the VAT on this discount. -ConfirmClassifyPaidPartiallyReasonDiscountVat=Remaining unpaid (%s %s) is a discount granted because payment was made before term. I recover the VAT on this discount without a credit note. -ConfirmClassifyPaidPartiallyReasonBadCustomer=Bad customer -ConfirmClassifyPaidPartiallyReasonProductReturned=Products partially returned -ConfirmClassifyPaidPartiallyReasonOther=Amount abandoned for other reason -ConfirmClassifyPaidPartiallyReasonDiscountNoVatDesc=This choice is possible if your invoice has been provided with suitable comments. (Example «Only the tax corresponding to the price that has been actually paid gives rights to deduction») -ConfirmClassifyPaidPartiallyReasonDiscountVatDesc=In some countries, this choice might be possible only if your invoice contains correct notes. -ConfirmClassifyPaidPartiallyReasonAvoirDesc=Use this choice if all other does not suit -ConfirmClassifyPaidPartiallyReasonBadCustomerDesc=A bad customer is a customer that refuses to pay his debt. -ConfirmClassifyPaidPartiallyReasonProductReturnedDesc=This choice is used when payment is not complete because some of products were returned -ConfirmClassifyPaidPartiallyReasonOtherDesc=Use this choice if all others are not suitable, for example in following situation:
    - payment not complete because some products were shipped back
    - amount claimed too important because a discount was forgotten
    In all cases, amount over-claimed must be corrected in accountancy system by creating a credit note. -ConfirmClassifyAbandonReasonOther=Other -ConfirmClassifyAbandonReasonOtherDesc=This choice will be used in all other cases. For example because you plan to create a replacing invoice. -ConfirmCustomerPayment=Do you confirm this payment input for %s %s? -ConfirmSupplierPayment=Do you confirm this payment input for %s %s? -ConfirmValidatePayment=Are you sure you want to validate this payment? No change can be made once payment is validated. -ValidateBill=Validate invoice -UnvalidateBill=Unvalidate invoice -NumberOfBills=No. of invoices -NumberOfBillsByMonth=No. of invoices per month -AmountOfBills=Amount of invoices -AmountOfBillsHT=Amount of invoices (net of tax) -AmountOfBillsByMonthHT=Amount of invoices by month (net of tax) -UseSituationInvoices=Allow situation invoice -UseSituationInvoicesCreditNote=Allow situation invoice credit note -Retainedwarranty=Retained warranty -AllowedInvoiceForRetainedWarranty=Retained warranty usable on the following types of invoices -RetainedwarrantyDefaultPercent=Retained warranty default percent -RetainedwarrantyOnlyForSituation=Make "retained warranty" available only for situation invoices -RetainedwarrantyOnlyForSituationFinal=On situation invoices the global "retained warranty" deduction is applied only on the final situation -ToPayOn=To pay on %s -toPayOn=to pay on %s -RetainedWarranty=Retained Warranty -PaymentConditionsShortRetainedWarranty=Retained warranty payment terms -DefaultPaymentConditionsRetainedWarranty=Default retained warranty payment terms -setPaymentConditionsShortRetainedWarranty=Set retained warranty payment terms -setretainedwarranty=Set retained warranty -setretainedwarrantyDateLimit=Set retained warranty date limit -RetainedWarrantyDateLimit=Retained warranty date limit -RetainedWarrantyNeed100Percent=The situation invoice need to be at 100%% progress to be displayed on PDF -AlreadyPaid=Already paid -AlreadyPaidBack=Already paid back -AlreadyPaidNoCreditNotesNoDeposits=Already paid (without credit notes and down payments) -Abandoned=Abandoned -RemainderToPay=Remaining unpaid -RemainderToTake=Remaining amount to take -RemainderToPayBack=Remaining amount to refund -Rest=Pending -AmountExpected=Amount claimed -ExcessReceived=Excess received -ExcessPaid=Excess paid -EscompteOffered=Discount offered (payment before term) -EscompteOfferedShort=Discount -SendBillRef=Submission of invoice %s -SendReminderBillRef=Submission of invoice %s (reminder) -NoDraftBills=No draft invoices -NoOtherDraftBills=No other draft invoices -NoDraftInvoices=No draft invoices -RefBill=Invoice ref -ToBill=To bill -RemainderToBill=Remainder to bill -SendBillByMail=Send invoice by email -SendReminderBillByMail=Send reminder by email -RelatedCommercialProposals=Related commercial proposals -RelatedRecurringCustomerInvoices=Related recurring customer invoices -MenuToValid=To valid -DateMaxPayment=Payment due on -DateInvoice=Invoice date -DatePointOfTax=Point of tax -NoInvoice=No invoice -NoOpenInvoice=No open invoice -ClassifyBill=Classify invoice -SupplierBillsToPay=Unpaid vendor invoices -CustomerBillsUnpaid=Unpaid customer invoices -NonPercuRecuperable=Non-recoverable -SetConditions=Set Payment Terms -SetMode=Set Payment Type -SetRevenuStamp=Set revenue stamp -Billed=Billed -RecurringInvoices=Recurring invoices -RepeatableInvoice=Template invoice -RepeatableInvoices=Template invoices -Repeatable=Template -Repeatables=Templates -ChangeIntoRepeatableInvoice=Convert into template invoice -CreateRepeatableInvoice=Create template invoice -CreateFromRepeatableInvoice=Create from template invoice -CustomersInvoicesAndInvoiceLines=Customer invoices and invoice details -CustomersInvoicesAndPayments=Customer invoices and payments -ExportDataset_invoice_1=Customer invoices and invoice details -ExportDataset_invoice_2=Customer invoices and payments -ProformaBill=Proforma Bill: -Reduction=Reduction -ReductionShort=Disc. -Reductions=Reductions -ReductionsShort=Disc. -Discounts=Discounts -AddDiscount=Create discount -AddRelativeDiscount=Create relative discount -EditRelativeDiscount=Edit relative discount -AddGlobalDiscount=Create absolute discount -EditGlobalDiscounts=Edit absolute discounts -AddCreditNote=Create credit note -ShowDiscount=Show discount -ShowReduc=Show the discount -ShowSourceInvoice=Show the source invoice -RelativeDiscount=Relative discount -GlobalDiscount=Global discount -CreditNote=Credit note -CreditNotes=Credit notes -CreditNotesOrExcessReceived=Credit notes or excess received -Deposit=Down payment -Deposits=Down payments -DiscountFromCreditNote=Discount from credit note %s -DiscountFromDeposit=Down payments from invoice %s -DiscountFromExcessReceived=Payments in excess of invoice %s -DiscountFromExcessPaid=Payments in excess of invoice %s -AbsoluteDiscountUse=This kind of credit can be used on invoice before its validation -CreditNoteDepositUse=Invoice must be validated to use this kind of credits -NewGlobalDiscount=New absolute discount -NewRelativeDiscount=New relative discount -DiscountType=Discount type -NoteReason=Note/Reason -ReasonDiscount=Reason -DiscountOfferedBy=Granted by -DiscountStillRemaining=Discounts or credits available -DiscountAlreadyCounted=Discounts or credits already consumed -CustomerDiscounts=Customer discounts -SupplierDiscounts=Vendors discounts -BillAddress=Bill address -HelpEscompte=This discount is a discount granted to customer because payment was made before term. -HelpAbandonBadCustomer=This amount has been abandoned (customer said to be a bad customer) and is considered as an exceptional loss. -HelpAbandonOther=This amount has been abandoned since it was an error (wrong customer or invoice replaced by another for example) -IdSocialContribution=Social/fiscal tax payment id -PaymentId=Payment id -PaymentRef=Payment ref. -InvoiceId=Invoice id -InvoiceRef=Invoice ref. -InvoiceDateCreation=Invoice creation date -InvoiceStatus=Invoice status -InvoiceNote=Invoice note -InvoicePaid=Invoice paid -InvoicePaidCompletely=Paid completely -InvoicePaidCompletelyHelp=Invoice that are paid completely. This excludes invoices that are paid partially. To get list of all 'Closed' or non 'Closed' invoices, prefer to use a filter on the invoice status. -OrderBilled=Order billed -DonationPaid=Donation paid -PaymentNumber=Payment number -RemoveDiscount=Remove discount -WatermarkOnDraftBill=Watermark on draft invoices (nothing if empty) -InvoiceNotChecked=No invoice selected -ConfirmCloneInvoice=Are you sure you want to clone this invoice %s? -DisabledBecauseReplacedInvoice=Action disabled because invoice has been replaced -DescTaxAndDividendsArea=This area presents a summary of all payments made for special expenses. Only records with payments during the fixed year are included here. -NbOfPayments=No. of payments -SplitDiscount=Split discount in two -ConfirmSplitDiscount=Are you sure you want to split this discount of %s %s into two smaller discounts? -TypeAmountOfEachNewDiscount=Input amount for each of two parts: -TotalOfTwoDiscountMustEqualsOriginal=The total of the two new discounts must be equal to the original discount amount. -ConfirmRemoveDiscount=Are you sure you want to remove this discount? -RelatedBill=Related invoice -RelatedBills=Related invoices -RelatedCustomerInvoices=Related customer invoices -RelatedSupplierInvoices=Related vendor invoices -LatestRelatedBill=Latest related invoice -WarningBillExist=Warning, one or more invoices already exist -MergingPDFTool=Merging PDF tool -AmountPaymentDistributedOnInvoice=Payment amount distributed on invoice -PaymentOnDifferentThirdBills=Allow payments on different third parties bills but same parent company -PaymentNote=Payment note -ListOfPreviousSituationInvoices=List of previous situation invoices -ListOfNextSituationInvoices=List of next situation invoices -ListOfSituationInvoices=List of situation invoices -CurrentSituationTotal=Total current situation -DisabledBecauseNotEnouthCreditNote=To remove a situation invoice from cycle, this invoice's credit note total must cover this invoice total -RemoveSituationFromCycle=Remove this invoice from cycle -ConfirmRemoveSituationFromCycle=Remove this invoice %s from cycle ? -ConfirmOuting=Confirm outing -FrequencyPer_d=Every %s days -FrequencyPer_m=Every %s months -FrequencyPer_y=Every %s years -FrequencyUnit=Frequency unit -toolTipFrequency=Examples:
    Set 7, Day: give a new invoice every 7 days
    Set 3, Month: give a new invoice every 3 month -NextDateToExecution=Date for next invoice generation -NextDateToExecutionShort=Date next gen. -DateLastGeneration=Date of latest generation -DateLastGenerationShort=Date latest gen. -MaxPeriodNumber=Max. number of invoice generation -NbOfGenerationDone=Number of invoice generation already done -NbOfGenerationOfRecordDone=Number of record generation already done -NbOfGenerationDoneShort=Number of generation done -MaxGenerationReached=Maximum number of generations reached -InvoiceAutoValidate=Validate invoices automatically -GeneratedFromRecurringInvoice=Generated from template recurring invoice %s -DateIsNotEnough=Date not reached yet -InvoiceGeneratedFromTemplate=Invoice %s generated from recurring template invoice %s -GeneratedFromTemplate=Generated from template invoice %s -WarningInvoiceDateInFuture=Warning, the invoice date is higher than current date -WarningInvoiceDateTooFarInFuture=Warning, the invoice date is too far from current date -ViewAvailableGlobalDiscounts=View available discounts -GroupPaymentsByModOnReports=Group payments by mode on reports -# PaymentConditions -Statut=Status -PaymentConditionShortRECEP=Due Upon Receipt -PaymentConditionRECEP=Due Upon Receipt -PaymentConditionShort30D=30 days -PaymentCondition30D=30 days -PaymentConditionShort30DENDMONTH=30 days of month-end -PaymentCondition30DENDMONTH=Within 30 days following the end of the month -PaymentConditionShort60D=60 days -PaymentCondition60D=60 days -PaymentConditionShort60DENDMONTH=60 days of month-end -PaymentCondition60DENDMONTH=Within 60 days following the end of the month -PaymentConditionShortPT_DELIVERY=Delivery -PaymentConditionPT_DELIVERY=On delivery -PaymentConditionShortPT_ORDER=Order -PaymentConditionPT_ORDER=On order -PaymentConditionShortPT_5050=50-50 -PaymentConditionPT_5050=50%% in advance, 50%% on delivery -PaymentConditionShort10D=10 days -PaymentCondition10D=10 days -PaymentConditionShort10DENDMONTH=10 days of month-end -PaymentCondition10DENDMONTH=Within 10 days following the end of the month -PaymentConditionShort14D=14 days -PaymentCondition14D=14 days -PaymentConditionShort14DENDMONTH=14 days of month-end -PaymentCondition14DENDMONTH=Within 14 days following the end of the month -FixAmount=Fixed amount - 1 line with label '%s' -VarAmount=Variable amount (%% tot.) -VarAmountOneLine=Variable amount (%% tot.) - 1 line with label '%s' -VarAmountAllLines=Variable amount (%% tot.) - all lines from origin -# PaymentType -PaymentTypeVIR=Bank transfer -PaymentTypeShortVIR=Bank transfer -PaymentTypePRE=Direct debit payment order -PaymentTypeShortPRE=Debit payment order -PaymentTypeLIQ=Cash -PaymentTypeShortLIQ=Cash -PaymentTypeCB=Credit card -PaymentTypeShortCB=Credit card -PaymentTypeCHQ=Check -PaymentTypeShortCHQ=Check -PaymentTypeTIP=TIP (Documents against Payment) -PaymentTypeShortTIP=TIP Payment -PaymentTypeVAD=Online payment -PaymentTypeShortVAD=Online payment -PaymentTypeTRA=Bank draft -PaymentTypeShortTRA=Draft -PaymentTypeFAC=Factor -PaymentTypeShortFAC=Factor -BankDetails=Bank details -BankCode=Bank code -DeskCode=Branch code -BankAccountNumber=Account number -BankAccountNumberKey=Checksum -Residence=Address -IBANNumber=IBAN account number -IBAN=IBAN -CustomerIBAN=IBAN of customer -SupplierIBAN=IBAN of vendor -BIC=BIC/SWIFT -BICNumber=BIC/SWIFT code -ExtraInfos=Extra infos -RegulatedOn=Regulated on -ChequeNumber=Check N° -ChequeOrTransferNumber=Check/Transfer N° -ChequeBordereau=Check schedule -ChequeMaker=Check/Transfer sender -ChequeBank=Bank of Check -CheckBank=Check -NetToBePaid=Net to be paid -PhoneNumber=Tel -FullPhoneNumber=Telephone -TeleFax=Fax -PrettyLittleSentence=Accept the amount of payments due by checks issued in my name as a Member of an accounting association approved by the Fiscal Administration. -IntracommunityVATNumber=Intra-Community VAT ID -PaymentByChequeOrderedTo=Check payments (including tax) are payable to %s, send to -PaymentByChequeOrderedToShort=Check payments (incl. tax) are payable to -SendTo=sent to -PaymentByTransferOnThisBankAccount=Payment by transfer to the following bank account -VATIsNotUsedForInvoice=* Non applicable VAT art-293B of CGI -LawApplicationPart1=By application of the law 80.335 of 12/05/80 -LawApplicationPart2=the goods remain the property of -LawApplicationPart3=the seller until full payment of -LawApplicationPart4=their price. -LimitedLiabilityCompanyCapital=SARL with Capital of -UseLine=Apply -UseDiscount=Use discount -UseCredit=Use credit -UseCreditNoteInInvoicePayment=Reduce amount to pay with this credit -MenuChequeDeposits=Check Deposits -MenuCheques=Checks -MenuChequesReceipts=Check receipts -NewChequeDeposit=New deposit -ChequesReceipts=Check receipts -ChequesArea=Check deposits area -ChequeDeposits=Check deposits -Cheques=Checks -DepositId=Id deposit -NbCheque=Number of checks -CreditNoteConvertedIntoDiscount=This %s has been converted into %s -UsBillingContactAsIncoiveRecipientIfExist=Use contact/address with type 'billing contact' instead of third-party address as recipient for invoices -ShowUnpaidAll=Show all unpaid invoices -ShowUnpaidLateOnly=Show late unpaid invoices only -PaymentInvoiceRef=Payment invoice %s -ValidateInvoice=Validate invoice -ValidateInvoices=Validate invoices -Cash=Cash -Reported=Delayed -DisabledBecausePayments=Not possible since there are some payments -CantRemovePaymentWithOneInvoicePaid=Can't remove payment since there is at least one invoice classified paid -CantRemovePaymentVATPaid=Can't remove payment since VAT declaration is classified paid -CantRemovePaymentSalaryPaid=Can't remove payment since salary is classified paid -ExpectedToPay=Expected payment -CantRemoveConciliatedPayment=Can't remove reconciled payment -PayedByThisPayment=Paid by this payment -ClosePaidInvoicesAutomatically=Classify automatically all standard, down payment or replacement invoices as "Paid" when payment is done entirely. -ClosePaidCreditNotesAutomatically=Classify automatically all credit notes as "Paid" when refund is done entirely. -ClosePaidContributionsAutomatically=Classify automatically all social or fiscal contributions as "Paid" when payment is done entirely. -ClosePaidVATAutomatically=Classify automatically VAT declaration as "Paid" when payment is done entirely. -ClosePaidSalaryAutomatically=Classify automatically salary as "Paid" when payment is done entirely. -AllCompletelyPayedInvoiceWillBeClosed=All invoices with no remainder to pay will be automatically closed with status "Paid". -ToMakePayment=Pay -ToMakePaymentBack=Pay back -ListOfYourUnpaidInvoices=List of unpaid invoices -NoteListOfYourUnpaidInvoices=Note: This list contains only invoices for third parties you are linked to as a sale representative. -RevenueStamp=Tax stamp -YouMustCreateInvoiceFromThird=This option is only available when creating an invoice from tab "Customer" of third party -YouMustCreateInvoiceFromSupplierThird=This option is only available when creating an invoice from tab "Vendor" of third party -YouMustCreateStandardInvoiceFirstDesc=You have to create a standard invoice first and convert it to "template" to create a new template invoice -PDFCrabeDescription=Invoice PDF template Crabe. A complete invoice template (old implementation of Sponge template) -PDFSpongeDescription=Invoice PDF template Sponge. A complete invoice template -PDFCrevetteDescription=Invoice PDF template Crevette. A complete invoice template for situation invoices -TerreNumRefModelDesc1=Return number in the format %syymm-nnnn for standard invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequencial auto-incrementing number with no break and no return to 0 -MarsNumRefModelDesc1=Return number in the format %syymm-nnnn for standard invoices, %syymm-nnnn for replacement invoices, %syymm-nnnn for down payment invoices and %syymm-nnnn for credit notes where yy is year, mm is month and nnnn is a sequencial auto-incrementing number with no break and no return to 0 -TerreNumRefModelError=A bill starting with $syymm already exists and is not compatible with this model of sequence. Remove it or rename it to activate this module. -CactusNumRefModelDesc1=Return number in the format %syymm-nnnn for standard invoices, %syymm-nnnn for credit notes and %syymm-nnnn for down payment invoices where yy is year, mm is month and nnnn is a sequencial auto-incrementing number with no break and no return to 0 -EarlyClosingReason=Early closing reason -EarlyClosingComment=Early closing note -##### Types de contacts ##### -TypeContact_facture_internal_SALESREPFOLL=Representative following-up customer invoice -TypeContact_facture_external_BILLING=Customer invoice contact -TypeContact_facture_external_SHIPPING=Customer shipping contact -TypeContact_facture_external_SERVICE=Customer service contact -TypeContact_invoice_supplier_internal_SALESREPFOLL=Representative following-up vendor invoice -TypeContact_invoice_supplier_external_BILLING=Vendor invoice contact -TypeContact_invoice_supplier_external_SHIPPING=Vendor shipping contact -TypeContact_invoice_supplier_external_SERVICE=Vendor service contact -# Situation invoices -InvoiceFirstSituationAsk=First situation invoice -InvoiceFirstSituationDesc=The situation invoices are tied to situations related to a progression, for example the progression of a construction. Each situation is tied to an invoice. -InvoiceSituation=Situation invoice -PDFInvoiceSituation=Situation invoice -InvoiceSituationAsk=Invoice following the situation -InvoiceSituationDesc=Create a new situation following an already existing one -SituationAmount=Situation invoice amount(net) -SituationDeduction=Situation subtraction -ModifyAllLines=Modify all lines -CreateNextSituationInvoice=Create next situation -ErrorFindNextSituationInvoice=Error unable to find next situation cycle ref -ErrorOutingSituationInvoiceOnUpdate=Unable to outing this situation invoice. -ErrorOutingSituationInvoiceCreditNote=Unable to outing linked credit note. -NotLastInCycle=This invoice is not the latest in cycle and must not be modified. -DisabledBecauseNotLastInCycle=The next situation already exists. -DisabledBecauseFinal=This situation is final. -situationInvoiceShortcode_AS=AS -situationInvoiceShortcode_S=S -CantBeLessThanMinPercent=The progress can't be smaller than its value in the previous situation. -NoSituations=No open situations -InvoiceSituationLast=Final and general invoice -PDFCrevetteSituationNumber=Situation N°%s -PDFCrevetteSituationInvoiceLineDecompte=Situation invoice - COUNT -PDFCrevetteSituationInvoiceTitle=Situation invoice -PDFCrevetteSituationInvoiceLine=Situation N°%s: Inv. N°%s on %s -TotalSituationInvoice=Total situation -invoiceLineProgressError=Invoice line progress can't be greater than or equal to the next invoice line -updatePriceNextInvoiceErrorUpdateline=Error: update price on invoice line: %s -ToCreateARecurringInvoice=To create a recurring invoice for this contract, first create this draft invoice, then convert it into an invoice template and define the frequency for generation of future invoices. -ToCreateARecurringInvoiceGene=To generate future invoices regularly and manually, just go on menu %s - %s - %s. -ToCreateARecurringInvoiceGeneAuto=If you need to have such invoices generated automatically, ask your administrator to enable and setup module %s. Note that both methods (manual and automatic) can be used together with no risk of duplication. -DeleteRepeatableInvoice=Delete template invoice -ConfirmDeleteRepeatableInvoice=Are your sure you want to delete the template invoice? CreateOneBillByThird=Create one invoice per third party (otherwise, one invoice per order) -BillCreated=%s invoice(s) generated -BillXCreated=Invoice %s generated -StatusOfGeneratedDocuments=Status of document generation -DoNotGenerateDoc=Do not generate document file -AutogenerateDoc=Auto generate document file -AutoFillDateFrom=Set start date for service line with invoice date -AutoFillDateFromShort=Set start date -AutoFillDateTo=Set end date for service line with next invoice date -AutoFillDateToShort=Set end date -MaxNumberOfGenerationReached=Max number of gen. reached -BILL_DELETEInDolibarr=Invoice deleted -BILL_SUPPLIER_DELETEInDolibarr=Supplier invoice deleted -UnitPriceXQtyLessDiscount=Unit price x Qty - Discount -CustomersInvoicesArea=Customer billing area -SupplierInvoicesArea=Supplier billing area -FacParentLine=Invoice Line Parent -SituationTotalRayToRest=Remainder to pay without taxe -PDFSituationTitle=Situation n° %d -SituationTotalProgress=Total progress %d %% -SearchUnpaidInvoicesWithDueDate=Search unpaid invoices with a due date = %s diff --git a/htdocs/langs/ar_IQ/blockedlog.lang b/htdocs/langs/ar_IQ/blockedlog.lang deleted file mode 100644 index 44cb183050a..00000000000 --- a/htdocs/langs/ar_IQ/blockedlog.lang +++ /dev/null @@ -1,54 +0,0 @@ -BlockedLog=Unalterable Logs -Field=Field -BlockedLogDesc=This module tracks some events into an unalterable log (that you can't modify once recorded) into a block chain, in real time. This module provides compatibility with requirements of laws of some countries (like France with the law Finance 2016 - Norme NF525). -Fingerprints=Archived events and fingerprints -FingerprintsDesc=This is the tool to browse or extract the unalterable logs. Unalterable logs are generated and archived locally into a dedicated table, in real time when you record a business event. You can use this tool to export this archive and save it into an external support (some countries, like France, ask that you do it every year). Note that, there is no feature to purge this log and every change tried to be done directly into this log (by a hacker for example) will be reported with a non-valid fingerprint. If you really need to purge this table because you used your application for a demo/test purpose and want to clean your data to start your production, you can ask your reseller or integrator to reset your database (all your data will be removed). -CompanyInitialKey=Company initial key (hash of genesis block) -BrowseBlockedLog=Unalterable logs -ShowAllFingerPrintsMightBeTooLong=Show all archived logs (might be long) -ShowAllFingerPrintsErrorsMightBeTooLong=Show all non-valid archive logs (might be long) -DownloadBlockChain=Download fingerprints -KoCheckFingerprintValidity=Archived log entry is not valid. It means someone (a hacker?) has modified some data of this record after it was recorded, or has erased the previous archived record (check that line with previous # exists) or has modified checksum of the previous record. -OkCheckFingerprintValidity=Archived log record is valid. The data on this line was not modified and the entry follows the previous one. -OkCheckFingerprintValidityButChainIsKo=Archived log seems valid compared to previous one but the chain was corrupted previously. -AddedByAuthority=Stored into remote authority -NotAddedByAuthorityYet=Not yet stored into remote authority -ShowDetails=Show stored details -logPAYMENT_VARIOUS_CREATE=Payment (not assigned to an invoice) created -logPAYMENT_VARIOUS_MODIFY=Payment (not assigned to an invoice) modified -logPAYMENT_VARIOUS_DELETE=Payment (not assigned to an invoice) logical deletion -logPAYMENT_ADD_TO_BANK=Payment added to bank -logPAYMENT_CUSTOMER_CREATE=Customer payment created -logPAYMENT_CUSTOMER_DELETE=Customer payment logical deletion -logDONATION_PAYMENT_CREATE=Donation payment created -logDONATION_PAYMENT_DELETE=Donation payment logical deletion -logBILL_PAYED=Customer invoice paid -logBILL_UNPAYED=Customer invoice set unpaid -logBILL_VALIDATE=Customer invoice validated -logBILL_SENTBYMAIL=Customer invoice send by mail -logBILL_DELETE=Customer invoice logically deleted -logMODULE_RESET=Module BlockedLog was disabled -logMODULE_SET=Module BlockedLog was enabled -logDON_VALIDATE=Donation validated -logDON_MODIFY=Donation modified -logDON_DELETE=Donation logical deletion -logMEMBER_SUBSCRIPTION_CREATE=Member subscription created -logMEMBER_SUBSCRIPTION_MODIFY=Member subscription modified -logMEMBER_SUBSCRIPTION_DELETE=Member subscription logical deletion -logCASHCONTROL_VALIDATE=Cash desk closing recording -BlockedLogBillDownload=Customer invoice download -BlockedLogBillPreview=Customer invoice preview -BlockedlogInfoDialog=Log Details -ListOfTrackedEvents=List of tracked events -Fingerprint=Fingerprint -DownloadLogCSV=Export archived logs (CSV) -logDOC_PREVIEW=Preview of a validated document in order to print or download -logDOC_DOWNLOAD=Download of a validated document in order to print or send -DataOfArchivedEvent=Full datas of archived event -ImpossibleToReloadObject=Original object (type %s, id %s) not linked (see 'Full datas' column to get unalterable saved data) -BlockedLogAreRequiredByYourCountryLegislation=Unalterable Logs module may be required by the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they can not be validated by a tax audit. -BlockedLogActivatedBecauseRequiredByYourCountryLegislation=Unalterable Logs module was activated because of the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they cannot be validated by a tax audit. -BlockedLogDisableNotAllowedForCountry=List of countries where usage of this module is mandatory (just to prevent to disable the module by error, if your country is in this list, disable of module is not possible without editing this list first. Note also that enabling/disabling this module will keep a track into the unalterable log). -OnlyNonValid=Non-valid -TooManyRecordToScanRestrictFilters=Too many records to scan/analyze. Please restrict list with more restrictive filters. -RestrictYearToExport=Restrict month / year to export diff --git a/htdocs/langs/ar_IQ/bookmarks.lang b/htdocs/langs/ar_IQ/bookmarks.lang deleted file mode 100644 index 87466cadcfa..00000000000 --- a/htdocs/langs/ar_IQ/bookmarks.lang +++ /dev/null @@ -1,21 +0,0 @@ -# Dolibarr language file - Source file is en_US - marque pages -AddThisPageToBookmarks=Add current page to bookmarks -Bookmark=Bookmark -Bookmarks=Bookmarks -ListOfBookmarks=List of bookmarks -EditBookmarks=List/edit bookmarks -NewBookmark=New bookmark -ShowBookmark=Show bookmark -OpenANewWindow=Open a new tab -ReplaceWindow=Replace current tab -BookmarkTargetNewWindowShort=New tab -BookmarkTargetReplaceWindowShort=Current tab -BookmarkTitle=Bookmark name -UrlOrLink=URL -BehaviourOnClick=Behaviour when a bookmark URL is selected -CreateBookmark=Create bookmark -SetHereATitleForLink=Set a name for the bookmark -UseAnExternalHttpLinkOrRelativeDolibarrLink=Use an external/absolute link (https://URL) or an internal/relative link (/DOLIBARR_ROOT/htdocs/...) -ChooseIfANewWindowMustBeOpenedOnClickOnBookmark=Choose if the linked page should open in the current tab or a new tab -BookmarksManagement=Bookmarks management -BookmarksMenuShortCut=Ctrl + shift + m diff --git a/htdocs/langs/ar_IQ/boxes.lang b/htdocs/langs/ar_IQ/boxes.lang deleted file mode 100644 index 710d49bfab6..00000000000 --- a/htdocs/langs/ar_IQ/boxes.lang +++ /dev/null @@ -1,120 +0,0 @@ -# Dolibarr language file - Source file is en_US - boxes -BoxDolibarrStateBoard=Statistics on main business objects in database -BoxLoginInformation=Login Information -BoxLastRssInfos=RSS Information -BoxLastProducts=Latest %s Products/Services -BoxProductsAlertStock=Stock alerts for products -BoxLastProductsInContract=Latest %s contracted products/services -BoxLastSupplierBills=Latest Vendor invoices -BoxLastCustomerBills=Latest Customer invoices -BoxOldestUnpaidCustomerBills=Oldest unpaid customer invoices -BoxOldestUnpaidSupplierBills=Oldest unpaid vendor invoices -BoxLastProposals=Latest commercial proposals -BoxLastProspects=Latest modified prospects -BoxLastCustomers=Latest modified customers -BoxLastSuppliers=Latest modified suppliers -BoxLastCustomerOrders=Latest sales orders -BoxLastActions=Latest actions -BoxLastContracts=Latest contracts -BoxLastContacts=Latest contacts/addresses -BoxLastMembers=Latest members -BoxLastModifiedMembers=Latest modified members -BoxLastMembersSubscriptions=Latest member subscriptions -BoxFicheInter=Latest interventions -BoxCurrentAccounts=Open accounts balance -BoxTitleMemberNextBirthdays=Birthdays of this month (members) -BoxTitleMembersByType=Members by type -BoxTitleMembersSubscriptionsByYear=Members Subscriptions by year -BoxTitleLastRssInfos=Latest %s news from %s -BoxTitleLastProducts=Products/Services: last %s modified -BoxTitleProductsAlertStock=Products: stock alert -BoxTitleLastSuppliers=Latest %s recorded suppliers -BoxTitleLastModifiedSuppliers=Vendors: last %s modified -BoxTitleLastModifiedCustomers=Customers: last %s modified -BoxTitleLastCustomersOrProspects=Latest %s customers or prospects -BoxTitleLastCustomerBills=Latest %s modified Customer invoices -BoxTitleLastSupplierBills=Latest %s modified Vendor invoices -BoxTitleLastModifiedProspects=Prospects: last %s modified -BoxTitleLastModifiedMembers=Latest %s members -BoxTitleLastFicheInter=Latest %s modified interventions -BoxTitleOldestUnpaidCustomerBills=Customer Invoices: oldest %s unpaid -BoxTitleOldestUnpaidSupplierBills=Vendor Invoices: oldest %s unpaid -BoxTitleCurrentAccounts=Open Accounts: balances -BoxTitleSupplierOrdersAwaitingReception=Supplier orders awaiting reception -BoxTitleLastModifiedContacts=Contacts/Addresses: last %s modified -BoxMyLastBookmarks=Bookmarks: latest %s -BoxOldestExpiredServices=Oldest active expired services -BoxLastExpiredServices=Latest %s oldest contacts with active expired services -BoxTitleLastActionsToDo=Latest %s actions to do -BoxTitleLastContracts=Latest %s contracts which were modified -BoxTitleLastModifiedDonations=Latest %s donations which were modified -BoxTitleLastModifiedExpenses=Latest %s expense reports which were modified -BoxTitleLatestModifiedBoms=Latest %s BOMs which were modified -BoxTitleLatestModifiedMos=Latest %s Manufacturing Orders which were modified -BoxTitleLastOutstandingBillReached=Customers with maximum outstanding exceeded -BoxGlobalActivity=Global activity (invoices, proposals, orders) -BoxGoodCustomers=Good customers -BoxTitleGoodCustomers=%s Good customers -BoxScheduledJobs=Scheduled jobs -BoxTitleFunnelOfProspection=Lead funnel -FailedToRefreshDataInfoNotUpToDate=Failed to refresh RSS flux. Latest successful refresh date: %s -LastRefreshDate=Latest refresh date -NoRecordedBookmarks=No bookmarks defined. -ClickToAdd=Click here to add. -NoRecordedCustomers=No recorded customers -NoRecordedContacts=No recorded contacts -NoActionsToDo=No actions to do -NoRecordedOrders=No recorded sales orders -NoRecordedProposals=No recorded proposals -NoRecordedInvoices=No recorded customer invoices -NoUnpaidCustomerBills=No unpaid customer invoices -NoUnpaidSupplierBills=No unpaid vendor invoices -NoModifiedSupplierBills=No recorded vendor invoices -NoRecordedProducts=No recorded products/services -NoRecordedProspects=No recorded prospects -NoContractedProducts=No products/services contracted -NoRecordedContracts=No recorded contracts -NoRecordedInterventions=No recorded interventions -BoxLatestSupplierOrders=Latest purchase orders -BoxLatestSupplierOrdersAwaitingReception=Latest Purchase Orders (with a pending reception) -NoSupplierOrder=No recorded purchase order -BoxCustomersInvoicesPerMonth=Customer Invoices per month -BoxSuppliersInvoicesPerMonth=Vendor Invoices per month -BoxCustomersOrdersPerMonth=Sales Orders per month -BoxSuppliersOrdersPerMonth=Vendor Orders per month -BoxProposalsPerMonth=Proposals per month -NoTooLowStockProducts=No products are under the low stock limit -BoxProductDistribution=Products/Services Distribution -ForObject=On %s -BoxTitleLastModifiedSupplierBills=Vendor Invoices: last %s modified -BoxTitleLatestModifiedSupplierOrders=Vendor Orders: last %s modified -BoxTitleLastModifiedCustomerBills=Customer Invoices: last %s modified -BoxTitleLastModifiedCustomerOrders=Sales Orders: last %s modified -BoxTitleLastModifiedPropals=Latest %s modified proposals -BoxTitleLatestModifiedJobPositions=Latest %s modified job positions -BoxTitleLatestModifiedCandidatures=Latest %s modified job applications -ForCustomersInvoices=Customers invoices -ForCustomersOrders=Customers orders -ForProposals=Proposals -LastXMonthRolling=The latest %s month rolling -ChooseBoxToAdd=Add widget to your dashboard -BoxAdded=Widget was added in your dashboard -BoxTitleUserBirthdaysOfMonth=Birthdays of this month (users) -BoxLastManualEntries=Latest record in accountancy entered manually or without source document -BoxTitleLastManualEntries=%s latest record entered manually or without source document -NoRecordedManualEntries=No manual entries record in accountancy -BoxSuspenseAccount=Count accountancy operation with suspense account -BoxTitleSuspenseAccount=Number of unallocated lines -NumberOfLinesInSuspenseAccount=Number of line in suspense account -SuspenseAccountNotDefined=Suspense account isn't defined -BoxLastCustomerShipments=Last customer shipments -BoxTitleLastCustomerShipments=Latest %s customer shipments -NoRecordedShipments=No recorded customer shipment -BoxCustomersOutstandingBillReached=Customers with oustanding limit reached -# Pages -UsersHome=Home users and groups -MembersHome=Home Membership -ThirdpartiesHome=Home Thirdparties -TicketsHome=Home Tickets -AccountancyHome=Home Accountancy -ValidatedProjects=Validated projects diff --git a/htdocs/langs/ar_IQ/cashdesk.lang b/htdocs/langs/ar_IQ/cashdesk.lang deleted file mode 100644 index 3bc383ed2a1..00000000000 --- a/htdocs/langs/ar_IQ/cashdesk.lang +++ /dev/null @@ -1,131 +0,0 @@ -# Language file - Source file is en_US - cashdesk -CashDeskMenu=Point of sale -CashDesk=Point of sale -CashDeskBankCash=Bank account (cash) -CashDeskBankCB=Bank account (card) -CashDeskBankCheque=Bank account (cheque) -CashDeskWarehouse=Warehouse -CashdeskShowServices=Selling services -CashDeskProducts=Products -CashDeskStock=Stock -CashDeskOn=on -CashDeskThirdParty=Third party -ShoppingCart=Shopping cart -NewSell=New sell -AddThisArticle=Add this article -RestartSelling=Go back on sell -SellFinished=Sale complete -PrintTicket=Print ticket -SendTicket=Send ticket -NoProductFound=No article found -ProductFound=product found -NoArticle=No article -Identification=Identification -Article=Article -Difference=Difference -TotalTicket=Total ticket -NoVAT=No VAT for this sale -Change=Excess received -BankToPay=Account for payment -ShowCompany=Show company -ShowStock=Show warehouse -DeleteArticle=Click to remove this article -FilterRefOrLabelOrBC=Search (Ref/Label) -UserNeedPermissionToEditStockToUsePos=You ask to decrease stock on invoice creation, so user that uses POS needs to have permission to edit stock. -DolibarrReceiptPrinter=Dolibarr Receipt Printer -PointOfSale=Point of Sale -PointOfSaleShort=POS -CloseBill=Close Bill -Floors=Floors -Floor=Floor -AddTable=Add table -Place=Place -TakeposConnectorNecesary='TakePOS Connector' required -OrderPrinters=Add a button to send the order to some given printers, without payment (for example to send an order to a kitchen) -NotAvailableWithBrowserPrinter=Not available when printer for receipt is set to browser: -SearchProduct=Search product -Receipt=Receipt -Header=Header -Footer=Footer -AmountAtEndOfPeriod=Amount at end of period (day, month or year) -TheoricalAmount=Theorical amount -RealAmount=Real amount -CashFence=Cash desk closing -CashFenceDone=Cash desk closing done for the period -NbOfInvoices=Nb of invoices -Paymentnumpad=Type of Pad to enter payment -Numberspad=Numbers Pad -BillsCoinsPad=Coins and banknotes Pad -DolistorePosCategory=TakePOS modules and other POS solutions for Dolibarr -TakeposNeedsCategories=TakePOS needs at least one product categorie to work -TakeposNeedsAtLeastOnSubCategoryIntoParentCategory=TakePOS needs at least 1 product category under the category %s to work -OrderNotes=Can add some notes to each ordered items -CashDeskBankAccountFor=Default account to use for payments in -NoPaimementModesDefined=No paiment mode defined in TakePOS configuration -TicketVatGrouped=Group VAT by rate in tickets|receipts -AutoPrintTickets=Automatically print tickets|receipts -PrintCustomerOnReceipts=Print customer on tickets|receipts -EnableBarOrRestaurantFeatures=Enable features for Bar or Restaurant -ConfirmDeletionOfThisPOSSale=Do your confirm the deletion of this current sale ? -ConfirmDiscardOfThisPOSSale=Do you want to discard this current sale ? -History=History -ValidateAndClose=Validate and close -Terminal=Terminal -NumberOfTerminals=Number of Terminals -TerminalSelect=Select terminal you want to use: -POSTicket=POS Ticket -POSTerminal=POS Terminal -POSModule=POS Module -BasicPhoneLayout=Use basic layout for phones -SetupOfTerminalNotComplete=Setup of terminal %s is not complete -DirectPayment=Direct payment -DirectPaymentButton=Add a "Direct cash payment" button -InvoiceIsAlreadyValidated=Invoice is already validated -NoLinesToBill=No lines to bill -CustomReceipt=Custom Receipt -ReceiptName=Receipt Name -ProductSupplements=Manage supplements of products -SupplementCategory=Supplement category -ColorTheme=Color theme -Colorful=Colorful -HeadBar=Head Bar -SortProductField=Field for sorting products -Browser=Browser -BrowserMethodDescription=Simple and easy receipt printing. Only a few parameters to configure the receipt. Print via browser. -TakeposConnectorMethodDescription=External module with extra features. Posibility to print from the cloud. -PrintMethod=Print method -ReceiptPrinterMethodDescription=Powerful method with a lot of parameters. Full customizable with templates. The server hosting the application can't be in the Cloud (must be able to reach the printers in your network). -ByTerminal=By terminal -TakeposNumpadUsePaymentIcon=Use icon instead of text on payment buttons of numpad -CashDeskRefNumberingModules=Numbering module for POS sales -CashDeskGenericMaskCodes6 =
    {TN} tag is used to add the terminal number -TakeposGroupSameProduct=Group same products lines -StartAParallelSale=Start a new parallel sale -SaleStartedAt=Sale started at %s -ControlCashOpening=Open the "Control cash" popup when opening the POS -CloseCashFence=Close cash desk control -CashReport=Cash report -MainPrinterToUse=Main printer to use -OrderPrinterToUse=Order printer to use -MainTemplateToUse=Main template to use -OrderTemplateToUse=Order template to use -BarRestaurant=Bar Restaurant -AutoOrder=Order by the customer himself -RestaurantMenu=Menu -CustomerMenu=Customer menu -ScanToMenu=Scan QR code to see the menu -ScanToOrder=Scan QR code to order -Appearance=Appearance -HideCategoryImages=Hide Category Images -HideProductImages=Hide Product Images -NumberOfLinesToShow=Number of lines of images to show -DefineTablePlan=Define tables plan -GiftReceiptButton=Add a "Gift receipt" button -GiftReceipt=Gift receipt -ModuleReceiptPrinterMustBeEnabled=Module Receipt printer must have been enabled first -AllowDelayedPayment=Allow delayed payment -PrintPaymentMethodOnReceipts=Print payment method on tickets|receipts -WeighingScale=Weighing scale -ShowPriceHT = Display the column with the price excluding tax (on screen) -ShowPriceHTOnReceipt = Display the column with the price excluding tax (on the receipt) -CustomerDisplay=Customer display diff --git a/htdocs/langs/ar_IQ/categories.lang b/htdocs/langs/ar_IQ/categories.lang deleted file mode 100644 index 29e08f66541..00000000000 --- a/htdocs/langs/ar_IQ/categories.lang +++ /dev/null @@ -1,99 +0,0 @@ -# Dolibarr language file - Source file is en_US - categories -Rubrique=Tag/Category -Rubriques=Tags/Categories -RubriquesTransactions=Tags/Categories of transactions -categories=tags/categories -NoCategoryYet=No tag/category of this type has been created -In=In -AddIn=Add in -modify=modify -Classify=Classify -CategoriesArea=Tags/Categories area -ProductsCategoriesArea=Product/Service tags/categories area -SuppliersCategoriesArea=Vendor tags/categories area -CustomersCategoriesArea=Customer tags/categories area -MembersCategoriesArea=Member tags/categories area -ContactsCategoriesArea=Contact tags/categories area -AccountsCategoriesArea=Bank account tags/categories area -ProjectsCategoriesArea=Project tags/categories area -UsersCategoriesArea=User tags/categories area -SubCats=Sub-categories -CatList=List of tags/categories -CatListAll=List of tags/categories (all types) -NewCategory=New tag/category -ModifCat=Modify tag/category -CatCreated=Tag/category created -CreateCat=Create tag/category -CreateThisCat=Create this tag/category -NoSubCat=No subcategory. -SubCatOf=Subcategory -FoundCats=Found tags/categories -ImpossibleAddCat=Impossible to add the tag/category %s -WasAddedSuccessfully=%s was added successfully. -ObjectAlreadyLinkedToCategory=Element is already linked to this tag/category. -ProductIsInCategories=Product/service is linked to following tags/categories -CompanyIsInCustomersCategories=This third party is linked to following customers/prospects tags/categories -CompanyIsInSuppliersCategories=This third party is linked to following vendors tags/categories -MemberIsInCategories=This member is linked to following members tags/categories -ContactIsInCategories=This contact is linked to following contacts tags/categories -ProductHasNoCategory=This product/service is not in any tags/categories -CompanyHasNoCategory=This third party is not in any tags/categories -MemberHasNoCategory=This member is not in any tags/categories -ContactHasNoCategory=This contact is not in any tags/categories -ProjectHasNoCategory=This project is not in any tags/categories -ClassifyInCategory=Add to tag/category -NotCategorized=Without tag/category -CategoryExistsAtSameLevel=This category already exists with this ref -ContentsVisibleByAllShort=Contents visible by all -ContentsNotVisibleByAllShort=Contents not visible by all -DeleteCategory=Delete tag/category -ConfirmDeleteCategory=Are you sure you want to delete this tag/category? -NoCategoriesDefined=No tag/category defined -SuppliersCategoryShort=Vendors tag/category -CustomersCategoryShort=Customers tag/category -ProductsCategoryShort=Products tag/category -MembersCategoryShort=Members tag/category -SuppliersCategoriesShort=Vendors tags/categories -CustomersCategoriesShort=Customers tags/categories -ProspectsCategoriesShort=Prospects tags/categories -CustomersProspectsCategoriesShort=Cust./Prosp. tags/categories -ProductsCategoriesShort=Products tags/categories -MembersCategoriesShort=Members tags/categories -ContactCategoriesShort=Contacts tags/categories -AccountsCategoriesShort=Accounts tags/categories -ProjectsCategoriesShort=Projects tags/categories -UsersCategoriesShort=Users tags/categories -StockCategoriesShort=Warehouse tags/categories -ThisCategoryHasNoItems=This category does not contain any items. -CategId=Tag/category id -ParentCategory=Parent tag/category -ParentCategoryLabel=Label of parent tag/category -CatSupList=List of vendors tags/categories -CatCusList=List of customers/prospects tags/categories -CatProdList=List of products tags/categories -CatMemberList=List of members tags/categories -CatContactList=List of contacts tags/categories -CatProjectsList=List of projects tags/categories -CatUsersList=List of users tags/categories -CatSupLinks=Links between vendors and tags/categories -CatCusLinks=Links between customers/prospects and tags/categories -CatContactsLinks=Links between contacts/addresses and tags/categories -CatProdLinks=Links between products/services and tags/categories -CatMembersLinks=Links between members and tags/categories -CatProjectsLinks=Links between projects and tags/categories -CatUsersLinks=Links between users and tags/categories -DeleteFromCat=Remove from tags/category -ExtraFieldsCategories=Complementary attributes -CategoriesSetup=Tags/categories setup -CategorieRecursiv=Link with parent tag/category automatically -CategorieRecursivHelp=If option is on, when you add a product into a subcategory, product will also be added into the parent category. -AddProductServiceIntoCategory=Add the following product/service -AddCustomerIntoCategory=Assign category to customer -AddSupplierIntoCategory=Assign category to supplier -ShowCategory=Show tag/category -ByDefaultInList=By default in list -ChooseCategory=Choose category -StocksCategoriesArea=Warehouse Categories -ActionCommCategoriesArea=Event Categories -WebsitePagesCategoriesArea=Page-Container Categories -UseOrOperatorForCategories=Use 'OR' operator for categories diff --git a/htdocs/langs/ar_IQ/commercial.lang b/htdocs/langs/ar_IQ/commercial.lang deleted file mode 100644 index 21d282cd794..00000000000 --- a/htdocs/langs/ar_IQ/commercial.lang +++ /dev/null @@ -1,81 +0,0 @@ -# Dolibarr language file - Source file is en_US - commercial -Commercial=Commerce -CommercialArea=Commerce area -Customer=Customer -Customers=Customers -Prospect=Prospect -Prospects=Prospects -DeleteAction=Delete an event -NewAction=New event -AddAction=Create event -AddAnAction=Create an event -AddActionRendezVous=Create a Rendez-vous event -ConfirmDeleteAction=Are you sure you want to delete this event? -CardAction=Event card -ActionOnCompany=Related company -ActionOnContact=Related contact -TaskRDVWith=Meeting with %s -ShowTask=Show task -ShowAction=Show event -ActionsReport=Events report -ThirdPartiesOfSaleRepresentative=Third parties with sales representative -SaleRepresentativesOfThirdParty=Sales representatives of third party -SalesRepresentative=Sales representative -SalesRepresentatives=Sales representatives -SalesRepresentativeFollowUp=Sales representative (follow-up) -SalesRepresentativeSignature=Sales representative (signature) -NoSalesRepresentativeAffected=No particular sales representative assigned -ShowCustomer=Show customer -ShowProspect=Show prospect -ListOfProspects=List of prospects -ListOfCustomers=List of customers -LastDoneTasks=Latest %s completed actions -LastActionsToDo=Oldest %s not completed actions -DoneAndToDoActions=Completed and To do events -DoneActions=Completed events -ToDoActions=Incomplete events -SendPropalRef=Submission of commercial proposal %s -SendOrderRef=Submission of order %s -StatusNotApplicable=Not applicable -StatusActionToDo=To do -StatusActionDone=Complete -StatusActionInProcess=In process -TasksHistoryForThisContact=Events for this contact -LastProspectDoNotContact=Do not contact -LastProspectNeverContacted=Never contacted -LastProspectToContact=To contact -LastProspectContactInProcess=Contact in process -LastProspectContactDone=Contact done -ActionAffectedTo=Event assigned to -ActionDoneBy=Event done by -ActionAC_TEL=Phone call -ActionAC_FAX=Send fax -ActionAC_PROP=Send proposal by mail -ActionAC_EMAIL=Send Email -ActionAC_EMAIL_IN=Reception of Email -ActionAC_RDV=Meetings -ActionAC_INT=Intervention on site -ActionAC_FAC=Send customer invoice by mail -ActionAC_REL=Send customer invoice by mail (reminder) -ActionAC_CLO=Close -ActionAC_EMAILING=Send mass email -ActionAC_COM=Send sales order by mail -ActionAC_SHIP=Send shipping by mail -ActionAC_SUP_ORD=Send purchase order by mail -ActionAC_SUP_INV=Send vendor invoice by mail -ActionAC_OTH=Other -ActionAC_OTH_AUTO=Other auto -ActionAC_MANUAL=Manually inserted events -ActionAC_AUTO=Automatically inserted events -ActionAC_OTH_AUTOShort=Other -ActionAC_EVENTORGANIZATION=Event organization events -Stats=Sales statistics -StatusProsp=Prospect status -DraftPropals=Draft commercial proposals -NoLimit=No limit -ToOfferALinkForOnlineSignature=Link for online signature -WelcomeOnOnlineSignaturePage=Welcome to the page to accept commercial proposals from %s -ThisScreenAllowsYouToSignDocFrom=This screen allow you to accept and sign, or refuse, a quote/commercial proposal -ThisIsInformationOnDocumentToSign=This is information on document to accept or refuse -SignatureProposalRef=Signature of quote/commercial proposal %s -FeatureOnlineSignDisabled=Feature for online signing disabled or document generated before the feature was enabled diff --git a/htdocs/langs/ar_IQ/companies.lang b/htdocs/langs/ar_IQ/companies.lang index fbe75f09ab0..d781b34a0f8 100644 --- a/htdocs/langs/ar_IQ/companies.lang +++ b/htdocs/langs/ar_IQ/companies.lang @@ -1,477 +1,2 @@ # Dolibarr language file - Source file is en_US - companies -ErrorCompanyNameAlreadyExists=Company name %s already exists. Choose another one. -ErrorSetACountryFirst=Set the country first -SelectThirdParty=Select a third party -ConfirmDeleteCompany=Are you sure you want to delete this company and all related information? -DeleteContact=Delete a contact/address -ConfirmDeleteContact=Are you sure you want to delete this contact and all related information? -MenuNewThirdParty=New Third Party -MenuNewCustomer=New Customer -MenuNewProspect=New Prospect -MenuNewSupplier=New Vendor -MenuNewPrivateIndividual=New private individual -NewCompany=New company (prospect, customer, vendor) -NewThirdParty=New Third Party (prospect, customer, vendor) -CreateDolibarrThirdPartySupplier=Create a third party (vendor) -CreateThirdPartyOnly=Create third party -CreateThirdPartyAndContact=Create a third party + a child contact -ProspectionArea=Prospection area -IdThirdParty=Id third party -IdCompany=Company Id -IdContact=Contact Id -ThirdPartyContacts=Third-party contacts -ThirdPartyContact=Third-party contact/address -Company=Company -CompanyName=Company name -AliasNames=Alias name (commercial, trademark, ...) -AliasNameShort=Alias Name -Companies=Companies -CountryIsInEEC=Country is inside the European Economic Community -PriceFormatInCurrentLanguage=Price display format in the current language and currency -ThirdPartyName=Third-party name -ThirdPartyEmail=Third-party email -ThirdParty=Third-party -ThirdParties=Third-parties -ThirdPartyProspects=Prospects -ThirdPartyProspectsStats=Prospects -ThirdPartyCustomers=Customers -ThirdPartyCustomersStats=Customers -ThirdPartyCustomersWithIdProf12=Customers with %s or %s -ThirdPartySuppliers=Vendors -ThirdPartyType=Third-party type -Individual=Private individual -ToCreateContactWithSameName=Will automatically create a contact/address with same information as the third party under the third party. In most cases, even if your third party is a physical person, creating a third party alone is enough. -ParentCompany=Parent company -Subsidiaries=Subsidiaries -ReportByMonth=Report per month -ReportByCustomers=Report per customer -ReportByThirdparties=Report per thirdparty -ReportByQuarter=Report per rate -CivilityCode=Civility code -RegisteredOffice=Registered office -Lastname=Last name -Firstname=First name -PostOrFunction=Job position -UserTitle=Title -NatureOfThirdParty=Nature of Third party -NatureOfContact=Nature of Contact -Address=Address -State=State/Province -StateCode=State/Province code -StateShort=State -Region=Region -Region-State=Region - State -Country=Country -CountryCode=Country code -CountryId=Country id -Phone=Phone -PhoneShort=Phone -Skype=Skype -Call=Call -Chat=Chat -PhonePro=Bus. phone -PhonePerso=Pers. phone -PhoneMobile=Mobile -No_Email=Refuse bulk emailings -Fax=Fax -Zip=Zip Code -Town=City -Web=Web -Poste= Position -DefaultLang=Default language -VATIsUsed=Sales tax used VATIsUsedWhenSelling=This defines if this third party includes a sale tax or not when it makes an invoice to its own customers -VATIsNotUsed=Sales tax is not used -CopyAddressFromSoc=Copy address from third-party details -ThirdpartyNotCustomerNotSupplierSoNoRef=Third party neither customer nor vendor, no available referring objects -ThirdpartyIsNeitherCustomerNorClientSoCannotHaveDiscounts=Third party neither customer nor vendor, discounts are not available -PaymentBankAccount=Payment bank account -OverAllProposals=Proposals -OverAllOrders=Orders -OverAllInvoices=Invoices -OverAllSupplierProposals=Price requests -##### Local Taxes ##### -LocalTax1IsUsed=Use second tax -LocalTax1IsUsedES= RE is used -LocalTax1IsNotUsedES= RE is not used -LocalTax2IsUsed=Use third tax -LocalTax2IsUsedES= IRPF is used -LocalTax2IsNotUsedES= IRPF is not used -WrongCustomerCode=Customer code invalid -WrongSupplierCode=Vendor code invalid -CustomerCodeModel=Customer code model -SupplierCodeModel=Vendor code model -Gencod=Barcode -##### Professional ID ##### -ProfId1Short=Prof. id 1 -ProfId2Short=Prof. id 2 -ProfId3Short=Prof. id 3 -ProfId4Short=Prof. id 4 -ProfId5Short=Prof. id 5 -ProfId6Short=Prof. id 6 -ProfId1=Professional ID 1 -ProfId2=Professional ID 2 -ProfId3=Professional ID 3 -ProfId4=Professional ID 4 -ProfId5=Professional ID 5 -ProfId6=Professional ID 6 -ProfId1AR=Prof Id 1 (CUIT/CUIL) -ProfId2AR=Prof Id 2 (Revenu brutes) -ProfId3AR=- -ProfId4AR=- -ProfId5AR=- -ProfId6AR=- -ProfId1AT=Prof Id 1 (USt.-IdNr) -ProfId2AT=Prof Id 2 (USt.-Nr) -ProfId3AT=Prof Id 3 (Handelsregister-Nr.) -ProfId4AT=- -ProfId5AT=EORI number -ProfId6AT=- -ProfId1AU=Prof Id 1 (ABN) -ProfId2AU=- -ProfId3AU=- -ProfId4AU=- -ProfId5AU=- -ProfId6AU=- -ProfId1BE=Prof Id 1 (Professional number) -ProfId2BE=- -ProfId3BE=- -ProfId4BE=- -ProfId5BE=EORI number -ProfId6BE=- -ProfId1BR=- -ProfId2BR=IE (Inscricao Estadual) -ProfId3BR=IM (Inscricao Municipal) -ProfId4BR=CPF -#ProfId5BR=CNAE -#ProfId6BR=INSS -ProfId1CH=UID-Nummer -ProfId2CH=- -ProfId3CH=Prof Id 1 (Federal number) -ProfId4CH=Prof Id 2 (Commercial Record number) -ProfId5CH=EORI number -ProfId6CH=- -ProfId1CL=Prof Id 1 (R.U.T.) -ProfId2CL=- -ProfId3CL=- -ProfId4CL=- -ProfId5CL=- -ProfId6CL=- -ProfId1CO=Prof Id 1 (R.U.T.) -ProfId2CO=- -ProfId3CO=- -ProfId4CO=- -ProfId5CO=- -ProfId6CO=- -ProfId1DE=Prof Id 1 (USt.-IdNr) -ProfId2DE=Prof Id 2 (USt.-Nr) -ProfId3DE=Prof Id 3 (Handelsregister-Nr.) -ProfId4DE=- -ProfId5DE=EORI number -ProfId6DE=- -ProfId1ES=Prof Id 1 (CIF/NIF) -ProfId2ES=Prof Id 2 (Social security number) -ProfId3ES=Prof Id 3 (CNAE) -ProfId4ES=Prof Id 4 (Collegiate number) -ProfId5ES=Prof Id 5 (EORI number) -ProfId6ES=- -ProfId1FR=Prof Id 1 (SIREN) -ProfId2FR=Prof Id 2 (SIRET) -ProfId3FR=Prof Id 3 (NAF, old APE) -ProfId4FR=Prof Id 4 (RCS/RM) -ProfId5FR=Prof Id 5 (numéro EORI) -ProfId6FR=- -ProfId1ShortFR=SIREN -ProfId2ShortFR=SIRET -ProfId3ShortFR=NAF -ProfId4ShortFR=RCS -ProfId5ShortFR=EORI -ProfId6ShortFR=- -ProfId1GB=Registration Number -ProfId2GB=- -ProfId3GB=SIC -ProfId4GB=- -ProfId5GB=- -ProfId6GB=- -ProfId1HN=Id prof. 1 (RTN) -ProfId2HN=- -ProfId3HN=- -ProfId4HN=- -ProfId5HN=- -ProfId6HN=- -ProfId1IN=Prof Id 1 (TIN) -ProfId2IN=Prof Id 2 (PAN) -ProfId3IN=Prof Id 3 (SRVC TAX) -ProfId4IN=Prof Id 4 -ProfId5IN=Prof Id 5 -ProfId6IN=- -ProfId1IT=- -ProfId2IT=- -ProfId3IT=- -ProfId4IT=- -ProfId5IT=EORI number -ProfId6IT=- -ProfId1LU=Id. prof. 1 (R.C.S. Luxembourg) -ProfId2LU=Id. prof. 2 (Business permit) -ProfId3LU=- -ProfId4LU=- -ProfId5LU=EORI number -ProfId6LU=- -ProfId1MA=Id prof. 1 (R.C.) -ProfId2MA=Id prof. 2 (Patente) -ProfId3MA=Id prof. 3 (I.F.) -ProfId4MA=Id prof. 4 (C.N.S.S.) -ProfId5MA=Id prof. 5 (I.C.E.) -ProfId6MA=- -ProfId1MX=Prof Id 1 (R.F.C). -ProfId2MX=Prof Id 2 (R..P. IMSS) -ProfId3MX=Prof Id 3 (Profesional Charter) -ProfId4MX=- -ProfId5MX=- -ProfId6MX=- -ProfId1NL=KVK nummer -ProfId2NL=- -ProfId3NL=- -ProfId4NL=Burgerservicenummer (BSN) -ProfId5NL=EORI number -ProfId6NL=- -ProfId1PT=Prof Id 1 (NIPC) -ProfId2PT=Prof Id 2 (Social security number) -ProfId3PT=Prof Id 3 (Commercial Record number) -ProfId4PT=Prof Id 4 (Conservatory) -ProfId5PT=Prof Id 5 (EORI number) -ProfId6PT=- -ProfId1SN=RC -ProfId2SN=NINEA -ProfId3SN=- -ProfId4SN=- -ProfId5SN=- -ProfId6SN=- -ProfId1TN=Prof Id 1 (RC) -ProfId2TN=Prof Id 2 (Fiscal matricule) -ProfId3TN=Prof Id 3 (Douane code) -ProfId4TN=Prof Id 4 (BAN) -ProfId5TN=- -ProfId6TN=- -ProfId1US=Prof Id (FEIN) -ProfId2US=- -ProfId3US=- -ProfId4US=- -ProfId5US=- -ProfId6US=- -ProfId1RO=Prof Id 1 (CUI) -ProfId2RO=Prof Id 2 (Nr. Înmatriculare) -ProfId3RO=Prof Id 3 (CAEN) -ProfId4RO=Prof Id 5 (EUID) -ProfId5RO=Prof Id 5 (EORI number) -ProfId6RO=- -ProfId1RU=Prof Id 1 (OGRN) -ProfId2RU=Prof Id 2 (INN) -ProfId3RU=Prof Id 3 (KPP) -ProfId4RU=Prof Id 4 (OKPO) -ProfId5RU=- -ProfId6RU=- -ProfId1DZ=RC -ProfId2DZ=Art. -ProfId3DZ=NIF -ProfId4DZ=NIS -VATIntra=VAT ID -VATIntraShort=VAT ID -VATIntraSyntaxIsValid=Syntax is valid -VATReturn=VAT return -ProspectCustomer=Prospect / Customer -Prospect=Prospect -CustomerCard=Customer Card -Customer=Customer -CustomerRelativeDiscount=Relative customer discount -SupplierRelativeDiscount=Relative vendor discount -CustomerRelativeDiscountShort=Relative discount -CustomerAbsoluteDiscountShort=Absolute discount -CompanyHasRelativeDiscount=This customer has a default discount of %s%% -CompanyHasNoRelativeDiscount=This customer has no relative discount by default -HasRelativeDiscountFromSupplier=You have a default discount of %s%% from this vendor -HasNoRelativeDiscountFromSupplier=You have no default relative discount from this vendor -CompanyHasAbsoluteDiscount=This customer has discounts available (credits notes or down payments) for %s %s -CompanyHasDownPaymentOrCommercialDiscount=This customer has discounts available (commercial, down payments) for %s %s -CompanyHasCreditNote=This customer still has credit notes for %s %s -HasNoAbsoluteDiscountFromSupplier=You have no discount credit available from this vendor -HasAbsoluteDiscountFromSupplier=You have discounts available (credits notes or down payments) for %s %s from this vendor -HasDownPaymentOrCommercialDiscountFromSupplier=You have discounts available (commercial, down payments) for %s %s from this vendor -HasCreditNoteFromSupplier=You have credit notes for %s %s from this vendor -CompanyHasNoAbsoluteDiscount=This customer has no discount credit available -CustomerAbsoluteDiscountAllUsers=Absolute customer discounts (granted by all users) -CustomerAbsoluteDiscountMy=Absolute customer discounts (granted by yourself) -SupplierAbsoluteDiscountAllUsers=Absolute vendor discounts (entered by all users) -SupplierAbsoluteDiscountMy=Absolute vendor discounts (entered by yourself) -DiscountNone=None -Vendor=Vendor -Supplier=Vendor -AddContact=Create contact -AddContactAddress=Create contact/address -EditContact=Edit contact -EditContactAddress=Edit contact/address -Contact=Contact/Address -Contacts=Contacts/Addresses -ContactId=Contact id -ContactsAddresses=Contacts/Addresses -FromContactName=Name: -NoContactDefinedForThirdParty=No contact defined for this third party -NoContactDefined=No contact defined -DefaultContact=Default contact/address -ContactByDefaultFor=Default contact/address for -AddThirdParty=Create third party -DeleteACompany=Delete a company -PersonalInformations=Personal data -AccountancyCode=Accounting account -CustomerCode=Customer Code -SupplierCode=Vendor Code -CustomerCodeShort=Customer Code -SupplierCodeShort=Vendor Code -CustomerCodeDesc=Customer Code, unique for all customers -SupplierCodeDesc=Vendor Code, unique for all vendors -RequiredIfCustomer=Required if third party is a customer or prospect -RequiredIfSupplier=Required if third party is a vendor -ValidityControledByModule=Validity controlled by the module -ThisIsModuleRules=Rules for this module -ProspectToContact=Prospect to contact -CompanyDeleted=Company "%s" deleted from database. -ListOfContacts=List of contacts/addresses -ListOfContactsAddresses=List of contacts/addresses -ListOfThirdParties=List of Third Parties -ShowCompany=Third Party -ShowContact=Contact-Address -ContactsAllShort=All (No filter) -ContactType=Contact type -ContactForOrders=Order's contact -ContactForOrdersOrShipments=Order's or shipment's contact -ContactForProposals=Proposal's contact -ContactForContracts=Contract's contact -ContactForInvoices=Invoice's contact -NoContactForAnyOrder=This contact is not a contact for any order -NoContactForAnyOrderOrShipments=This contact is not a contact for any order or shipment -NoContactForAnyProposal=This contact is not a contact for any commercial proposal -NoContactForAnyContract=This contact is not a contact for any contract -NoContactForAnyInvoice=This contact is not a contact for any invoice -NewContact=New contact -NewContactAddress=New Contact/Address -MyContacts=My contacts -Capital=Capital -CapitalOf=Capital of %s -EditCompany=Edit company -ThisUserIsNot=This user is not a prospect, customer or vendor -VATIntraCheck=Check -VATIntraCheckDesc=The VAT ID must include the country prefix. The link %s uses the European VAT checker service (VIES) which requires internet access from the Dolibarr server. -VATIntraCheckURL=http://ec.europa.eu/taxation_customs/vies/vieshome.do -VATIntraCheckableOnEUSite=Check the intra-Community VAT ID on the European Commission website -VATIntraManualCheck=You can also check manually on the European Commission website %s -ErrorVATCheckMS_UNAVAILABLE=Check not possible. Check service is not provided by the member state (%s). -NorProspectNorCustomer=Not prospect, nor customer -JuridicalStatus=Business entity type -Workforce=Workforce -Staff=Employees -ProspectLevelShort=Potential -ProspectLevel=Prospect potential -ContactPrivate=Private -ContactPublic=Shared -ContactVisibility=Visibility -ContactOthers=Other -OthersNotLinkedToThirdParty=Others, not linked to a third party -ProspectStatus=Prospect status -PL_NONE=None -PL_UNKNOWN=Unknown -PL_LOW=Low -PL_MEDIUM=Medium -PL_HIGH=High -TE_UNKNOWN=- -TE_STARTUP=Startup -TE_GROUP=Large company -TE_MEDIUM=Medium company -TE_ADMIN=Governmental -TE_SMALL=Small company -TE_RETAIL=Retailer -TE_WHOLE=Wholesaler -TE_PRIVATE=Private individual -TE_OTHER=Other -StatusProspect-1=Do not contact -StatusProspect0=Never contacted -StatusProspect1=To be contacted -StatusProspect2=Contact in process -StatusProspect3=Contact done -ChangeDoNotContact=Change status to 'Do not contact' -ChangeNeverContacted=Change status to 'Never contacted' -ChangeToContact=Change status to 'To be contacted' -ChangeContactInProcess=Change status to 'Contact in process' -ChangeContactDone=Change status to 'Contact done' -ProspectsByStatus=Prospects by status -NoParentCompany=None -ExportCardToFormat=Export card to format -ContactNotLinkedToCompany=Contact not linked to any third party -DolibarrLogin=Dolibarr login -NoDolibarrAccess=No Dolibarr access -ExportDataset_company_1=Third-parties (companies/foundations/physical people) and their properties -ExportDataset_company_2=Contacts and their properties -ImportDataset_company_1=Third-parties and their properties -ImportDataset_company_2=Third-parties additional contacts/addresses and attributes -ImportDataset_company_3=Third-parties Bank accounts -ImportDataset_company_4=Third-parties Sales representatives (assign sales representatives/users to companies) -PriceLevel=Price Level -PriceLevelLabels=Price Level Labels -DeliveryAddress=Delivery address -AddAddress=Add address -SupplierCategory=Vendor category -JuridicalStatus200=Independent -DeleteFile=Delete file -ConfirmDeleteFile=Are you sure you want to delete this file? -AllocateCommercial=Assigned to sales representative -Organization=Organization -FiscalYearInformation=Fiscal Year -FiscalMonthStart=Starting month of the fiscal year -SocialNetworksInformation=Social networks -SocialNetworksFacebookURL=Facebook URL -SocialNetworksTwitterURL=Twitter URL -SocialNetworksLinkedinURL=Linkedin URL -SocialNetworksInstagramURL=Instagram URL -SocialNetworksYoutubeURL=Youtube URL -SocialNetworksGithubURL=Github URL -YouMustAssignUserMailFirst=You must create an email for this user prior to being able to add an email notification. -YouMustCreateContactFirst=To be able to add email notifications, you must first define contacts with valid emails for the third party -ListSuppliersShort=List of Vendors -ListProspectsShort=List of Prospects -ListCustomersShort=List of Customers -ThirdPartiesArea=Third Parties/Contacts -LastModifiedThirdParties=Latest %s Third Parties which were modified -UniqueThirdParties=Total number of Third Parties -InActivity=Open -ActivityCeased=Closed -ThirdPartyIsClosed=Third party is closed -ProductsIntoElements=List of products/services mapped to %s -CurrentOutstandingBill=Current outstanding bill -OutstandingBill=Max. for outstanding bill -OutstandingBillReached=Max. for outstanding bill reached -OrderMinAmount=Minimum amount for order -MonkeyNumRefModelDesc=Return a number in the format %syymm-nnnn for the customer code and %syymm-nnnn for the vendor code where yy is year, mm is month and nnnn is a sequencial auto-incrementing number with no break and no return to 0. -LeopardNumRefModelDesc=The code is free. This code can be modified at any time. -ManagingDirectors=Manager(s) name (CEO, director, president...) -MergeOriginThirdparty=Duplicate third party (third party you want to delete) -MergeThirdparties=Merge third parties -ConfirmMergeThirdparties=Are you sure you want to merge the chosen third party with the current one? All linked objects (invoices, orders, ...) will be moved to the current third party, after which the chosen third party will be deleted. -ThirdpartiesMergeSuccess=Third parties have been merged -SaleRepresentativeLogin=Login of sales representative -SaleRepresentativeFirstname=First name of sales representative -SaleRepresentativeLastname=Last name of sales representative -ErrorThirdpartiesMerge=There was an error when deleting the third parties. Please check the log. Changes have been reverted. -NewCustomerSupplierCodeProposed=Customer or Vendor code already used, a new code is suggested -KeepEmptyIfGenericAddress=Keep this field empty if this address is a generic address -#Imports -PaymentTypeCustomer=Payment Type - Customer -PaymentTermsCustomer=Payment Terms - Customer -PaymentTypeSupplier=Payment Type - Vendor -PaymentTermsSupplier=Payment Term - Vendor -PaymentTypeBoth=Payment Type - Customer and Vendor -MulticurrencyUsed=Use Multicurrency -MulticurrencyCurrency=Currency -InEEC=Europe (EEC) -RestOfEurope=Rest of Europe (EEC) -OutOfEurope=Out of Europe (EEC) -CurrentOutstandingBillLate=Current outstanding bill late -BecarefullChangeThirdpartyBeforeAddProductToInvoice=Be carefull, depending on your product price settings, you should change thirdparty before adding product to POS. diff --git a/htdocs/langs/ar_IQ/compta.lang b/htdocs/langs/ar_IQ/compta.lang index 8329346c163..0b2ce4fa537 100644 --- a/htdocs/langs/ar_IQ/compta.lang +++ b/htdocs/langs/ar_IQ/compta.lang @@ -1,294 +1,5 @@ # Dolibarr language file - Source file is en_US - compta -MenuFinancial=Billing | Payment -TaxModuleSetupToModifyRules=Go to Taxes module setup to modify rules for calculation -TaxModuleSetupToModifyRulesLT=Go to Company setup to modify rules for calculation -OptionMode=Option for accountancy -OptionModeTrue=Option Incomes-Expenses -OptionModeVirtual=Option Claims-Debts -OptionModeTrueDesc=In this context, the turnover is calculated over payments (date of payments). The validity of the figures is assured only if the book-keeping is scrutinized through the input/output on the accounts via invoices. -OptionModeVirtualDesc=In this context, the turnover is calculated over invoices (date of validation). When these invoices are due, whether they have been paid or not, they are listed in the turnover output. -FeatureIsSupportedInInOutModeOnly=Feature only available in CREDITS-DEBTS accountancy mode (See Accountancy module configuration) -VATReportBuildWithOptionDefinedInModule=Amounts shown here are calculated using rules defined by Tax module setup. -LTReportBuildWithOptionDefinedInModule=Amounts shown here are calculated using rules defined by Company setup. -Param=Setup -RemainingAmountPayment=Amount payment remaining: -Account=Account -Accountparent=Parent account -Accountsparent=Parent accounts -Income=Income -Outcome=Expense -MenuReportInOut=Income / Expense -ReportInOut=Balance of income and expenses -ReportTurnover=Turnover invoiced -ReportTurnoverCollected=Turnover collected -PaymentsNotLinkedToInvoice=Payments not linked to any invoice, so not linked to any third party -PaymentsNotLinkedToUser=Payments not linked to any user -Profit=Profit -AccountingResult=Accounting result -BalanceBefore=Balance (before) -Balance=Balance -Debit=Debit -Credit=Credit -Piece=Accounting Doc. -AmountHTVATRealReceived=Net collected -AmountHTVATRealPaid=Net paid -VATToPay=Tax sales -VATReceived=Tax received -VATToCollect=Tax purchases -VATSummary=Tax monthly -VATBalance=Tax Balance -VATPaid=Tax paid -LT1Summary=Tax 2 summary -LT2Summary=Tax 3 summary -LT1SummaryES=RE Balance -LT2SummaryES=IRPF Balance -LT1SummaryIN=CGST Balance -LT2SummaryIN=SGST Balance -LT1Paid=Tax 2 paid -LT2Paid=Tax 3 paid -LT1PaidES=RE Paid -LT2PaidES=IRPF Paid -LT1PaidIN=CGST Paid -LT2PaidIN=SGST Paid -LT1Customer=Tax 2 sales -LT1Supplier=Tax 2 purchases -LT1CustomerES=RE sales -LT1SupplierES=RE purchases -LT1CustomerIN=CGST sales -LT1SupplierIN=CGST purchases -LT2Customer=Tax 3 sales -LT2Supplier=Tax 3 purchases -LT2CustomerES=IRPF sales -LT2SupplierES=IRPF purchases -LT2CustomerIN=SGST sales -LT2SupplierIN=SGST purchases -VATCollected=VAT collected -StatusToPay=To pay -SpecialExpensesArea=Area for all special payments -VATExpensesArea=Area for all TVA payments -SocialContribution=Social or fiscal tax -SocialContributions=Social or fiscal taxes -SocialContributionsDeductibles=Deductible social or fiscal taxes -SocialContributionsNondeductibles=Nondeductible social or fiscal taxes -DateOfSocialContribution=Date of social or fiscal tax -LabelContrib=Label contribution -TypeContrib=Type contribution -MenuSpecialExpenses=Special expenses -MenuTaxAndDividends=Taxes and dividends -MenuSocialContributions=Social/fiscal taxes -MenuNewSocialContribution=New social/fiscal tax -NewSocialContribution=New social/fiscal tax -AddSocialContribution=Add social/fiscal tax -ContributionsToPay=Social/fiscal taxes to pay -AccountancyTreasuryArea=Billing and payment area -NewPayment=New payment -PaymentCustomerInvoice=Customer invoice payment -PaymentSupplierInvoice=vendor invoice payment -PaymentSocialContribution=Social/fiscal tax payment -PaymentVat=VAT payment -AutomaticCreationPayment=Automatically record the payment -ListPayment=List of payments -ListOfCustomerPayments=List of customer payments -ListOfSupplierPayments=List of vendor payments -DateStartPeriod=Date start period -DateEndPeriod=Date end period -newLT1Payment=New tax 2 payment -newLT2Payment=New tax 3 payment -LT1Payment=Tax 2 payment -LT1Payments=Tax 2 payments -LT2Payment=Tax 3 payment -LT2Payments=Tax 3 payments -newLT1PaymentES=New RE payment -newLT2PaymentES=New IRPF payment -LT1PaymentES=RE Payment -LT1PaymentsES=RE Payments -LT2PaymentES=IRPF Payment -LT2PaymentsES=IRPF Payments -VATPayment=Sales tax payment -VATPayments=Sales tax payments -VATDeclarations=VAT declarations -VATDeclaration=VAT declaration -VATRefund=Sales tax refund -NewVATPayment=New sales tax payment -NewLocalTaxPayment=New tax %s payment -Refund=Refund -SocialContributionsPayments=Social/fiscal taxes payments -ShowVatPayment=Show VAT payment -TotalToPay=Total to pay -BalanceVisibilityDependsOnSortAndFilters=Balance is visible in this list only if table is sorted on %s and filtered on 1 bank account (with no other filters) -CustomerAccountancyCode=Customer accounting code -SupplierAccountancyCode=Vendor accounting code -CustomerAccountancyCodeShort=Cust. account. code -SupplierAccountancyCodeShort=Sup. account. code -AccountNumber=Account number -NewAccountingAccount=New account -Turnover=Turnover invoiced -TurnoverCollected=Turnover collected -SalesTurnoverMinimum=Minimum turnover -ByExpenseIncome=By expenses & incomes -ByThirdParties=By third parties -ByUserAuthorOfInvoice=By invoice author -CheckReceipt=Check deposit -CheckReceiptShort=Check deposit -LastCheckReceiptShort=Latest %s check receipts -NewCheckReceipt=New discount -NewCheckDeposit=New check deposit -NewCheckDepositOn=Create receipt for deposit on account: %s -NoWaitingChecks=No checks awaiting deposit. -DateChequeReceived=Check receiving date -NbOfCheques=No. of checks -PaySocialContribution=Pay a social/fiscal tax -PayVAT=Pay a VAT declaration -PaySalary=Pay a salary card -ConfirmPaySocialContribution=Are you sure you want to classify this social or fiscal tax as paid ? -ConfirmPayVAT=Are you sure you want to classify this VAT declaration as paid ? -ConfirmPaySalary=Are you sure you want to classify this salary card as paid? -DeleteSocialContribution=Delete a social or fiscal tax payment -DeleteVAT=Delete a VAT declaration -DeleteSalary=Delete a salary card -ConfirmDeleteSocialContribution=Are you sure you want to delete this social/fiscal tax payment ? -ConfirmDeleteVAT=Are you sure you want to delete this VAT declaration ? -ConfirmDeleteSalary=Are you sure you want to delete this salary? -ExportDataset_tax_1=Social and fiscal taxes and payments -CalcModeVATDebt=Mode %sVAT on commitment accounting%s. -CalcModeVATEngagement=Mode %sVAT on incomes-expenses%s. -CalcModeDebt=Analysis of known recorded documents even if they are not yet accounted in ledger. -CalcModeEngagement=Analysis of known recorded payments, even if they are not yet accounted in Ledger. -CalcModeBookkeeping=Analysis of data journalized in Bookkeeping Ledger table. -CalcModeLT1= Mode %sRE on customer invoices - suppliers invoices%s -CalcModeLT1Debt=Mode %sRE on customer invoices%s -CalcModeLT1Rec= Mode %sRE on suppliers invoices%s -CalcModeLT2= Mode %sIRPF on customer invoices - suppliers invoices%s -CalcModeLT2Debt=Mode %sIRPF on customer invoices%s -CalcModeLT2Rec= Mode %sIRPF on suppliers invoices%s -AnnualSummaryDueDebtMode=Balance of income and expenses, annual summary -AnnualSummaryInputOutputMode=Balance of income and expenses, annual summary -AnnualByCompanies=Balance of income and expenses, by predefined groups of account -AnnualByCompaniesDueDebtMode=Balance of income and expenses, detail by predefined groups, mode %sClaims-Debts%s said Commitment accounting. -AnnualByCompaniesInputOutputMode=Balance of income and expenses, detail by predefined groups, mode %sIncomes-Expenses%s said cash accounting. -SeeReportInInputOutputMode=See %sanalysis of payments%s for a calculation based on recorded payments made even if they are not yet accounted in Ledger -SeeReportInDueDebtMode=See %sanalysis of recorded documents%s for a calculation based on known recorded documents even if they are not yet accounted in Ledger -SeeReportInBookkeepingMode=See %sanalysis of bookeeping ledger table%s for a report based on Bookkeeping Ledger table -RulesAmountWithTaxIncluded=- Amounts shown are with all taxes included -RulesResultDue=- It includes outstanding invoices, expenses, VAT, donations whether they are paid or not. Is also includes paid salaries.
    - It is based on the billing date of invoices and on the due date for expenses or tax payments. For salaries defined with Salary module, the value date of payment is used. -RulesResultInOut=- It includes the real payments made on invoices, expenses, VAT and salaries.
    - It is based on the payment dates of the invoices, expenses, VAT and salaries. The donation date for donation. -RulesCADue=- It includes the customer's due invoices whether they are paid or not.
    - It is based on the billing date of these invoices.
    -RulesCAIn=- It includes all the effective payments of invoices received from customers.
    - It is based on the payment date of these invoices
    -RulesCATotalSaleJournal=It includes all credit lines from the Sale journal. -RulesSalesTurnoverOfIncomeAccounts=It includes (credit - debit) of lines for product accounts in group INCOME -RulesAmountOnInOutBookkeepingRecord=It includes record in your Ledger with accounting accounts that has the group "EXPENSE" or "INCOME" -RulesResultBookkeepingPredefined=It includes record in your Ledger with accounting accounts that has the group "EXPENSE" or "INCOME" -RulesResultBookkeepingPersonalized=It show record in your Ledger with accounting accounts grouped by personalized groups -SeePageForSetup=See menu %s for setup -DepositsAreNotIncluded=- Down payment invoices are not included -DepositsAreIncluded=- Down payment invoices are included -LT1ReportByMonth=Tax 2 report by month -LT2ReportByMonth=Tax 3 report by month -LT1ReportByCustomers=Report tax 2 by third party -LT2ReportByCustomers=Report tax 3 by third party -LT1ReportByCustomersES=Report by third party RE -LT2ReportByCustomersES=Report by third party IRPF -VATReport=Sale tax report -VATReportByPeriods=Sale tax report by period -VATReportByMonth=Sale tax report by month -VATReportByRates=Sale tax report by rates -VATReportByThirdParties=Sale tax report by third parties -VATReportByCustomers=Sale tax report by customer -VATReportByCustomersInInputOutputMode=Report by the customer VAT collected and paid -VATReportByQuartersInInputOutputMode=Report by Sale tax rate of the tax collected and paid -VATReportShowByRateDetails=Show details of this rate -LT1ReportByQuarters=Report tax 2 by rate -LT2ReportByQuarters=Report tax 3 by rate -LT1ReportByQuartersES=Report by RE rate -LT2ReportByQuartersES=Report by IRPF rate SeeVATReportInInputOutputMode=See report %sVAT encasement%s for a standard calculation SeeVATReportInDueDebtMode=See report %sVAT on flow%s for a calculation with an option on the flow RulesVATInServices=- For services, the report includes the VAT regulations actually received or issued on the basis of the date of payment. -RulesVATInProducts=- For material assets, the report includes the VAT received or issued on the basis of the date of payment. RulesVATDueServices=- For services, the report includes VAT invoices due, paid or not, based on the invoice date. -RulesVATDueProducts=- For material assets, the report includes the VAT invoices, based on the invoice date. -OptionVatInfoModuleComptabilite=Note: For material assets, it should use the date of delivery to be more fair. -ThisIsAnEstimatedValue=This is a preview, based on business events and not from the final ledger table, so final results may differ from this preview values -PercentOfInvoice=%%/invoice -NotUsedForGoods=Not used on goods -ProposalStats=Statistics on proposals -OrderStats=Statistics on orders -InvoiceStats=Statistics on bills -Dispatch=Dispatching -Dispatched=Dispatched -ToDispatch=To dispatch -ThirdPartyMustBeEditAsCustomer=Third party must be defined as a customer -SellsJournal=Sales Journal -PurchasesJournal=Purchases Journal -DescSellsJournal=Sales Journal -DescPurchasesJournal=Purchases Journal -CodeNotDef=Not defined -WarningDepositsNotIncluded=Down payment invoices are not included in this version with this accountancy module. -DatePaymentTermCantBeLowerThanObjectDate=Payment term date can't be lower than object date. -Pcg_version=Chart of accounts models -Pcg_type=Pcg type -Pcg_subtype=Pcg subtype -InvoiceLinesToDispatch=Invoice lines to dispatch -ByProductsAndServices=By product and service -RefExt=External ref -ToCreateAPredefinedInvoice=To create a template invoice, create a standard invoice, then, without validating it, click on button "%s". -LinkedOrder=Link to order -Mode1=Method 1 -Mode2=Method 2 -CalculationRuleDesc=To calculate total VAT, there is two methods:
    Method 1 is rounding vat on each line, then summing them.
    Method 2 is summing all vat on each line, then rounding result.
    Final result may differs from few cents. Default mode is mode %s. -CalculationRuleDescSupplier=According to vendor, choose appropriate method to apply same calculation rule and get same result expected by your vendor. -TurnoverPerProductInCommitmentAccountingNotRelevant=The report of Turnover collected per product is not available. This report is only available for turnover invoiced. -TurnoverPerSaleTaxRateInCommitmentAccountingNotRelevant=The report of Turnover collected per sale tax rate is not available. This report is only available for turnover invoiced. -CalculationMode=Calculation mode -AccountancyJournal=Accounting code journal -ACCOUNTING_VAT_SOLD_ACCOUNT=Accounting account by default for VAT on sales (used if not defined on VAT dictionary setup) -ACCOUNTING_VAT_BUY_ACCOUNT=Accounting account by default for VAT on purchases (used if not defined on VAT dictionary setup) -ACCOUNTING_VAT_PAY_ACCOUNT=Accounting account by default for paying VAT -ACCOUNTING_ACCOUNT_CUSTOMER=Accounting account used for customer third parties -ACCOUNTING_ACCOUNT_CUSTOMER_Desc=The dedicated accounting account defined on third party card will be used for Subledger accounting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated customer accounting account on third party is not defined. -ACCOUNTING_ACCOUNT_SUPPLIER=Accounting account used for vendor third parties -ACCOUNTING_ACCOUNT_SUPPLIER_Desc=The dedicated accounting account defined on third party card will be used for Subledger accounting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated vendor accounting account on third party is not defined. -ConfirmCloneTax=Confirm the clone of a social/fiscal tax -ConfirmCloneVAT=Confirm the clone of a VAT declaration -ConfirmCloneSalary=Confirm the clone of a salary -CloneTaxForNextMonth=Clone it for next month -SimpleReport=Simple report -AddExtraReport=Extra reports (add foreign and national customer report) -OtherCountriesCustomersReport=Foreign customers report -BasedOnTwoFirstLettersOfVATNumberBeingDifferentFromYourCompanyCountry=Based on the two first letters of the VAT number being different from your own company's country code -SameCountryCustomersWithVAT=National customers report -BasedOnTwoFirstLettersOfVATNumberBeingTheSameAsYourCompanyCountry=Based on the two first letters of the VAT number being the same as your own company's country code -LinkedFichinter=Link to an intervention -ImportDataset_tax_contrib=Social/fiscal taxes -ImportDataset_tax_vat=Vat payments -ErrorBankAccountNotFound=Error: Bank account not found -FiscalPeriod=Accounting period -ListSocialContributionAssociatedProject=List of social contributions associated with the project -DeleteFromCat=Remove from accounting group -AccountingAffectation=Accounting assignment -LastDayTaxIsRelatedTo=Last day of period the tax is related to -VATDue=Sale tax claimed -ClaimedForThisPeriod=Claimed for the period -PaidDuringThisPeriod=Paid for this period -PaidDuringThisPeriodDesc=This is the sum of all payments linked to VAT declarations which have an end-of-period date in the selected date range -ByVatRate=By sale tax rate -TurnoverbyVatrate=Turnover invoiced by sale tax rate -TurnoverCollectedbyVatrate=Turnover collected by sale tax rate -PurchasebyVatrate=Purchase by sale tax rate -LabelToShow=Short label -PurchaseTurnover=Purchase turnover -PurchaseTurnoverCollected=Purchase turnover collected -RulesPurchaseTurnoverDue=- It includes the supplier's due invoices whether they are paid or not.
    - It is based on the invoice date of these invoices.
    -RulesPurchaseTurnoverIn=- It includes all the effective payments of invoices done to suppliers.
    - It is based on the payment date of these invoices
    -RulesPurchaseTurnoverTotalPurchaseJournal=It includes all debit lines from the purchase journal. -RulesPurchaseTurnoverOfExpenseAccounts=It includes (debit - credit) of lines for product accounts in group EXPENSE -ReportPurchaseTurnover=Purchase turnover invoiced -ReportPurchaseTurnoverCollected=Purchase turnover collected -IncludeVarpaysInResults = Include various payments in reports -IncludeLoansInResults = Include loans in reports -InvoiceLate30Days = Invoices late > 30 days -InvoiceLate15Days = Invoices late > 15 days -InvoiceLateMinus15Days = Invoices late -InvoiceNotLate = To be collected < 15 days -InvoiceNotLate15Days = To be collected in 15 days -InvoiceNotLate30Days = To be collected in 30 days diff --git a/htdocs/langs/ar_IQ/contracts.lang b/htdocs/langs/ar_IQ/contracts.lang deleted file mode 100644 index a9ac308142a..00000000000 --- a/htdocs/langs/ar_IQ/contracts.lang +++ /dev/null @@ -1,104 +0,0 @@ -# Dolibarr language file - Source file is en_US - contracts -ContractsArea=Contracts area -ListOfContracts=List of contracts -AllContracts=All contracts -ContractCard=Contract card -ContractStatusNotRunning=Not running -ContractStatusDraft=Draft -ContractStatusValidated=Validated -ContractStatusClosed=Closed -ServiceStatusInitial=Not running -ServiceStatusRunning=Running -ServiceStatusNotLate=Running, not expired -ServiceStatusNotLateShort=Not expired -ServiceStatusLate=Running, expired -ServiceStatusLateShort=Expired -ServiceStatusClosed=Closed -ShowContractOfService=Show contract of service -Contracts=Contracts -ContractsSubscriptions=Contracts/Subscriptions -ContractsAndLine=Contracts and line of contracts -Contract=Contract -ContractLine=Contract line -Closing=Closing -NoContracts=No contracts -MenuServices=Services -MenuInactiveServices=Services not active -MenuRunningServices=Running services -MenuExpiredServices=Expired services -MenuClosedServices=Closed services -NewContract=New contract -NewContractSubscription=New contract or subscription -AddContract=Create contract -DeleteAContract=Delete a contract -ActivateAllOnContract=Activate all services -CloseAContract=Close a contract -ConfirmDeleteAContract=Are you sure you want to delete this contract and all its services? -ConfirmValidateContract=Are you sure you want to validate this contract under name %s? -ConfirmActivateAllOnContract=This will open all services (not yet active). Are you sure you want to open all services? -ConfirmCloseContract=This will close all services (active or not). Are you sure you want to close this contract? -ConfirmCloseService=Are you sure you want to close this service with date %s? -ValidateAContract=Validate a contract -ActivateService=Activate service -ConfirmActivateService=Are you sure you want to activate this service with date %s? -RefContract=Contract reference -DateContract=Contract date -DateServiceActivate=Service activation date -ListOfServices=List of services -ListOfInactiveServices=List of not active services -ListOfExpiredServices=List of expired active services -ListOfClosedServices=List of closed services -ListOfRunningServices=List of running services -NotActivatedServices=Inactive services (among validated contracts) -BoardNotActivatedServices=Services to activate among validated contracts -BoardNotActivatedServicesShort=Services to activate -LastContracts=Latest %s contracts -LastModifiedServices=Latest %s modified services -ContractStartDate=Start date -ContractEndDate=End date -DateStartPlanned=Planned start date -DateStartPlannedShort=Planned start date -DateEndPlanned=Planned end date -DateEndPlannedShort=Planned end date -DateStartReal=Real start date -DateStartRealShort=Real start date -DateEndReal=Real end date -DateEndRealShort=Real end date -CloseService=Close service -BoardRunningServices=Services running -BoardRunningServicesShort=Services running -BoardExpiredServices=Services expired -BoardExpiredServicesShort=Services expired -ServiceStatus=Status of service -DraftContracts=Drafts contracts -CloseRefusedBecauseOneServiceActive=Contract can't be closed as there is at least one open service on it -ActivateAllContracts=Activate all contract lines -CloseAllContracts=Close all contract lines -DeleteContractLine=Delete a contract line -ConfirmDeleteContractLine=Are you sure you want to delete this contract line? -MoveToAnotherContract=Move service into another contract. -ConfirmMoveToAnotherContract=I choosed new target contract and confirm I want to move this service into this contract. -ConfirmMoveToAnotherContractQuestion=Choose in which existing contract (of same third party), you want to move this service to? -PaymentRenewContractId=Renew contract line (number %s) -ExpiredSince=Expiration date -NoExpiredServices=No expired active services -ListOfServicesToExpireWithDuration=List of Services to expire in %s days -ListOfServicesToExpireWithDurationNeg=List of Services expired from more than %s days -ListOfServicesToExpire=List of Services to expire -NoteListOfYourExpiredServices=This list contains only services of contracts for third parties you are linked to as a sale representative. -StandardContractsTemplate=Standard contracts template -ContactNameAndSignature=For %s, name and signature: -OnlyLinesWithTypeServiceAreUsed=Only lines with type "Service" will be cloned. -ConfirmCloneContract=Are you sure you want to clone the contract %s? -LowerDateEndPlannedShort=Lower planned end date of active services -SendContractRef=Contract information __REF__ -OtherContracts=Other contracts -##### Types de contacts ##### -TypeContact_contrat_internal_SALESREPSIGN=Sales representative signing contract -TypeContact_contrat_internal_SALESREPFOLL=Sales representative following-up contract -TypeContact_contrat_external_BILLING=Billing customer contact -TypeContact_contrat_external_CUSTOMER=Follow-up customer contact -TypeContact_contrat_external_SALESREPSIGN=Signing contract customer contact -HideClosedServiceByDefault=Hide closed services by default -ShowClosedServices=Show Closed Services -HideClosedServices=Hide Closed Services diff --git a/htdocs/langs/ar_IQ/cron.lang b/htdocs/langs/ar_IQ/cron.lang deleted file mode 100644 index 4fd2220dea6..00000000000 --- a/htdocs/langs/ar_IQ/cron.lang +++ /dev/null @@ -1,91 +0,0 @@ -# Dolibarr language file - Source file is en_US - cron -# About page -# Right -Permission23101 = Read Scheduled job -Permission23102 = Create/update Scheduled job -Permission23103 = Delete Scheduled job -Permission23104 = Execute Scheduled job -# Admin -CronSetup=Scheduled job management setup -URLToLaunchCronJobs=URL to check and launch qualified cron jobs from a browser -OrToLaunchASpecificJob=Or to check and launch a specific job from a browser -KeyForCronAccess=Security key for URL to launch cron jobs -FileToLaunchCronJobs=Command line to check and launch qualified cron jobs -CronExplainHowToRunUnix=On Unix environment you should use the following crontab entry to run the command line each 5 minutes -CronExplainHowToRunWin=On Microsoft(tm) Windows environment you can use Scheduled Task tools to run the command line each 5 minutes -CronMethodDoesNotExists=Class %s does not contains any method %s -CronMethodNotAllowed=Method %s of class %s is in blacklist of forbidden methods -CronJobDefDesc=Cron job profiles are defined into the module descriptor file. When module is activated, they are loaded and available so you can administer the jobs from the admin tools menu %s. -CronJobProfiles=List of predefined cron job profiles -# Menu -EnabledAndDisabled=Enabled and disabled -# Page list -CronLastOutput=Latest run output -CronLastResult=Latest result code -CronCommand=Command -CronList=Scheduled jobs -CronDelete=Delete scheduled jobs -CronConfirmDelete=Are you sure you want to delete these scheduled jobs? -CronExecute=Launch scheduled job -CronConfirmExecute=Are you sure you want to execute these scheduled jobs now? -CronInfo=Scheduled job module allows to schedule jobs to execute them automatically. Jobs can also be started manually. -CronTask=Job -CronNone=None -CronDtStart=Not before -CronDtEnd=Not after -CronDtNextLaunch=Next execution -CronDtLastLaunch=Start date of latest execution -CronDtLastResult=End date of latest execution -CronFrequency=Frequency -CronClass=Class -CronMethod=Method -CronModule=Module -CronNoJobs=No jobs registered -CronPriority=Priority -CronLabel=Label -CronNbRun=Number of launches -CronMaxRun=Maximum number of launches -CronEach=Every -JobFinished=Job launched and finished -Scheduled=Scheduled -#Page card -CronAdd= Add jobs -CronEvery=Execute job each -CronObject=Instance/Object to create -CronArgs=Parameters -CronSaveSucess=Save successfully -CronNote=Comment -CronFieldMandatory=Fields %s is mandatory -CronErrEndDateStartDt=End date cannot be before start date -StatusAtInstall=Status at module installation -CronStatusActiveBtn=Schedule -CronStatusInactiveBtn=Disable -CronTaskInactive=This job is disabled (not scheduled) -CronId=Id -CronClassFile=Filename with class -CronModuleHelp=Name of Dolibarr module directory (also work with external Dolibarr module).
    For example to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for module is
    product -CronClassFileHelp=The relative path and file name to load (path is relative to web server root directory).
    For example to call the fetch method of Dolibarr Product object htdocs/product/class/product.class.php, the value for class file name is
    product/class/product.class.php -CronObjectHelp=The object name to load.
    For example to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for class file name is
    Product -CronMethodHelp=The object method to launch.
    For example to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for method is
    fetch -CronArgsHelp=The method arguments.
    For example to call the fetch method of Dolibarr Product object /htdocs/product/class/product.class.php, the value for paramters can be
    0, ProductRef -CronCommandHelp=The system command line to execute. -CronCreateJob=Create new Scheduled Job -CronFrom=From -# Info -# Common -CronType=Job type -CronType_method=Call method of a PHP Class -CronType_command=Shell command -CronCannotLoadClass=Cannot load class file %s (to use class %s) -CronCannotLoadObject=Class file %s was loaded, but object %s was not found into it -UseMenuModuleToolsToAddCronJobs=Go into menu "Home - Admin tools - Scheduled jobs" to see and edit scheduled jobs. -JobDisabled=Job disabled -MakeLocalDatabaseDumpShort=Local database backup -MakeLocalDatabaseDump=Create a local database dump. Parameters are: compression ('gz' or 'bz' or 'none'), backup type ('mysql', 'pgsql', 'auto'), 1, 'auto' or filename to build, number of backup files to keep -WarningCronDelayed=Attention, for performance purpose, whatever is next date of execution of enabled jobs, your jobs may be delayed to a maximum of %s hours, before being run. -DATAPOLICYJob=Data cleaner and anonymizer -JobXMustBeEnabled=Job %s must be enabled -# Cron Boxes -LastExecutedScheduledJob=Last executed scheduled job -NextScheduledJobExecute=Next scheduled job to execute -NumberScheduledJobError=Number of scheduled jobs in error diff --git a/htdocs/langs/ar_IQ/deliveries.lang b/htdocs/langs/ar_IQ/deliveries.lang deleted file mode 100644 index cd8a36e6c70..00000000000 --- a/htdocs/langs/ar_IQ/deliveries.lang +++ /dev/null @@ -1,33 +0,0 @@ -# Dolibarr language file - Source file is en_US - deliveries -Delivery=Delivery -DeliveryRef=Ref Delivery -DeliveryCard=Receipt card -DeliveryOrder=Delivery receipt -DeliveryDate=Delivery date -CreateDeliveryOrder=Generate delivery receipt -DeliveryStateSaved=Delivery state saved -SetDeliveryDate=Set shipping date -ValidateDeliveryReceipt=Validate delivery receipt -ValidateDeliveryReceiptConfirm=Are you sure you want to validate this delivery receipt? -DeleteDeliveryReceipt=Delete delivery receipt -DeleteDeliveryReceiptConfirm=Are you sure you want to delete delivery receipt %s? -DeliveryMethod=Delivery method -TrackingNumber=Tracking number -DeliveryNotValidated=Delivery not validated -StatusDeliveryCanceled=Canceled -StatusDeliveryDraft=Draft -StatusDeliveryValidated=Received -# merou PDF model -NameAndSignature=Name and Signature: -ToAndDate=To___________________________________ on ____/_____/__________ -GoodStatusDeclaration=Have received the goods above in good condition, -Deliverer=Deliverer: -Sender=Sender -Recipient=Recipient -ErrorStockIsNotEnough=There's not enough stock -Shippable=Shippable -NonShippable=Not Shippable -ShowShippableStatus=Show shippable status -ShowReceiving=Show delivery receipt -NonExistentOrder=Nonexistent order -StockQuantitiesAlreadyAllocatedOnPreviousLines = Stock quantities already allocated on previous lines diff --git a/htdocs/langs/ar_IQ/dict.lang b/htdocs/langs/ar_IQ/dict.lang deleted file mode 100644 index 0524cf1ca18..00000000000 --- a/htdocs/langs/ar_IQ/dict.lang +++ /dev/null @@ -1,359 +0,0 @@ -# Dolibarr language file - Source file is en_US - dict -CountryFR=France -CountryBE=Belgium -CountryIT=Italy -CountryES=Spain -CountryDE=Germany -CountryCH=Switzerland -# Warning, country code GB is for United Kingdom. UK Does not exists as country code in ISO standard. -CountryGB=United Kingdom -CountryUK=United Kingdom -CountryIE=Ireland -CountryCN=China -CountryTN=Tunisia -CountryUS=United States -CountryMA=Morocco -CountryDZ=Algeria -CountryCA=Canada -CountryTG=Togo -CountryGA=Gabon -CountryNL=Netherlands -CountryHU=Hungary -CountryRU=Russia -CountrySE=Sweden -CountryCI=Ivory Coast -CountrySN=Senegal -CountryAR=Argentina -CountryCM=Cameroon -CountryPT=Portugal -CountrySA=Saudi Arabia -CountryMC=Monaco -CountryAU=Australia -CountrySG=Singapore -CountryAF=Afghanistan -CountryAX=Åland Islands -CountryAL=Albania -CountryAS=American Samoa -CountryAD=Andorra -CountryAO=Angola -CountryAI=Anguilla -CountryAQ=Antarctica -CountryAG=Antigua and Barbuda -CountryAM=Armenia -CountryAW=Aruba -CountryAT=Austria -CountryAZ=Azerbaijan -CountryBS=Bahamas -CountryBH=Bahrain -CountryBD=Bangladesh -CountryBB=Barbados -CountryBY=Belarus -CountryBZ=Belize -CountryBJ=Benin -CountryBM=Bermuda -CountryBT=Bhutan -CountryBO=Bolivia -CountryBA=Bosnia and Herzegovina -CountryBW=Botswana -CountryBV=Bouvet Island -CountryBR=Brazil -CountryIO=British Indian Ocean Territory -CountryBN=Brunei Darussalam -CountryBG=Bulgaria -CountryBF=Burkina Faso -CountryBI=Burundi -CountryKH=Cambodia -CountryCV=Cape Verde -CountryKY=Cayman Islands -CountryCF=Central African Republic -CountryTD=Chad -CountryCL=Chile -CountryCX=Christmas Island -CountryCC=Cocos (Keeling) Islands -CountryCO=Colombia -CountryKM=Comoros -CountryCG=Congo -CountryCD=Congo, The Democratic Republic of the -CountryCK=Cook Islands -CountryCR=Costa Rica -CountryHR=Croatia -CountryCU=Cuba -CountryCY=Cyprus -CountryCZ=Czech Republic -CountryDK=Denmark -CountryDJ=Djibouti -CountryDM=Dominica -CountryDO=Dominican Republic -CountryEC=Ecuador -CountryEG=Egypt -CountrySV=El Salvador -CountryGQ=Equatorial Guinea -CountryER=Eritrea -CountryEE=Estonia -CountryET=Ethiopia -CountryFK=Falkland Islands -CountryFO=Faroe Islands -CountryFJ=Fiji Islands -CountryFI=Finland -CountryGF=French Guiana -CountryPF=French Polynesia -CountryTF=French Southern Territories -CountryGM=Gambia -CountryGE=Georgia -CountryGH=Ghana -CountryGI=Gibraltar -CountryGR=Greece -CountryGL=Greenland -CountryGD=Grenada -CountryGP=Guadeloupe -CountryGU=Guam -CountryGT=Guatemala -CountryGN=Guinea -CountryGW=Guinea-Bissau -CountryGY=Guyana -CountryHT=Haïti -CountryHM=Heard Island and McDonald -CountryVA=Holy See (Vatican City State) -CountryHN=Honduras -CountryHK=Hong Kong -CountryIS=Iceland -CountryIN=India -CountryID=Indonesia -CountryIR=Iran -CountryIQ=Iraq -CountryIL=Israel -CountryJM=Jamaica -CountryJP=Japan -CountryJO=Jordan -CountryKZ=Kazakhstan -CountryKE=Kenya -CountryKI=Kiribati -CountryKP=North Korea -CountryKR=South Korea -CountryKW=Kuwait -CountryKG=Kyrgyzstan -CountryLA=Lao -CountryLV=Latvia -CountryLB=Lebanon -CountryLS=Lesotho -CountryLR=Liberia -CountryLY=Libyan -CountryLI=Liechtenstein -CountryLT=Lithuania -CountryLU=Luxembourg -CountryMO=Macao -CountryMK=Macedonia, the former Yugoslav of -CountryMG=Madagascar -CountryMW=Malawi -CountryMY=Malaysia -CountryMV=Maldives -CountryML=Mali -CountryMT=Malta -CountryMH=Marshall Islands -CountryMQ=Martinique -CountryMR=Mauritania -CountryMU=Mauritius -CountryYT=Mayotte -CountryMX=Mexico -CountryFM=Micronesia -CountryMD=Moldova -CountryMN=Mongolia -CountryMS=Monserrat -CountryMZ=Mozambique -CountryMM=Myanmar (Burma) -CountryNA=Namibia -CountryNR=Nauru -CountryNP=Nepal -CountryAN=Netherlands Antilles -CountryNC=New Caledonia -CountryNZ=New Zealand -CountryNI=Nicaragua -CountryNE=Niger -CountryNG=Nigeria -CountryNU=Niue -CountryNF=Norfolk Island -CountryMP=Northern Mariana Islands -CountryNO=Norway -CountryOM=Oman -CountryPK=Pakistan -CountryPW=Palau -CountryPS=Palestinian Territory, Occupied -CountryPA=Panama -CountryPG=Papua New Guinea -CountryPY=Paraguay -CountryPE=Peru -CountryPH=Philippines -CountryPN=Pitcairn Islands -CountryPL=Poland -CountryPR=Puerto Rico -CountryQA=Qatar -CountryRE=Reunion -CountryRO=Romania -CountryRW=Rwanda -CountrySH=Saint Helena -CountryKN=Saint Kitts and Nevis -CountryLC=Saint Lucia -CountryPM=Saint Pierre and Miquelon -CountryVC=Saint Vincent and Grenadines -CountryWS=Samoa -CountrySM=San Marino -CountryST=Sao Tome and Principe -CountryRS=Serbia -CountrySC=Seychelles -CountrySL=Sierra Leone -CountrySK=Slovakia -CountrySI=Slovenia -CountrySB=Solomon Islands -CountrySO=Somalia -CountryZA=South Africa -CountryGS=South Georgia and the South Sandwich Islands -CountryLK=Sri Lanka -CountrySD=Sudan -CountrySR=Suriname -CountrySJ=Svalbard and Jan Mayen -CountrySZ=Swaziland -CountrySY=Syrian -CountryTW=Taiwan -CountryTJ=Tajikistan -CountryTZ=Tanzania -CountryTH=Thailand -CountryTL=Timor-Leste -CountryTK=Tokelau -CountryTO=Tonga -CountryTT=Trinidad and Tobago -CountryTR=Turkey -CountryTM=Turkmenistan -CountryTC=Turks and Caicos Islands -CountryTV=Tuvalu -CountryUG=Uganda -CountryUA=Ukraine -CountryAE=United Arab Emirates -CountryUM=United States Minor Outlying Islands -CountryUY=Uruguay -CountryUZ=Uzbekistan -CountryVU=Vanuatu -CountryVE=Venezuela -CountryVN=Viet Nam -CountryVG=Virgin Islands, British -CountryVI=Virgin Islands, U.S. -CountryWF=Wallis and Futuna -CountryEH=Western Sahara -CountryYE=Yemen -CountryZM=Zambia -CountryZW=Zimbabwe -CountryGG=Guernsey -CountryIM=Isle of Man -CountryJE=Jersey -CountryME=Montenegro -CountryBL=Saint Barthelemy -CountryMF=Saint Martin - -##### Civilities ##### -CivilityMME=Mrs. -CivilityMR=Mr. -CivilityMLE=Ms. -CivilityMTRE=Master -CivilityDR=Doctor -##### Currencies ##### -Currencyeuros=Euros -CurrencyAUD=AU Dollars -CurrencySingAUD=AU Dollar -CurrencyCAD=CAN Dollars -CurrencySingCAD=CAN Dollar -CurrencyCHF=Swiss Francs -CurrencySingCHF=Swiss Franc -CurrencyEUR=Euros -CurrencySingEUR=Euro -CurrencyFRF=French Francs -CurrencySingFRF=French Franc -CurrencyGBP=GB Pounds -CurrencySingGBP=GB Pound -CurrencyINR=Indian rupees -CurrencySingINR=Indian rupee -CurrencyMAD=Dirham -CurrencySingMAD=Dirham -CurrencyMGA=Ariary -CurrencySingMGA=Ariary -CurrencyMUR=Mauritius rupees -CurrencySingMUR=Mauritius rupee -CurrencyNOK=Norwegian krones -CurrencySingNOK=Norwegian kronas -CurrencyTND=Tunisian dinars -CurrencySingTND=Tunisian dinar -CurrencyUSD=US Dollars -CurrencySingUSD=US Dollar -CurrencyUAH=Hryvnia -CurrencySingUAH=Hryvnia -CurrencyXAF=CFA Francs BEAC -CurrencySingXAF=CFA Franc BEAC -CurrencyXOF=CFA Francs BCEAO -CurrencySingXOF=CFA Franc BCEAO -CurrencyXPF=CFP Francs -CurrencySingXPF=CFP Franc -CurrencyCentEUR=cents -CurrencyCentSingEUR=cent -CurrencyCentINR=paisa -CurrencyCentSingINR=paise -CurrencyThousandthSingTND=thousandth -#### Input reasons ##### -DemandReasonTypeSRC_INTE=Internet -DemandReasonTypeSRC_CAMP_MAIL=Mailing campaign -DemandReasonTypeSRC_CAMP_EMAIL=EMailing campaign -DemandReasonTypeSRC_CAMP_PHO=Phone campaign -DemandReasonTypeSRC_CAMP_FAX=Fax campaign -DemandReasonTypeSRC_COMM=Commercial contact -DemandReasonTypeSRC_SHOP=Shop contact -DemandReasonTypeSRC_WOM=Word of mouth -DemandReasonTypeSRC_PARTNER=Partner -DemandReasonTypeSRC_EMPLOYEE=Employee -DemandReasonTypeSRC_SPONSORING=Sponsorship -DemandReasonTypeSRC_SRC_CUSTOMER=Incoming contact of a customer -#### Paper formats #### -PaperFormatEU4A0=Format 4A0 -PaperFormatEU2A0=Format 2A0 -PaperFormatEUA0=Format A0 -PaperFormatEUA1=Format A1 -PaperFormatEUA2=Format A2 -PaperFormatEUA3=Format A3 -PaperFormatEUA4=Format A4 -PaperFormatEUA5=Format A5 -PaperFormatEUA6=Format A6 -PaperFormatUSLETTER=Format Letter US -PaperFormatUSLEGAL=Format Legal US -PaperFormatUSEXECUTIVE=Format Executive US -PaperFormatUSLEDGER=Format Ledger/Tabloid -PaperFormatCAP1=Format P1 Canada -PaperFormatCAP2=Format P2 Canada -PaperFormatCAP3=Format P3 Canada -PaperFormatCAP4=Format P4 Canada -PaperFormatCAP5=Format P5 Canada -PaperFormatCAP6=Format P6 Canada -#### Expense report categories #### -ExpAutoCat=Car -ExpCycloCat=Moped -ExpMotoCat=Motorbike -ExpAuto3CV=3 CV -ExpAuto4CV=4 CV -ExpAuto5CV=5 CV -ExpAuto6CV=6 CV -ExpAuto7CV=7 CV -ExpAuto8CV=8 CV -ExpAuto9CV=9 CV -ExpAuto10CV=10 CV -ExpAuto11CV=11 CV -ExpAuto12CV=12 CV -ExpAuto3PCV=3 CV and more -ExpAuto4PCV=4 CV and more -ExpAuto5PCV=5 CV and more -ExpAuto6PCV=6 CV and more -ExpAuto7PCV=7 CV and more -ExpAuto8PCV=8 CV and more -ExpAuto9PCV=9 CV and more -ExpAuto10PCV=10 CV and more -ExpAuto11PCV=11 CV and more -ExpAuto12PCV=12 CV and more -ExpAuto13PCV=13 CV and more -ExpCyclo=Capacity lower to 50cm3 -ExpMoto12CV=Motorbike 1 or 2 CV -ExpMoto345CV=Motorbike 3, 4 or 5 CV -ExpMoto5PCV=Motorbike 5 CV and more diff --git a/htdocs/langs/ar_IQ/donations.lang b/htdocs/langs/ar_IQ/donations.lang deleted file mode 100644 index d512abb2eea..00000000000 --- a/htdocs/langs/ar_IQ/donations.lang +++ /dev/null @@ -1,35 +0,0 @@ -# Dolibarr language file - Source file is en_US - donations -Donation=Donation -Donations=Donations -DonationRef=Donation ref. -Donor=Donor -AddDonation=Create a donation -NewDonation=New donation -DeleteADonation=Delete a donation -ConfirmDeleteADonation=Are you sure you want to delete this donation? -PublicDonation=Public donation -DonationsArea=Donations area -DonationStatusPromiseNotValidated=Draft promise -DonationStatusPromiseValidated=Validated promise -DonationStatusPaid=Donation received -DonationStatusPromiseNotValidatedShort=Draft -DonationStatusPromiseValidatedShort=Validated -DonationStatusPaidShort=Received -DonationTitle=Donation receipt -DonationDate=Donation date -DonationDatePayment=Payment date -ValidPromess=Validate promise -DonationReceipt=Donation receipt -DonationsModels=Documents models for donation receipts -LastModifiedDonations=Latest %s modified donations -DonationRecipient=Donation recipient -IConfirmDonationReception=The recipient declare reception, as a donation, of the following amount -MinimumAmount=Minimum amount is %s -FreeTextOnDonations=Free text to show in footer -FrenchOptions=Options for France -DONATION_ART200=Show article 200 from CGI if you are concerned -DONATION_ART238=Show article 238 from CGI if you are concerned -DONATION_ART885=Show article 885 from CGI if you are concerned -DonationPayment=Donation payment -DonationValidated=Donation %s validated -DonationUseThirdparties=Use an existing thirdparty as coordinates of donators diff --git a/htdocs/langs/ar_IQ/ecm.lang b/htdocs/langs/ar_IQ/ecm.lang deleted file mode 100644 index bc18bed4a29..00000000000 --- a/htdocs/langs/ar_IQ/ecm.lang +++ /dev/null @@ -1,47 +0,0 @@ -# Dolibarr language file - Source file is en_US - ecm -ECMNbOfDocs=No. of documents in directory -ECMSection=Directory -ECMSectionManual=Manual directory -ECMSectionAuto=Automatic directory -ECMSectionsManual=Manual tree -ECMSectionsAuto=Automatic tree -ECMSections=Directories -ECMRoot=ECM Root -ECMNewSection=New directory -ECMAddSection=Add directory -ECMCreationDate=Creation date -ECMNbOfFilesInDir=Number of files in directory -ECMNbOfSubDir=Number of sub-directories -ECMNbOfFilesInSubDir=Number of files in sub-directories -ECMCreationUser=Creator -ECMArea=DMS/ECM area -ECMAreaDesc=The DMS/ECM (Document Management System / Electronic Content Management) area allows you to save, share and search quickly all kind of documents in Dolibarr. -ECMAreaDesc2=* Automatic directories are filled automatically when adding documents from card of an element.
    * Manual directories can be used to save documents not linked to a particular element. -ECMSectionWasRemoved=Directory %s has been deleted. -ECMSectionWasCreated=Directory %s has been created. -ECMSearchByKeywords=Search by keywords -ECMSearchByEntity=Search by object -ECMSectionOfDocuments=Directories of documents -ECMTypeAuto=Automatic -ECMDocsBy=Documents linked to %s -ECMNoDirectoryYet=No directory created -ShowECMSection=Show directory -DeleteSection=Remove directory -ConfirmDeleteSection=Can you confirm you want to delete the directory %s? -ECMDirectoryForFiles=Relative directory for files -CannotRemoveDirectoryContainsFilesOrDirs=Removal not possible because it contains some files or sub-directories -CannotRemoveDirectoryContainsFiles=Removal not possible because it contains some files -ECMFileManager=File manager -ECMSelectASection=Select a directory in the tree... -DirNotSynchronizedSyncFirst=This directory seems to be created or modified outside ECM module. You must click on "Resync" button first to synchronize disk and database to get content of this directory. -ReSyncListOfDir=Resync list of directories -HashOfFileContent=Hash of file content -NoDirectoriesFound=No directories found -FileNotYetIndexedInDatabase=File not yet indexed into database (try to re-upload it) -ExtraFieldsEcmFiles=Extrafields Ecm Files -ExtraFieldsEcmDirectories=Extrafields Ecm Directories -ECMSetup=ECM Setup -GenerateImgWebp=Duplicate all images with another version with .webp format -ConfirmGenerateImgWebp=If you confirm, you will generate an image in .webp format for all images currently into this folder (subfolders are not included)... -ConfirmImgWebpCreation=Confirm all images duplication -SucessConvertImgWebp=Images successfully duplicated diff --git a/htdocs/langs/ar_IQ/errors.lang b/htdocs/langs/ar_IQ/errors.lang deleted file mode 100644 index 45b2c258c41..00000000000 --- a/htdocs/langs/ar_IQ/errors.lang +++ /dev/null @@ -1,305 +0,0 @@ -# Dolibarr language file - Source file is en_US - errors - -# No errors -NoErrorCommitIsDone=No error, we commit -# Errors -ErrorButCommitIsDone=Errors found but we validate despite this -ErrorBadEMail=Email %s is incorrect -ErrorBadMXDomain=Email %s seems incorrect (domain has no valid MX record) -ErrorBadUrl=Url %s is incorrect -ErrorBadValueForParamNotAString=Bad value for your parameter. It appends generally when translation is missing. -ErrorRefAlreadyExists=Reference %s already exists. -ErrorLoginAlreadyExists=Login %s already exists. -ErrorGroupAlreadyExists=Group %s already exists. -ErrorEmailAlreadyExists=Email %s already exists. -ErrorRecordNotFound=Record not found. -ErrorFailToCopyFile=Failed to copy file '%s' into '%s'. -ErrorFailToCopyDir=Failed to copy directory '%s' into '%s'. -ErrorFailToRenameFile=Failed to rename file '%s' into '%s'. -ErrorFailToDeleteFile=Failed to remove file '%s'. -ErrorFailToCreateFile=Failed to create file '%s'. -ErrorFailToRenameDir=Failed to rename directory '%s' into '%s'. -ErrorFailToCreateDir=Failed to create directory '%s'. -ErrorFailToDeleteDir=Failed to delete directory '%s'. -ErrorFailToMakeReplacementInto=Failed to make replacement into file '%s'. -ErrorFailToGenerateFile=Failed to generate file '%s'. -ErrorThisContactIsAlreadyDefinedAsThisType=This contact is already defined as contact for this type. -ErrorCashAccountAcceptsOnlyCashMoney=This bank account is a cash account, so it accepts payments of type cash only. -ErrorFromToAccountsMustDiffers=Source and targets bank accounts must be different. -ErrorBadThirdPartyName=Bad value for third-party name -ErrorProdIdIsMandatory=The %s is mandatory -ErrorBadCustomerCodeSyntax=Bad syntax for customer code -ErrorBadBarCodeSyntax=Bad syntax for barcode. May be you set a bad barcode type or you defined a barcode mask for numbering that does not match value scanned. -ErrorCustomerCodeRequired=Customer code required -ErrorBarCodeRequired=Barcode required -ErrorCustomerCodeAlreadyUsed=Customer code already used -ErrorBarCodeAlreadyUsed=Barcode already used -ErrorPrefixRequired=Prefix required -ErrorBadSupplierCodeSyntax=Bad syntax for vendor code -ErrorSupplierCodeRequired=Vendor code required -ErrorSupplierCodeAlreadyUsed=Vendor code already used -ErrorBadParameters=Bad parameters -ErrorWrongParameters=Wrong or missing parameters -ErrorBadValueForParameter=Wrong value '%s' for parameter '%s' -ErrorBadImageFormat=Image file has not a supported format (Your PHP does not support functions to convert images of this format) -ErrorBadDateFormat=Value '%s' has wrong date format -ErrorWrongDate=Date is not correct! -ErrorFailedToWriteInDir=Failed to write in directory %s -ErrorFoundBadEmailInFile=Found incorrect email syntax for %s lines in file (example line %s with email=%s) -ErrorUserCannotBeDelete=User cannot be deleted. Maybe it is associated to Dolibarr entities. -ErrorFieldsRequired=Some required fields have been left blank. -ErrorSubjectIsRequired=The email subject is required -ErrorFailedToCreateDir=Failed to create a directory. Check that Web server user has permissions to write into Dolibarr documents directory. If parameter safe_mode is enabled on this PHP, check that Dolibarr php files owns to web server user (or group). -ErrorNoMailDefinedForThisUser=No mail defined for this user -ErrorSetupOfEmailsNotComplete=Setup of emails is not complete -ErrorFeatureNeedJavascript=This feature need javascript to be activated to work. Change this in setup - display. -ErrorTopMenuMustHaveAParentWithId0=A menu of type 'Top' can't have a parent menu. Put 0 in parent menu or choose a menu of type 'Left'. -ErrorLeftMenuMustHaveAParentId=A menu of type 'Left' must have a parent id. -ErrorFileNotFound=File %s not found (Bad path, wrong permissions or access denied by PHP openbasedir or safe_mode parameter) -ErrorDirNotFound=Directory %s not found (Bad path, wrong permissions or access denied by PHP openbasedir or safe_mode parameter) -ErrorFunctionNotAvailableInPHP=Function %s is required for this feature but is not available in this version/setup of PHP. -ErrorDirAlreadyExists=A directory with this name already exists. -ErrorFileAlreadyExists=A file with this name already exists. -ErrorDestinationAlreadyExists=Another file with the name %s already exists. -ErrorPartialFile=File not received completely by server. -ErrorNoTmpDir=Temporary directy %s does not exists. -ErrorUploadBlockedByAddon=Upload blocked by a PHP/Apache plugin. -ErrorFileSizeTooLarge=File size is too large. -ErrorFieldTooLong=Field %s is too long. -ErrorSizeTooLongForIntType=Size too long for int type (%s digits maximum) -ErrorSizeTooLongForVarcharType=Size too long for string type (%s chars maximum) -ErrorNoValueForSelectType=Please fill value for select list -ErrorNoValueForCheckBoxType=Please fill value for checkbox list -ErrorNoValueForRadioType=Please fill value for radio list -ErrorBadFormatValueList=The list value cannot have more than one comma: %s, but need at least one: key,value -ErrorFieldCanNotContainSpecialCharacters=The field %s must not contains special characters. -ErrorFieldCanNotContainSpecialNorUpperCharacters=The field %s must not contain special characters, nor upper case characters and cannot contain only numbers. -ErrorFieldMustHaveXChar=The field %s must have at least %s characters. -ErrorNoAccountancyModuleLoaded=No accountancy module activated -ErrorExportDuplicateProfil=This profile name already exists for this export set. -ErrorLDAPSetupNotComplete=Dolibarr-LDAP matching is not complete. -ErrorLDAPMakeManualTest=A .ldif file has been generated in directory %s. Try to load it manually from command line to have more information on errors. -ErrorCantSaveADoneUserWithZeroPercentage=Can't save an action with "status not started" if field "done by" is also filled. -ErrorRefAlreadyExists=Reference %s already exists. -ErrorPleaseTypeBankTransactionReportName=Please enter the bank statement name where the entry has to be reported (Format YYYYMM or YYYYMMDD) -ErrorRecordHasChildren=Failed to delete record since it has some child records. -ErrorRecordHasAtLeastOneChildOfType=Object has at least one child of type %s -ErrorRecordIsUsedCantDelete=Can't delete record. It is already used or included into another object. -ErrorModuleRequireJavascript=Javascript must not be disabled to have this feature working. To enable/disable Javascript, go to menu Home->Setup->Display. -ErrorPasswordsMustMatch=Both typed passwords must match each other -ErrorContactEMail=A technical error occured. Please, contact administrator to following email %s and provide the error code %s in your message, or add a screen copy of this page. -ErrorWrongValueForField=Field %s: '%s' does not match regex rule %s -ErrorFieldValueNotIn=Field %s: '%s' is not a value found in field %s of %s -ErrorFieldRefNotIn=Field %s: '%s' is not a %s existing ref -ErrorsOnXLines=%s errors found -ErrorFileIsInfectedWithAVirus=The antivirus program was not able to validate the file (file might be infected by a virus) -ErrorSpecialCharNotAllowedForField=Special characters are not allowed for field "%s" -ErrorNumRefModel=A reference exists into database (%s) and is not compatible with this numbering rule. Remove record or renamed reference to activate this module. -ErrorQtyTooLowForThisSupplier=Quantity too low for this vendor or no price defined on this product for this vendor -ErrorOrdersNotCreatedQtyTooLow=Some orders haven't been created because of too-low quantities -ErrorModuleSetupNotComplete=Setup of module %s looks to be uncomplete. Go on Home - Setup - Modules to complete. -ErrorBadMask=Error on mask -ErrorBadMaskFailedToLocatePosOfSequence=Error, mask without sequence number -ErrorBadMaskBadRazMonth=Error, bad reset value -ErrorMaxNumberReachForThisMask=Maximum number reached for this mask -ErrorCounterMustHaveMoreThan3Digits=Counter must have more than 3 digits -ErrorSelectAtLeastOne=Error, select at least one entry. -ErrorDeleteNotPossibleLineIsConsolidated=Delete not possible because record is linked to a bank transaction that is conciliated -ErrorProdIdAlreadyExist=%s is assigned to another third -ErrorFailedToSendPassword=Failed to send password -ErrorFailedToLoadRSSFile=Fails to get RSS feed. Try to add constant MAIN_SIMPLEXMLLOAD_DEBUG if error messages does not provide enough information. -ErrorForbidden=Access denied.
    You try to access to a page, area or feature of a disabled module or without being in an authenticated session or that is not allowed to your user. -ErrorForbidden2=Permission for this login can be defined by your Dolibarr administrator from menu %s->%s. -ErrorForbidden3=It seems that Dolibarr is not used through an authenticated session. Take a look at Dolibarr setup documentation to know how to manage authentications (htaccess, mod_auth or other...). -ErrorNoImagickReadimage=Class Imagick is not found in this PHP. No preview can be available. Administrators can disable this tab from menu Setup - Display. -ErrorRecordAlreadyExists=Record already exists -ErrorLabelAlreadyExists=This label already exists -ErrorCantReadFile=Failed to read file '%s' -ErrorCantReadDir=Failed to read directory '%s' -ErrorBadLoginPassword=Bad value for login or password -ErrorLoginDisabled=Your account has been disabled -ErrorFailedToRunExternalCommand=Failed to run external command. Check it is available and runnable by your PHP server user. Check also the command is not protected on shell level by a security layer like apparmor. -ErrorFailedToChangePassword=Failed to change password -ErrorLoginDoesNotExists=User with login %s could not be found. -ErrorLoginHasNoEmail=This user has no email address. Process aborted. -ErrorBadValueForCode=Bad value for security code. Try again with new value... -ErrorBothFieldCantBeNegative=Fields %s and %s can't be both negative -ErrorFieldCantBeNegativeOnInvoice=Field %s cannot be negative on this type of invoice. If you need to add a discount line, just create the discount first (from field '%s' in thirdparty card) and apply it to the invoice. -ErrorLinesCantBeNegativeForOneVATRate=Total of lines (net of tax) can't be negative for a given not null VAT rate (Found a negative total for VAT rate %s%%). -ErrorLinesCantBeNegativeOnDeposits=Lines can't be negative in a deposit. You will face problems when you will need to consume the deposit in final invoice if you do so. -ErrorQtyForCustomerInvoiceCantBeNegative=Quantity for line into customer invoices can't be negative -ErrorWebServerUserHasNotPermission=User account %s used to execute web server has no permission for that -ErrorNoActivatedBarcode=No barcode type activated -ErrUnzipFails=Failed to unzip %s with ZipArchive -ErrNoZipEngine=No engine to zip/unzip %s file in this PHP -ErrorFileMustBeADolibarrPackage=The file %s must be a Dolibarr zip package -ErrorModuleFileRequired=You must select a Dolibarr module package file -ErrorPhpCurlNotInstalled=The PHP CURL is not installed, this is essential to talk with Paypal -ErrorFailedToAddToMailmanList=Failed to add record %s to Mailman list %s or SPIP base -ErrorFailedToRemoveToMailmanList=Failed to remove record %s to Mailman list %s or SPIP base -ErrorNewValueCantMatchOldValue=New value can't be equal to old one -ErrorFailedToValidatePasswordReset=Failed to reinit password. May be the reinit was already done (this link can be used only one time). If not, try to restart the reinit process. -ErrorToConnectToMysqlCheckInstance=Connect to database fails. Check database server is running (for example, with mysql/mariadb, you can launch it from command line with 'sudo service mysql start'). -ErrorFailedToAddContact=Failed to add contact -ErrorDateMustBeBeforeToday=The date must be lower than today -ErrorDateMustBeInFuture=The date must be greater than today -ErrorPaymentModeDefinedToWithoutSetup=A payment mode was set to type %s but setup of module Invoice was not completed to define information to show for this payment mode. -ErrorPHPNeedModule=Error, your PHP must have module %s installed to use this feature. -ErrorOpenIDSetupNotComplete=You setup Dolibarr config file to allow OpenID authentication, but URL of OpenID service is not defined into constant %s -ErrorWarehouseMustDiffers=Source and target warehouses must differs -ErrorBadFormat=Bad format! -ErrorMemberNotLinkedToAThirpartyLinkOrCreateFirst=Error, this member is not yet linked to any third party. Link member to an existing third party or create a new third party before creating subscription with invoice. -ErrorThereIsSomeDeliveries=Error, there is some deliveries linked to this shipment. Deletion refused. -ErrorCantDeletePaymentReconciliated=Can't delete a payment that had generated a bank entry that was reconciled -ErrorCantDeletePaymentSharedWithPayedInvoice=Can't delete a payment shared by at least one invoice with status Paid -ErrorPriceExpression1=Cannot assign to constant '%s' -ErrorPriceExpression2=Cannot redefine built-in function '%s' -ErrorPriceExpression3=Undefined variable '%s' in function definition -ErrorPriceExpression4=Illegal character '%s' -ErrorPriceExpression5=Unexpected '%s' -ErrorPriceExpression6=Wrong number of arguments (%s given, %s expected) -ErrorPriceExpression8=Unexpected operator '%s' -ErrorPriceExpression9=An unexpected error occured -ErrorPriceExpression10=Operator '%s' lacks operand -ErrorPriceExpression11=Expecting '%s' -ErrorPriceExpression14=Division by zero -ErrorPriceExpression17=Undefined variable '%s' -ErrorPriceExpression19=Expression not found -ErrorPriceExpression20=Empty expression -ErrorPriceExpression21=Empty result '%s' -ErrorPriceExpression22=Negative result '%s' -ErrorPriceExpression23=Unknown or non set variable '%s' in %s -ErrorPriceExpression24=Variable '%s' exists but has no value -ErrorPriceExpressionInternal=Internal error '%s' -ErrorPriceExpressionUnknown=Unknown error '%s' -ErrorSrcAndTargetWarehouseMustDiffers=Source and target warehouses must differs -ErrorTryToMakeMoveOnProductRequiringBatchData=Error, trying to make a stock movement without lot/serial information, on product '%s' requiring lot/serial information -ErrorCantSetReceptionToTotalDoneWithReceptionToApprove=All recorded receptions must first be verified (approved or denied) before being allowed to do this action -ErrorCantSetReceptionToTotalDoneWithReceptionDenied=All recorded receptions must first be verified (approved) before being allowed to do this action -ErrorGlobalVariableUpdater0=HTTP request failed with error '%s' -ErrorGlobalVariableUpdater1=Invalid JSON format '%s' -ErrorGlobalVariableUpdater2=Missing parameter '%s' -ErrorGlobalVariableUpdater3=The requested data was not found in result -ErrorGlobalVariableUpdater4=SOAP client failed with error '%s' -ErrorGlobalVariableUpdater5=No global variable selected -ErrorFieldMustBeANumeric=Field %s must be a numeric value -ErrorMandatoryParametersNotProvided=Mandatory parameter(s) not provided -ErrorOppStatusRequiredIfAmount=You set an estimated amount for this lead. So you must also enter it's status. -ErrorFailedToLoadModuleDescriptorForXXX=Failed to load module descriptor class for %s -ErrorBadDefinitionOfMenuArrayInModuleDescriptor=Bad Definition Of Menu Array In Module Descriptor (bad value for key fk_menu) -ErrorSavingChanges=An error has occurred when saving the changes -ErrorWarehouseRequiredIntoShipmentLine=Warehouse is required on the line to ship -ErrorFileMustHaveFormat=File must have format %s -ErrorFilenameCantStartWithDot=Filename can't start with a '.' -ErrorSupplierCountryIsNotDefined=Country for this vendor is not defined. Correct this first. -ErrorsThirdpartyMerge=Failed to merge the two records. Request canceled. -ErrorStockIsNotEnoughToAddProductOnOrder=Stock is not enough for product %s to add it into a new order. -ErrorStockIsNotEnoughToAddProductOnInvoice=Stock is not enough for product %s to add it into a new invoice. -ErrorStockIsNotEnoughToAddProductOnShipment=Stock is not enough for product %s to add it into a new shipment. -ErrorStockIsNotEnoughToAddProductOnProposal=Stock is not enough for product %s to add it into a new proposal. -ErrorFailedToLoadLoginFileForMode=Failed to get the login key for mode '%s'. -ErrorModuleNotFound=File of module was not found. -ErrorFieldAccountNotDefinedForBankLine=Value for Accounting account not defined for source line id %s (%s) -ErrorFieldAccountNotDefinedForInvoiceLine=Value for Accounting account not defined for invoice id %s (%s) -ErrorFieldAccountNotDefinedForLine=Value for Accounting account not defined for the line (%s) -ErrorBankStatementNameMustFollowRegex=Error, bank statement name must follow the following syntax rule %s -ErrorPhpMailDelivery=Check that you don't use a too high number of recipients and that your email content is not similar to a Spam. Ask also your administrator to check firewall and server logs files for a more complete information. -ErrorUserNotAssignedToTask=User must be assigned to task to be able to enter time consumed. -ErrorTaskAlreadyAssigned=Task already assigned to user -ErrorModuleFileSeemsToHaveAWrongFormat=The module package seems to have a wrong format. -ErrorModuleFileSeemsToHaveAWrongFormat2=At least one mandatory directory must exists into zip of module: %s or %s -ErrorFilenameDosNotMatchDolibarrPackageRules=The name of the module package (%s) does not match expected name syntax: %s -ErrorDuplicateTrigger=Error, duplicate trigger name %s. Already loaded from %s. -ErrorNoWarehouseDefined=Error, no warehouses defined. -ErrorBadLinkSourceSetButBadValueForRef=The link you use is not valid. A 'source' for payment is defined, but value for 'ref' is not valid. -ErrorTooManyErrorsProcessStopped=Too many errors. Process was stopped. -ErrorMassValidationNotAllowedWhenStockIncreaseOnAction=Mass validation is not possible when option to increase/decrease stock is set on this action (you must validate one by one so you can define the warehouse to increase/decrease) -ErrorObjectMustHaveStatusDraftToBeValidated=Object %s must have status 'Draft' to be validated. -ErrorObjectMustHaveLinesToBeValidated=Object %s must have lines to be validated. -ErrorOnlyInvoiceValidatedCanBeSentInMassAction=Only validated invoices can be sent using the "Send by email" mass action. -ErrorChooseBetweenFreeEntryOrPredefinedProduct=You must choose if article is a predefined product or not -ErrorDiscountLargerThanRemainToPaySplitItBefore=The discount you try to apply is larger than remain to pay. Split the discount in 2 smaller discounts before. -ErrorFileNotFoundWithSharedLink=File was not found. May be the share key was modified or file was removed recently. -ErrorProductBarCodeAlreadyExists=The product barcode %s already exists on another product reference. -ErrorNoteAlsoThatSubProductCantBeFollowedByLot=Note also that using kits to have auto increase/decrease of subproducts is not possible when at least one subproduct (or subproduct of subproducts) needs a serial/lot number. -ErrorDescRequiredForFreeProductLines=Description is mandatory for lines with free product -ErrorAPageWithThisNameOrAliasAlreadyExists=The page/container %s has the same name or alternative alias that the one your try to use -ErrorDuringChartLoad=Error when loading chart of accounts. If few accounts were not loaded, you can still enter them manually. -ErrorBadSyntaxForParamKeyForContent=Bad syntax for param keyforcontent. Must have a value starting with %s or %s -ErrorVariableKeyForContentMustBeSet=Error, the constant with name %s (with text content to show) or %s (with external url to show) must be set. -ErrorURLMustEndWith=URL %s must end %s -ErrorURLMustStartWithHttp=URL %s must start with http:// or https:// -ErrorHostMustNotStartWithHttp=Host name %s must NOT start with http:// or https:// -ErrorNewRefIsAlreadyUsed=Error, the new reference is already used -ErrorDeletePaymentLinkedToAClosedInvoiceNotPossible=Error, delete payment linked to a closed invoice is not possible. -ErrorSearchCriteriaTooSmall=Search criteria too small. -ErrorObjectMustHaveStatusActiveToBeDisabled=Objects must have status 'Active' to be disabled -ErrorObjectMustHaveStatusDraftOrDisabledToBeActivated=Objects must have status 'Draft' or 'Disabled' to be enabled -ErrorNoFieldWithAttributeShowoncombobox=No fields has property 'showoncombobox' into definition of object '%s'. No way to show the combolist. -ErrorFieldRequiredForProduct=Field '%s' is required for product %s -ProblemIsInSetupOfTerminal=Problem is in setup of terminal %s. -ErrorAddAtLeastOneLineFirst=Add at least one line first -ErrorRecordAlreadyInAccountingDeletionNotPossible=Error, record is already transferred in accounting, deletion is not possible. -ErrorLanguageMandatoryIfPageSetAsTranslationOfAnother=Error, language is mandatory if you set the page as a translation of another one. -ErrorLanguageOfTranslatedPageIsSameThanThisPage=Error, language of translated page is same than this one. -ErrorBatchNoFoundForProductInWarehouse=No lot/serial found for product "%s" in warehouse "%s". -ErrorBatchNoFoundEnoughQuantityForProductInWarehouse=No enough quantity for this lot/serial for product "%s" in warehouse "%s". -ErrorOnlyOneFieldForGroupByIsPossible=Only 1 field for the 'Group by' is possible (others are discarded) -ErrorTooManyDifferentValueForSelectedGroupBy=Found too many different value (more than %s) for the field '%s', so we can't use it as a 'Group by' for graphics. The field 'Group By' has been removed. May be you wanted to use it as an X-Axis ? -ErrorReplaceStringEmpty=Error, the string to replace into is empty -ErrorProductNeedBatchNumber=Error, product '%s' need a lot/serial number -ErrorProductDoesNotNeedBatchNumber=Error, product '%s' does not accept a lot/serial number -ErrorFailedToReadObject=Error, failed to read object of type %s -ErrorParameterMustBeEnabledToAllwoThisFeature=Error, parameter %s must be enabled into conf/conf.php to allow use of Command Line Interface by the internal job scheduler -ErrorLoginDateValidity=Error, this login is outside the validity date range -ErrorValueLength=Length of field '%s' must be higher than '%s' -ErrorReservedKeyword=The word '%s' is a reserved keyword -ErrorNotAvailableWithThisDistribution=Not available with this distribution -ErrorPublicInterfaceNotEnabled=Public interface was not enabled -ErrorLanguageRequiredIfPageIsTranslationOfAnother=The language of new page must be defined if it is set as a translation of another page -ErrorLanguageMustNotBeSourceLanguageIfPageIsTranslationOfAnother=The language of new page must not be the source language if it is set as a translation of another page -ErrorAParameterIsRequiredForThisOperation=A parameter is mandatory for this operation -ErrorDateIsInFuture=Error, the date can't be in the future -ErrorAnAmountWithoutTaxIsRequired=Error, amount is mandatory -ErrorAPercentIsRequired=Error, please fill in the percentage correctly -ErrorYouMustFirstSetupYourChartOfAccount=You must first setup your chart of account -ErrorFailedToFindEmailTemplate=Failed to find template with code name %s -ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Duration not defined on service. No way to calculate the hourly price. - -# Warnings -WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. -WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. -WarningMandatorySetupNotComplete=Click here to setup mandatory parameters -WarningEnableYourModulesApplications=Click here to enable your modules and applications -WarningSafeModeOnCheckExecDir=Warning, PHP option safe_mode is on so command must be stored inside a directory declared by php parameter safe_mode_exec_dir. -WarningBookmarkAlreadyExists=A bookmark with this title or this target (URL) already exists. -WarningPassIsEmpty=Warning, database password is empty. This is a security hole. You should add a password to your database and change your conf.php file to reflect this. -WarningConfFileMustBeReadOnly=Warning, your config file (htdocs/conf/conf.php) can be overwritten by the web server. This is a serious security hole. Modify permissions on file to be in read only mode for operating system user used by Web server. If you use Windows and FAT format for your disk, you must know that this file system does not allow to add permissions on file, so can't be completely safe. -WarningsOnXLines=Warnings on %s source record(s) -WarningNoDocumentModelActivated=No model, for document generation, has been activated. A model will be chosen by default until you check your module setup. -WarningLockFileDoesNotExists=Warning, once setup is finished, you must disable the installation/migration tools by adding a file install.lock into directory %s. Omitting the creation of this file is a grave security risk. -WarningUntilDirRemoved=All security warnings (visible by admin users only) will remain active as long as the vulnerability is present (or that constant MAIN_REMOVE_INSTALL_WARNING is added in Setup->Other Setup). -WarningCloseAlways=Warning, closing is done even if amount differs between source and target elements. Enable this feature with caution. -WarningUsingThisBoxSlowDown=Warning, using this box slow down seriously all pages showing the box. -WarningClickToDialUserSetupNotComplete=Setup of ClickToDial information for your user are not complete (see tab ClickToDial onto your user card). -WarningFeatureDisabledWithDisplayOptimizedForBlindNoJs=Feature disabled when display setup is optimized for blind person or text browsers. -WarningPaymentDateLowerThanInvoiceDate=Payment date (%s) is earlier than invoice date (%s) for invoice %s. -WarningTooManyDataPleaseUseMoreFilters=Too many data (more than %s lines). Please use more filters or set the constant %s to a higher limit. -WarningSomeLinesWithNullHourlyRate=Some times were recorded by some users while their hourly rate was not defined. A value of 0 %s per hour was used but this may result in wrong valuation of time spent. -WarningYourLoginWasModifiedPleaseLogin=Your login was modified. For security purpose you will have to login with your new login before next action. -WarningAnEntryAlreadyExistForTransKey=An entry already exists for the translation key for this language -WarningNumberOfRecipientIsRestrictedInMassAction=Warning, number of different recipient is limited to %s when using the mass actions on lists -WarningDateOfLineMustBeInExpenseReportRange=Warning, the date of line is not in the range of the expense report -WarningProjectDraft=Project is still in draft mode. Don't forget to validate it if you plan to use tasks. -WarningProjectClosed=Project is closed. You must re-open it first. -WarningSomeBankTransactionByChequeWereRemovedAfter=Some bank transaction were removed after that the receipt including them were generated. So nb of cheques and total of receipt may differ from number and total in list. -WarningFailedToAddFileIntoDatabaseIndex=Warning, failed to add file entry into ECM database index table -WarningTheHiddenOptionIsOn=Warning, the hidden option %s is on. -WarningCreateSubAccounts=Warning, you can't create directly a sub account, you must create a third party or an user and assign them an accounting code to find them in this list -WarningAvailableOnlyForHTTPSServers=Available only if using HTTPS secured connection. -WarningModuleXDisabledSoYouMayMissEventHere=Module %s has not been enabled. So you may miss a lot of event here. -ErrorActionCommPropertyUserowneridNotDefined=User's owner is required -ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Event Type dictionary -CheckVersionFail=Version check fail -ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it -ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. diff --git a/htdocs/langs/ar_IQ/eventorganization.lang b/htdocs/langs/ar_IQ/eventorganization.lang deleted file mode 100644 index 67a242e640a..00000000000 --- a/htdocs/langs/ar_IQ/eventorganization.lang +++ /dev/null @@ -1,149 +0,0 @@ -# Copyright (C) 2021 Florian Henry -# Copyright (C) 2021 Dorian Vabre -# -# 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 . - -# -# Generic -# -ModuleEventOrganizationName = Event Organization -EventOrganizationDescription = Event Organization through Module Project -EventOrganizationDescriptionLong= Manage Event organization for conference, attendees, speaker, and attendees, with public subcription page -# -# Menu -# -EventOrganizationMenuLeft = Organized events -EventOrganizationConferenceOrBoothMenuLeft = Conference Or Booth - -# -# Admin page -# -EventOrganizationSetup = Event Organization setup -Settings = Settings -EventOrganizationSetupPage = Event Organization setup page -EVENTORGANIZATION_TASK_LABEL = Label of tasks to create automatically when project is validated -EVENTORGANIZATION_TASK_LABELTooltip = When you validate an organized event, some tasks can be automatically created in the project

    For example:
    Send Call for Conference
    Send Call for Booth
    Receive call for conferences
    Receive call for Booth
    Open subscriptions to events for attendees
    Send remind of event to speakers
    Send remind of event to Booth hoster
    Send remind of event to attendees -EVENTORGANIZATION_CATEG_THIRDPARTY_CONF = Category to add to third-parties automatically created when someone suggests a conference -EVENTORGANIZATION_CATEG_THIRDPARTY_BOOTH = Category to add to third-parties automatically created when they suggests a booth -EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_CONF = Template of email to send after receiving a suggestion of a conference. -EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH = Template of email to send after receiving a suggestion of a booth. -EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_BOOTH = Template of email to send after a subscription to a booth has been paid. -EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT = Template of email to send after a subscription to an event has been paid. -EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER = Template of email of massaction to attendes -EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES = Template of email of massaction to speakers -EVENTORGANIZATION_FILTERATTENDEES_CAT = Filter thirdpartie's select list in attendees creation card/form with category -EVENTORGANIZATION_FILTERATTENDEES_TYPE = Filter thirdpartie's select list in attendees creation card/form with customer type - -# -# Object -# -EventOrganizationConfOrBooth= Conference Or Booth -ManageOrganizeEvent = Manage event organisation -ConferenceOrBooth = Conference Or Booth -ConferenceOrBoothTab = Conference Or Booth -AmountOfSubscriptionPaid = Amount of subscription paid -DateSubscription = Date of subscription -ConferenceOrBoothAttendee = Conference Or Booth Attendee - -# -# Template Mail -# -YourOrganizationEventConfRequestWasReceived = Your request for conference was received -YourOrganizationEventBoothRequestWasReceived = Your request for booth was received -EventOrganizationEmailAskConf = Request for conference -EventOrganizationEmailAskBooth = Request for booth -EventOrganizationEmailSubsBooth = Subscription for booth -EventOrganizationEmailSubsEvent = Subscription for an event -EventOrganizationMassEmailAttendees = Communication to attendees -EventOrganizationMassEmailSpeakers = Communication to speakers - -# -# Event -# -AllowUnknownPeopleSuggestConf=Allow unknown people to suggest conferences -AllowUnknownPeopleSuggestConfHelp=Allow unknown people to suggest conferences -AllowUnknownPeopleSuggestBooth=Allow unknown people to suggest booth -AllowUnknownPeopleSuggestBoothHelp=Allow unknown people to suggest booth -PriceOfRegistration=Price of registration -PriceOfRegistrationHelp=Price of registration -PriceOfBooth=Subscription price to stand a booth -PriceOfBoothHelp=Subscription price to stand a booth -EventOrganizationICSLink=Link ICS for events -ConferenceOrBoothInformation=Conference Or Booth informations -Attendees = Attendees -DownloadICSLink = Download ICS link -EVENTORGANIZATION_SECUREKEY = Secure Key of the public registration link to a conference -SERVICE_BOOTH_LOCATION = Service used for the invoice row about a booth location -SERVICE_CONFERENCE_ATTENDEE_SUBSCRIPTION = Service used for the invoice row about an attendee subscription to a conference -NbVotes=Number of votes -# -# Status -# -EvntOrgDraft = Draft -EvntOrgSuggested = Suggested -EvntOrgConfirmed = Confirmed -EvntOrgNotQualified = Not Qualified -EvntOrgDone = Done -EvntOrgCancelled = Cancelled -# -# Public page -# -SuggestForm = Suggestion page -RegisterPage = Page for conferences or booth -EvntOrgRegistrationHelpMessage = Here, you can vote for an event, or suggest a new conference or booth for the project -EvntOrgRegistrationConfHelpMessage = Here, you can suggest a new conference for the project -EvntOrgRegistrationBoothHelpMessage = Here, you can suggest a new booth for the project -ListOfSuggestedConferences = List of suggested conferences -ListOfSuggestedBooths = List of suggested booths -SuggestConference = Suggest a new conference -SuggestBooth = Suggest a booth -ViewAndVote = View and vote for suggested events -PublicAttendeeSubscriptionPage = Public link of registration to a conference -MissingOrBadSecureKey = The security key is invalid or missing -EvntOrgWelcomeMessage = This form allows you to register as a new participant to the conference : '%s' -EvntOrgDuration = This conference starts on %s and ends on %s. -ConferenceAttendeeFee = Conference attendee fee for the event : '%s' occurring from %s to %s. -BoothLocationFee = Booth location for the event : '%s' occurring from %s to %s -EventType = Event type -LabelOfBooth=Booth label -LabelOfconference=Conference label -ConferenceIsNotConfirmed=Subcription not available, conference is not confirmed yet -DateMustBeBeforeThan=%s must be before %s -DateMustBeAfterThan=%s must be after %s - -# -# Vote page -# -EvntOrgRegistrationWelcomeMessage = Welcome on the conference or booth suggestion page. -EvntOrgRegistrationConfWelcomeMessage = Welcome on the conference suggestion page. -EvntOrgRegistrationBoothWelcomeMessage = Welcome on the booth suggestion page. -EvntOrgVoteHelpMessage = Here, you can view and vote for the suggested events for the project -VoteOk = Your vote has been accepted. -AlreadyVoted = You have already voted for this event. -VoteError = An error has occurred during the vote, please try again. - -# -# SubscriptionOk page -# -SubscriptionOk = Your subscription to this conference has been validated -# -# Subscription validation mail -# -ConfAttendeeSubscriptionConfirmation = Confirmation of your subscription to a conference -# -# Payment page -# -Attendee = Attendee -PaymentConferenceAttendee = Conference attendee payment -PaymentBoothLocation = Booth location payment diff --git a/htdocs/langs/ar_IQ/exports.lang b/htdocs/langs/ar_IQ/exports.lang index cb652229825..4b7a62067ac 100644 --- a/htdocs/langs/ar_IQ/exports.lang +++ b/htdocs/langs/ar_IQ/exports.lang @@ -1,137 +1,2 @@ # Dolibarr language file - Source file is en_US - exports -ExportsArea=Exports -ImportArea=Import -NewExport=New Export -NewImport=New Import -ExportableDatas=Exportable dataset -ImportableDatas=Importable dataset -SelectExportDataSet=Choose dataset you want to export... -SelectImportDataSet=Choose dataset you want to import... -SelectExportFields=Choose the fields you want to export, or select a predefined export profile -SelectImportFields=Choose the source file fields you want to import and their target field in database by moving them up and down with anchor %s, or select a predefined import profile: -NotImportedFields=Fields of source file not imported -SaveExportModel=Save your selections as an export profile/template (for reuse). -SaveImportModel=Save this import profile (for reuse) ... -ExportModelName=Export profile name -ExportModelSaved=Export profile saved as %s. -ExportableFields=Exportable fields -ExportedFields=Exported fields -ImportModelName=Import profile name -ImportModelSaved=Import profile saved as %s. -DatasetToExport=Dataset to export -DatasetToImport=Import file into dataset -ChooseFieldsOrdersAndTitle=Choose fields order... -FieldsTitle=Fields title -FieldTitle=Field title -NowClickToGenerateToBuildExportFile=Now, select the file format in the combo box and click on "Generate" to build the export file... -AvailableFormats=Available Formats -LibraryShort=Library -ExportCsvSeparator=Csv caracter separator -ImportCsvSeparator=Csv caracter separator -Step=Step -FormatedImport=Import Assistant -FormatedImportDesc1=This module allows you to update existing data or add new objects into the database from a file without technical knowledge, using an assistant. -FormatedImportDesc2=First step is to choose the kind of data you want to import, then the format of the source file, then the fields you want to import. -FormatedExport=Export Assistant -FormatedExportDesc1=These tools allow the export of personalized data using an assistant, to help you in the process without requiring technical knowledge. -FormatedExportDesc2=First step is to choose a predefined dataset, then which fields you want to export, and in which order. -FormatedExportDesc3=When data to export are selected, you can choose the format of the output file. -Sheet=Sheet -NoImportableData=No importable data (no module with definitions to allow data imports) -FileSuccessfullyBuilt=File generated -SQLUsedForExport=SQL Request used to extract data -LineId=Id of line -LineLabel=Label of line -LineDescription=Description of line -LineUnitPrice=Unit price of line -LineVATRate=VAT Rate of line -LineQty=Quantity for line -LineTotalHT=Amount excl. tax for line -LineTotalTTC=Amount with tax for line -LineTotalVAT=Amount of VAT for line -TypeOfLineServiceOrProduct=Type of line (0=product, 1=service) -FileWithDataToImport=File with data to import -FileToImport=Source file to import -FileMustHaveOneOfFollowingFormat=File to import must have one of following formats -DownloadEmptyExample=Download template file with field content information -StarAreMandatory=* are mandatory fields -ChooseFormatOfFileToImport=Choose the file format to use as import file format by clicking on the %s icon to select it... -ChooseFileToImport=Upload file then click on the %s icon to select file as source import file... -SourceFileFormat=Source file format -FieldsInSourceFile=Fields in source file -FieldsInTargetDatabase=Target fields in Dolibarr database (bold=mandatory) -Field=Field -NoFields=No fields -MoveField=Move field column number %s -ExampleOfImportFile=Example_of_import_file -SaveImportProfile=Save this import profile -ErrorImportDuplicateProfil=Failed to save this import profile with this name. An existing profile already exists with this name. -TablesTarget=Targeted tables -FieldsTarget=Targeted fields -FieldTarget=Targeted field -FieldSource=Source field -NbOfSourceLines=Number of lines in source file -NowClickToTestTheImport=Check that the file format (field and string delimiters) of your file matches the options shown and that you have omitted the header line, or these will be flagged as errors in the following simulation.
    Click on the "%s" button to run a check of the file structure/contents and simulate the import process.
    No data will be changed in your database. -RunSimulateImportFile=Run Import Simulation -FieldNeedSource=This field requires data from the source file -SomeMandatoryFieldHaveNoSource=Some mandatory fields have no source from data file -InformationOnSourceFile=Information on source file -InformationOnTargetTables=Information on target fields -SelectAtLeastOneField=Switch at least one source field in the column of fields to export -SelectFormat=Choose this import file format -RunImportFile=Import Data -NowClickToRunTheImport=Check the results of the import simulation. Correct any errors and re-test.
    When the simulation reports no errors you may proceed to import the data into the database. -DataLoadedWithId=The imported data will have an additional field in each database table with this import id: %s, to allow it to be searchable in the case of investigating a problem related to this import. -ErrorMissingMandatoryValue=Mandatory data is empty in the source file for field %s. -TooMuchErrors=There are still %s other source lines with errors but output has been limited. -TooMuchWarnings=There are still %s other source lines with warnings but output has been limited. -EmptyLine=Empty line (will be discarded) -CorrectErrorBeforeRunningImport=You must correct all errors before running the definitive import. -FileWasImported=File was imported with number %s. -YouCanUseImportIdToFindRecord=You can find all the imported records in your database by filtering on field import_key='%s'. -NbOfLinesOK=Number of lines with no errors and no warnings: %s. -NbOfLinesImported=Number of lines successfully imported: %s. -DataComeFromNoWhere=Value to insert comes from nowhere in source file. -DataComeFromFileFieldNb=Value to insert comes from field number %s in source file. -DataComeFromIdFoundFromRef=Value that comes from field number %s of source file will be used to find the id of the parent object to use (so the object %s that has the ref. from source file must exist in the database). -DataComeFromIdFoundFromCodeId=Code that comes from field number %s of source file will be used to find the id of the parent object to use (so the code from source file must exist in the dictionary %s). Note that if you know the id, you can also use it in the source file instead of the code. Import should work in both cases. -DataIsInsertedInto=Data coming from source file will be inserted into the following field: -DataIDSourceIsInsertedInto=The id of parent object was found using the data in the source file, will be inserted into the following field: DataCodeIDSourceIsInsertedInto=The id of parent line found from code, will be inserted into following field: -SourceRequired=Data value is mandatory -SourceExample=Example of possible data value -ExampleAnyRefFoundIntoElement=Any ref found for element %s -ExampleAnyCodeOrIdFoundIntoDictionary=Any code (or id) found into dictionary %s -CSVFormatDesc=Comma Separated Value file format (.csv).
    This is a text file format where fields are separated by a separator [ %s ]. If separator is found inside a field content, field is rounded by round character [ %s ]. Escape character to escape round character is [ %s ]. -Excel95FormatDesc=Excel file format (.xls)
    This is the native Excel 95 format (BIFF5). -Excel2007FormatDesc=Excel file format (.xlsx)
    This is the native Excel 2007 format (SpreadsheetML). -TsvFormatDesc=Tab Separated Value file format (.tsv)
    This is a text file format where fields are separated by a tabulator [tab]. -ExportFieldAutomaticallyAdded=Field %s was automatically added. It will avoid you to have similar lines to be treated as duplicate record (with this field added, all lines will own their own id and will differ). -CsvOptions=CSV format options -Separator=Field Separator -Enclosure=String Delimiter -SpecialCode=Special code -ExportStringFilter=%% allows replacing one or more characters in the text -ExportDateFilter=YYYY, YYYYMM, YYYYMMDD: filters by one year/month/day
    YYYY+YYYY, YYYYMM+YYYYMM, YYYYMMDD+YYYYMMDD: filters over a range of years/months/days
    > YYYY, > YYYYMM, > YYYYMMDD: filters on all following years/months/days
    < YYYY, < YYYYMM, < YYYYMMDD: filters on all previous years/months/days -ExportNumericFilter=NNNNN filters by one value
    NNNNN+NNNNN filters over a range of values
    < NNNNN filters by lower values
    > NNNNN filters by higher values -ImportFromLine=Import starting from line number -EndAtLineNb=End at line number -ImportFromToLine=Limit range (From - To). Eg. to omit header line(s). -SetThisValueTo2ToExcludeFirstLine=For example, set this value to 3 to exclude the 2 first lines.
    If the header lines are NOT omitted, this will result in multiple errors in the Import Simulation. -KeepEmptyToGoToEndOfFile=Keep this field empty to process all lines to the end of the file. -SelectPrimaryColumnsForUpdateAttempt=Select column(s) to use as primary key for an UPDATE import -UpdateNotYetSupportedForThisImport=Update is not supported for this type of import (only insert) -NoUpdateAttempt=No update attempt was performed, only insert -ImportDataset_user_1=Users (employees or not) and properties -ComputedField=Computed field -## filters -SelectFilterFields=If you want to filter on some values, just input values here. -FilteredFields=Filtered fields -FilteredFieldsValues=Value for filter -FormatControlRule=Format control rule -## imports updates -KeysToUseForUpdates=Key (column) to use for updating existing data -NbInsert=Number of inserted lines: %s -NbUpdate=Number of updated lines: %s -MultipleRecordFoundWithTheseFilters=Multiple records have been found with these filters: %s -StocksWithBatch=Stocks and location (warehouse) of products with batch/serial number diff --git a/htdocs/langs/ar_IQ/externalsite.lang b/htdocs/langs/ar_IQ/externalsite.lang deleted file mode 100644 index 452100c65b3..00000000000 --- a/htdocs/langs/ar_IQ/externalsite.lang +++ /dev/null @@ -1,5 +0,0 @@ -# Dolibarr language file - Source file is en_US - externalsite -ExternalSiteSetup=Setup link to external website -ExternalSiteURL=External Site URL of HTML iframe content -ExternalSiteModuleNotComplete=Module ExternalSite was not configured properly. -ExampleMyMenuEntry=My menu entry diff --git a/htdocs/langs/ar_IQ/ftp.lang b/htdocs/langs/ar_IQ/ftp.lang deleted file mode 100644 index 254a2a698ce..00000000000 --- a/htdocs/langs/ar_IQ/ftp.lang +++ /dev/null @@ -1,14 +0,0 @@ -# Dolibarr language file - Source file is en_US - ftp -FTPClientSetup=FTP or SFTP Client module setup -NewFTPClient=New FTP/FTPS connection setup -FTPArea=FTP/FTPS Area -FTPAreaDesc=This screen shows a view of an FTP et SFTP server. -SetupOfFTPClientModuleNotComplete=The setup of the FTP or SFTP client module seems to be incomplete -FTPFeatureNotSupportedByYourPHP=Your PHP does not support FTP or SFTP functions -FailedToConnectToFTPServer=Failed to connect to server (server %s, port %s) -FailedToConnectToFTPServerWithCredentials=Failed to login to server with defined login/password -FTPFailedToRemoveFile=Failed to remove file %s. -FTPFailedToRemoveDir=Failed to remove directory %s: check permissions and that the directory is empty. -FTPPassiveMode=Passive mode -ChooseAFTPEntryIntoMenu=Choose a FTP/SFTP site from the menu... -FailedToGetFile=Failed to get files %s diff --git a/htdocs/langs/ar_IQ/help.lang b/htdocs/langs/ar_IQ/help.lang deleted file mode 100644 index 048de16d3c0..00000000000 --- a/htdocs/langs/ar_IQ/help.lang +++ /dev/null @@ -1,23 +0,0 @@ -# Dolibarr language file - Source file is en_US - help -CommunitySupport=Forum/Wiki support -EMailSupport=Emails support -RemoteControlSupport=Online real-time / remote support -OtherSupport=Other support -ToSeeListOfAvailableRessources=To contact/see available resources: -HelpCenter=Help Center -DolibarrHelpCenter=Dolibarr Help and Support Center -ToGoBackToDolibarr=Otherwise, click here to continue to use Dolibarr. -TypeOfSupport=Type of support -TypeSupportCommunauty=Community (free) -TypeSupportCommercial=Commercial -TypeOfHelp=Type -NeedHelpCenter=Need help or support? -Efficiency=Efficiency -TypeHelpOnly=Help only -TypeHelpDev=Help+Development -TypeHelpDevForm=Help+Development+Training -BackToHelpCenter=Otherwise, go back to Help center home page. -LinkToGoldMember=You can call one of the trainers preselected by Dolibarr for your language (%s) by clicking their Widget (status and maximum price are automatically updated): -PossibleLanguages=Supported languages -SubscribeToFoundation=Help the Dolibarr project, subscribe to the foundation -SeeOfficalSupport=For official Dolibarr support in your language:
    %s diff --git a/htdocs/langs/ar_IQ/holiday.lang b/htdocs/langs/ar_IQ/holiday.lang deleted file mode 100644 index 0527f4c0788..00000000000 --- a/htdocs/langs/ar_IQ/holiday.lang +++ /dev/null @@ -1,136 +0,0 @@ -# Dolibarr language file - Source file is en_US - holiday -HRM=HRM -Holidays=Leave -CPTitreMenu=Leave -MenuReportMonth=Monthly statement -MenuAddCP=New leave request -NotActiveModCP=You must enable the module Leave to view this page. -AddCP=Make a leave request -DateDebCP=Start date -DateFinCP=End date -DraftCP=Draft -ToReviewCP=Awaiting approval -ApprovedCP=Approved -CancelCP=Canceled -RefuseCP=Refused -ValidatorCP=Approver -ListeCP=List of leave -Leave=Leave request -LeaveId=Leave ID -ReviewedByCP=Will be approved by -UserID=User ID -UserForApprovalID=User for approval ID -UserForApprovalFirstname=First name of approval user -UserForApprovalLastname=Last name of approval user -UserForApprovalLogin=Login of approval user -DescCP=Description -SendRequestCP=Create leave request -DelayToRequestCP=Leave requests must be made at least %s day(s) before them. -MenuConfCP=Balance of leave -SoldeCPUser=Leave balance is %s days. -ErrorEndDateCP=You must select an end date greater than the start date. -ErrorSQLCreateCP=An SQL error occurred during the creation: -ErrorIDFicheCP=An error has occurred, the leave request does not exist. -ReturnCP=Return to previous page -ErrorUserViewCP=You are not authorized to read this leave request. -InfosWorkflowCP=Information Workflow -RequestByCP=Requested by -TitreRequestCP=Leave request -TypeOfLeaveId=Type of leave ID -TypeOfLeaveCode=Type of leave code -TypeOfLeaveLabel=Type of leave label -NbUseDaysCP=Number of days of leave used -NbUseDaysCPHelp=The calculation takes into account the non-working days and the holidays defined in the dictionary. -NbUseDaysCPShort=Days of leave -NbUseDaysCPShortInMonth=Days of leave in month -DayIsANonWorkingDay=%s is a non-working day -DateStartInMonth=Start date in month -DateEndInMonth=End date in month -EditCP=Edit -DeleteCP=Delete -ActionRefuseCP=Refuse -ActionCancelCP=Cancel -StatutCP=Status -TitleDeleteCP=Delete the leave request -ConfirmDeleteCP=Confirm the deletion of this leave request? -ErrorCantDeleteCP=Error you don't have the right to delete this leave request. -CantCreateCP=You don't have the right to make leave requests. -InvalidValidatorCP=You must choose the approver for your leave request. -NoDateDebut=You must select a start date. -NoDateFin=You must select an end date. -ErrorDureeCP=Your leave request does not contain working day. -TitleValidCP=Approve the leave request -ConfirmValidCP=Are you sure you want to approve the leave request? -DateValidCP=Date approved -TitleToValidCP=Send leave request -ConfirmToValidCP=Are you sure you want to send the leave request? -TitleRefuseCP=Refuse the leave request -ConfirmRefuseCP=Are you sure you want to refuse the leave request? -NoMotifRefuseCP=You must choose a reason for refusing the request. -TitleCancelCP=Cancel the leave request -ConfirmCancelCP=Are you sure you want to cancel the leave request? -DetailRefusCP=Reason for refusal -DateRefusCP=Date of refusal -DateCancelCP=Date of cancellation -DefineEventUserCP=Assign an exceptional leave for a user -addEventToUserCP=Assign leave -NotTheAssignedApprover=You are not the assigned approver -MotifCP=Reason -UserCP=User -ErrorAddEventToUserCP=An error occurred while adding the exceptional leave. -AddEventToUserOkCP=The addition of the exceptional leave has been completed. -MenuLogCP=View change logs -LogCP=Log of all updates made to "Balance of Leave" -ActionByCP=Updated by -UserUpdateCP=Updated for -PrevSoldeCP=Previous Balance -NewSoldeCP=New Balance -alreadyCPexist=A leave request has already been done on this period. -FirstDayOfHoliday=Beginning day of leave request -LastDayOfHoliday=Ending day of leave request -BoxTitleLastLeaveRequests=Latest %s modified leave requests -HolidaysMonthlyUpdate=Monthly update -ManualUpdate=Manual update -HolidaysCancelation=Leave request cancelation -EmployeeLastname=Employee last name -EmployeeFirstname=Employee first name -TypeWasDisabledOrRemoved=Leave type (id %s) was disabled or removed -LastHolidays=Latest %s leave requests -AllHolidays=All leave requests -HalfDay=Half day -NotTheAssignedApprover=You are not the assigned approver -LEAVE_PAID=Paid vacation -LEAVE_SICK=Sick leave -LEAVE_OTHER=Other leave -LEAVE_PAID_FR=Paid vacation -## Configuration du Module ## -LastUpdateCP=Last automatic update of leave allocation -MonthOfLastMonthlyUpdate=Month of last automatic update of leave allocation -UpdateConfCPOK=Updated successfully. -Module27130Name= Management of leave requests -Module27130Desc= Management of leave requests -ErrorMailNotSend=An error occurred while sending email: -NoticePeriod=Notice period -#Messages -HolidaysToValidate=Validate leave requests -HolidaysToValidateBody=Below is a leave request to validate -HolidaysToValidateDelay=This leave request will take place within a period of less than %s days. -HolidaysToValidateAlertSolde=The user who made this leave request does not have enough available days. -HolidaysValidated=Validated leave requests -HolidaysValidatedBody=Your leave request for %s to %s has been validated. -HolidaysRefused=Request denied -HolidaysRefusedBody=Your leave request for %s to %s has been denied for the following reason: -HolidaysCanceled=Canceled leaved request -HolidaysCanceledBody=Your leave request for %s to %s has been canceled. -FollowedByACounter=1: This type of leave need to be followed by a counter. Counter is incremented manually or automatically and when a leave request is validated, counter is decremented.
    0: Not followed by a counter. -NoLeaveWithCounterDefined=There is no leave types defined that need to be followed by a counter -GoIntoDictionaryHolidayTypes=Go into Home - Setup - Dictionaries - Type of leave to setup the different types of leaves. -HolidaySetup=Setup of module Leave -HolidaysNumberingModules=Numbering models for leave requests -TemplatePDFHolidays=Template for leave requests PDF -FreeLegalTextOnHolidays=Free text on PDF -WatermarkOnDraftHolidayCards=Watermarks on draft leave requests -HolidaysToApprove=Holidays to approve -NobodyHasPermissionToValidateHolidays=Nobody has permission to validate holidays -HolidayBalanceMonthlyUpdate=Monthly update of holiday balance -XIsAUsualNonWorkingDay=%s is usualy a NON working day diff --git a/htdocs/langs/ar_IQ/hrm.lang b/htdocs/langs/ar_IQ/hrm.lang deleted file mode 100644 index da098e10bdb..00000000000 --- a/htdocs/langs/ar_IQ/hrm.lang +++ /dev/null @@ -1,19 +0,0 @@ -# Dolibarr language file - en_US - hrm -# Admin -HRM_EMAIL_EXTERNAL_SERVICE=Email to prevent HRM external service -Establishments=Establishments -Establishment=Establishment -NewEstablishment=New establishment -DeleteEstablishment=Delete establishment -ConfirmDeleteEstablishment=Are you sure you wish to delete this establishment? -OpenEtablishment=Open establishment -CloseEtablishment=Close establishment -# Dictionary -DictionaryPublicHolidays=Leave - Public holidays -DictionaryDepartment=HRM - Department list -DictionaryFunction=HRM - Job positions -# Module -Employees=Employees -Employee=Employee -NewEmployee=New employee -ListOfEmployees=List of employees diff --git a/htdocs/langs/ar_IQ/install.lang b/htdocs/langs/ar_IQ/install.lang deleted file mode 100644 index c1ffee936d7..00000000000 --- a/htdocs/langs/ar_IQ/install.lang +++ /dev/null @@ -1,218 +0,0 @@ -# Dolibarr language file - Source file is en_US - install -InstallEasy=Just follow the instructions step by step. -MiscellaneousChecks=Prerequisites check -ConfFileExists=Configuration file %s exists. -ConfFileDoesNotExistsAndCouldNotBeCreated=Configuration file %s does not exist and could not be created! -ConfFileCouldBeCreated=Configuration file %s could be created. -ConfFileIsNotWritable=Configuration file %s is not writable. Check permissions. For first install, your web server must be able to write into this file during configuration process ("chmod 666" for example on a Unix like OS). -ConfFileIsWritable=Configuration file %s is writable. -ConfFileMustBeAFileNotADir=Configuration file %s must be a file, not a directory. -ConfFileReload=Reloading parameters from configuration file. -PHPSupportPOSTGETOk=This PHP supports variables POST and GET. -PHPSupportPOSTGETKo=It's possible your PHP setup does not support variables POST and/or GET. Check the parameter variables_order in php.ini. -PHPSupportSessions=This PHP supports sessions. -PHPSupport=This PHP supports %s functions. -PHPMemoryOK=Your PHP max session memory is set to %s. This should be enough. -PHPMemoryTooLow=Your PHP max session memory is set to %s bytes. This is too low. Change your php.ini to set memory_limit parameter to at least %s bytes. -Recheck=Click here for a more detailed test -ErrorPHPDoesNotSupportSessions=Your PHP installation does not support sessions. This feature is required to allow Dolibarr to work. Check your PHP setup and permissions of the sessions directory. -ErrorPHPDoesNotSupportGD=Your PHP installation does not support GD graphical functions. No graphs will be available. -ErrorPHPDoesNotSupportCurl=Your PHP installation does not support Curl. -ErrorPHPDoesNotSupportCalendar=Your PHP installation does not support php calendar extensions. -ErrorPHPDoesNotSupportUTF8=Your PHP installation does not support UTF8 functions. Dolibarr cannot work correctly. Resolve this before installing Dolibarr. -ErrorPHPDoesNotSupportIntl=Your PHP installation does not support Intl functions. -ErrorPHPDoesNotSupportxDebug=Your PHP installation does not support extend debug functions. -ErrorPHPDoesNotSupport=Your PHP installation does not support %s functions. -ErrorDirDoesNotExists=Directory %s does not exist. -ErrorGoBackAndCorrectParameters=Go back and check/correct the parameters. -ErrorWrongValueForParameter=You may have typed a wrong value for parameter '%s'. -ErrorFailedToCreateDatabase=Failed to create database '%s'. -ErrorFailedToConnectToDatabase=Failed to connect to database '%s'. -ErrorDatabaseVersionTooLow=Database version (%s) too old. Version %s or higher is required. -ErrorPHPVersionTooLow=PHP version too old. Version %s is required. -ErrorConnectedButDatabaseNotFound=Connection to server successful but database '%s' not found. -ErrorDatabaseAlreadyExists=Database '%s' already exists. -IfDatabaseNotExistsGoBackAndUncheckCreate=If the database does not exist, go back and check option "Create database". -IfDatabaseExistsGoBackAndCheckCreate=If database already exists, go back and uncheck "Create database" option. -WarningBrowserTooOld=Version of browser is too old. Upgrading your browser to a recent version of Firefox, Chrome or Opera is highly recommended. -PHPVersion=PHP Version -License=Using license -ConfigurationFile=Configuration file -WebPagesDirectory=Directory where web pages are stored -DocumentsDirectory=Directory to store uploaded and generated documents -URLRoot=URL Root -ForceHttps=Force secure connections (https) -CheckToForceHttps=Check this option to force secure connections (https).
    This requires that the web server is configured with an SSL certificate. -DolibarrDatabase=Dolibarr Database -DatabaseType=Database type -DriverType=Driver type -Server=Server -ServerAddressDescription=Name or ip address for the database server. Usually 'localhost' when the database server is hosted on the same server as the web server. -ServerPortDescription=Database server port. Keep empty if unknown. -DatabaseServer=Database server -DatabaseName=Database name -DatabasePrefix=Database table prefix -DatabasePrefixDescription=Database table prefix. If empty, defaults to llx_. -AdminLogin=User account for the Dolibarr database owner. -PasswordAgain=Retype password confirmation -AdminPassword=Password for Dolibarr database owner. -CreateDatabase=Create database -CreateUser=Create user account or grant user account permission on the Dolibarr database -DatabaseSuperUserAccess=Database server - Superuser access -CheckToCreateDatabase=Check the box if the database does not exist yet and so must be created.
    In this case, you must also fill in the user name and password for the superuser account at the bottom of this page. -CheckToCreateUser=Check the box if:
    the database user account does not yet exist and so must be created, or
    if the user account exists but the database does not exist and permissions must be granted.
    In this case, you must enter the user account and password and also the superuser account name and password at the bottom of this page. If this box is unchecked, database owner and password must already exist. -DatabaseRootLoginDescription=Superuser account name (to create new databases or new users), mandatory if the database or its owner does not already exist. -KeepEmptyIfNoPassword=Leave empty if superuser has no password (NOT recommended) -SaveConfigurationFile=Saving parameters to -ServerConnection=Server connection -DatabaseCreation=Database creation -CreateDatabaseObjects=Database objects creation -ReferenceDataLoading=Reference data loading -TablesAndPrimaryKeysCreation=Tables and Primary keys creation -CreateTableAndPrimaryKey=Create table %s -CreateOtherKeysForTable=Create foreign keys and indexes for table %s -OtherKeysCreation=Foreign keys and indexes creation -FunctionsCreation=Functions creation -AdminAccountCreation=Administrator login creation -PleaseTypePassword=Please type a password, empty passwords are not allowed! -PleaseTypeALogin=Please type a login! -PasswordsMismatch=Passwords differs, please try again! -SetupEnd=End of setup -SystemIsInstalled=This installation is complete. -SystemIsUpgraded=Dolibarr has been upgraded successfully. -YouNeedToPersonalizeSetup=You need to configure Dolibarr to suit your needs (appearance, features, ...). To do this, please follow the link below: -AdminLoginCreatedSuccessfuly=Dolibarr administrator login '%s' created successfully. -GoToDolibarr=Go to Dolibarr -GoToSetupArea=Go to Dolibarr (setup area) -MigrationNotFinished=The database version is not completely up to date: run the upgrade process again. -GoToUpgradePage=Go to upgrade page again -WithNoSlashAtTheEnd=Without the slash "/" at the end -DirectoryRecommendation=IMPORTANT: You must use a directory that is outside of the web pages (so do not use a subdirectory of previous parameter). -LoginAlreadyExists=Already exists -DolibarrAdminLogin=Dolibarr admin login -AdminLoginAlreadyExists=Dolibarr administrator account '%s' already exists. Go back if you want to create another one. -FailedToCreateAdminLogin=Failed to create Dolibarr administrator account. -WarningRemoveInstallDir=Warning, for security reasons, once the install or upgrade is complete, you should add a file called install.lock into the Dolibarr document directory in order to prevent the accidental/malicious use of the install tools again. -FunctionNotAvailableInThisPHP=Not available in this PHP -ChoosedMigrateScript=Choose migration script -DataMigration=Database migration (data) -DatabaseMigration=Database migration (structure + some data) -ProcessMigrateScript=Script processing -ChooseYourSetupMode=Choose your setup mode and click "Start"... -FreshInstall=Fresh install -FreshInstallDesc=Use this mode if this is your first install. If not, this mode can repair a incomplete previous install. If you want to upgrade your version, choose "Upgrade" mode. -Upgrade=Upgrade -UpgradeDesc=Use this mode if you have replaced old Dolibarr files with files from a newer version. This will upgrade your database and data. -Start=Start -InstallNotAllowed=Setup not allowed by conf.php permissions -YouMustCreateWithPermission=You must create file %s and set write permissions on it for the web server during install process. -CorrectProblemAndReloadPage=Please fix the problem and press F5 to reload the page. -AlreadyDone=Already migrated -DatabaseVersion=Database version -ServerVersion=Database server version -YouMustCreateItAndAllowServerToWrite=You must create this directory and allow for the web server to write into it. -DBSortingCollation=Character sorting order -YouAskDatabaseCreationSoDolibarrNeedToConnect=You selected create database %s, but for this, Dolibarr needs to connect to server %s with super user %s permissions. -YouAskLoginCreationSoDolibarrNeedToConnect=You selected create database user %s, but for this, Dolibarr needs to connect to server %s with super user %s permissions. -BecauseConnectionFailedParametersMayBeWrong=The database connection failed: the host or super user parameters must be wrong. -OrphelinsPaymentsDetectedByMethod=Orphans payment detected by method %s -RemoveItManuallyAndPressF5ToContinue=Remove it manually and press F5 to continue. -FieldRenamed=Field renamed -IfLoginDoesNotExistsCheckCreateUser=If the user does not exist yet, you must check option "Create user" -ErrorConnection=Server "%s", database name "%s", login "%s", or database password may be wrong or the PHP client version may be too old compared to the database version. -InstallChoiceRecommanded=Recommended choice to install version %s from your current version %s -InstallChoiceSuggested=Install choice suggested by installer. -MigrateIsDoneStepByStep=The targeted version (%s) has a gap of several versions. The install wizard will come back to suggest a further migration once this one is complete. -CheckThatDatabasenameIsCorrect=Check that the database name "%s" is correct. -IfAlreadyExistsCheckOption=If this name is correct and that database does not exist yet, you must check option "Create database". -OpenBaseDir=PHP openbasedir parameter -YouAskToCreateDatabaseSoRootRequired=You checked the box "Create database". For this, you need to provide the login/password of superuser (bottom of form). -YouAskToCreateDatabaseUserSoRootRequired=You checked the box "Create database owner". For this, you need to provide the login/password of superuser (bottom of form). -NextStepMightLastALongTime=The current step may take several minutes. Please wait until the next screen is shown completely before continuing. -MigrationCustomerOrderShipping=Migrate shipping for sales orders storage -MigrationShippingDelivery=Upgrade storage of shipping -MigrationShippingDelivery2=Upgrade storage of shipping 2 -MigrationFinished=Migration finished -LastStepDesc=Last step: Define here the login and password you wish to use to connect to Dolibarr. Do not lose this as it is the master account to administer all other/additional user accounts. -ActivateModule=Activate module %s -ShowEditTechnicalParameters=Click here to show/edit advanced parameters (expert mode) -WarningUpgrade=Warning:\nDid you run a database backup first?\nThis is highly recommended. Loss of data (due to for example bugs in mysql version 5.5.40/41/42/43) may be possible during this process, so it is essential to take a complete dump of your database before starting any migration.\n\nClick OK to start migration process... -ErrorDatabaseVersionForbiddenForMigration=Your database version is %s. It has a critical bug, making data loss possible if you make structural changes in your database, such as is required by the migration process. For his reason, migration will not be allowed until you upgrade your database to a layer (patched) version (list of known buggy versions: %s) -KeepDefaultValuesWamp=You used the Dolibarr setup wizard from DoliWamp, so values proposed here are already optimized. Change them only if you know what you are doing. -KeepDefaultValuesDeb=You used the Dolibarr setup wizard from a Linux package (Ubuntu, Debian, Fedora...), so the values proposed here are already optimized. Only the password of the database owner to create must be entered. Change other parameters only if you know what you are doing. -KeepDefaultValuesMamp=You used the Dolibarr setup wizard from DoliMamp, so the values proposed here are already optimized. Change them only if you know what you are doing. -KeepDefaultValuesProxmox=You used the Dolibarr setup wizard from a Proxmox virtual appliance, so the values proposed here are already optimized. Change them only if you know what you are doing. -UpgradeExternalModule=Run dedicated upgrade process of external module -SetAtLeastOneOptionAsUrlParameter=Set at least one option as a parameter in URL. For example: '...repair.php?standard=confirmed' -NothingToDelete=Nothing to clean/delete -NothingToDo=Nothing to do -######### -# upgrade -MigrationFixData=Fix for denormalized data -MigrationOrder=Data migration for customer's orders -MigrationSupplierOrder=Data migration for vendor's orders -MigrationProposal=Data migration for commercial proposals -MigrationInvoice=Data migration for customer's invoices -MigrationContract=Data migration for contracts -MigrationSuccessfullUpdate=Upgrade successful -MigrationUpdateFailed=Failed upgrade process -MigrationRelationshipTables=Data migration for relationship tables (%s) -MigrationPaymentsUpdate=Payment data correction -MigrationPaymentsNumberToUpdate=%s payment(s) to update -MigrationProcessPaymentUpdate=Update payment(s) %s -MigrationPaymentsNothingToUpdate=No more things to do -MigrationPaymentsNothingUpdatable=No more payments that can be corrected -MigrationContractsUpdate=Contract data correction -MigrationContractsNumberToUpdate=%s contract(s) to update -MigrationContractsLineCreation=Create contract line for contract ref %s -MigrationContractsNothingToUpdate=No more things to do -MigrationContractsFieldDontExist=Field fk_facture does not exist anymore. Nothing to do. -MigrationContractsEmptyDatesUpdate=Contract empty date correction -MigrationContractsEmptyDatesUpdateSuccess=Contract empty date correction done successfully -MigrationContractsEmptyDatesNothingToUpdate=No contract empty date to correct -MigrationContractsEmptyCreationDatesNothingToUpdate=No contract creation date to correct -MigrationContractsInvalidDatesUpdate=Bad value date contract correction -MigrationContractsInvalidDateFix=Correct contract %s (Contract date=%s, Starting service date min=%s) -MigrationContractsInvalidDatesNumber=%s contracts modified -MigrationContractsInvalidDatesNothingToUpdate=No date with bad value to correct -MigrationContractsIncoherentCreationDateUpdate=Bad value contract creation date correction -MigrationContractsIncoherentCreationDateUpdateSuccess=Bad value contract creation date correction done successfully -MigrationContractsIncoherentCreationDateNothingToUpdate=No bad value for contract creation date to correct -MigrationReopeningContracts=Open contract closed by error -MigrationReopenThisContract=Reopen contract %s -MigrationReopenedContractsNumber=%s contracts modified -MigrationReopeningContractsNothingToUpdate=No closed contract to open -MigrationBankTransfertsUpdate=Update links between bank entry and a bank transfer -MigrationBankTransfertsNothingToUpdate=All links are up to date -MigrationShipmentOrderMatching=Sendings receipt update -MigrationDeliveryOrderMatching=Delivery receipt update -MigrationDeliveryDetail=Delivery update -MigrationStockDetail=Update stock value of products -MigrationMenusDetail=Update dynamic menus tables -MigrationDeliveryAddress=Update delivery address in shipments -MigrationProjectTaskActors=Data migration for table llx_projet_task_actors -MigrationProjectUserResp=Data migration field fk_user_resp of llx_projet to llx_element_contact -MigrationProjectTaskTime=Update time spent in seconds -MigrationActioncommElement=Update data on actions -MigrationPaymentMode=Data migration for payment type -MigrationCategorieAssociation=Migration of categories -MigrationEvents=Migration of events to add event owner into assignment table -MigrationEventsContact=Migration of events to add event contact into assignment table -MigrationRemiseEntity=Update entity field value of llx_societe_remise -MigrationRemiseExceptEntity=Update entity field value of llx_societe_remise_except -MigrationUserRightsEntity=Update entity field value of llx_user_rights -MigrationUserGroupRightsEntity=Update entity field value of llx_usergroup_rights -MigrationUserPhotoPath=Migration of photo paths for users -MigrationFieldsSocialNetworks=Migration of users fields social networks (%s) -MigrationReloadModule=Reload module %s -MigrationResetBlockedLog=Reset module BlockedLog for v7 algorithm -MigrationImportOrExportProfiles=Migration of import or export profiles (%s) -ShowNotAvailableOptions=Show unavailable options -HideNotAvailableOptions=Hide unavailable options -ErrorFoundDuringMigration=Error(s) were reported during the migration process so next step is not available. To ignore errors, you can click here, but the application or some features may not work correctly until the errors are resolved. -YouTryInstallDisabledByDirLock=The application tried to self-upgrade, but the install/upgrade pages have been disabled for security (directory renamed with .lock suffix).
    -YouTryInstallDisabledByFileLock=The application tried to self-upgrade, but the install/upgrade pages have been disabled for security (by the existence of a lock file install.lock in the dolibarr documents directory).
    -ClickHereToGoToApp=Click here to go to your application -ClickOnLinkOrRemoveManualy=If an upgrade is in progress, please wait. If not, click on the following link. If you always see this same page, you must remove/rename the file install.lock in the documents directory. -Loaded=Loaded -FunctionTest=Function test diff --git a/htdocs/langs/ar_IQ/interventions.lang b/htdocs/langs/ar_IQ/interventions.lang deleted file mode 100644 index ef5df43e546..00000000000 --- a/htdocs/langs/ar_IQ/interventions.lang +++ /dev/null @@ -1,68 +0,0 @@ -# Dolibarr language file - Source file is en_US - interventions -Intervention=Intervention -Interventions=Interventions -InterventionCard=Intervention card -NewIntervention=New intervention -AddIntervention=Create intervention -ChangeIntoRepeatableIntervention=Change to repeatable intervention -ListOfInterventions=List of interventions -ActionsOnFicheInter=Actions on intervention -LastInterventions=Latest %s interventions -AllInterventions=All interventions -CreateDraftIntervention=Create draft -InterventionContact=Intervention contact -DeleteIntervention=Delete intervention -ValidateIntervention=Validate intervention -ModifyIntervention=Modify intervention -DeleteInterventionLine=Delete intervention line -ConfirmDeleteIntervention=Are you sure you want to delete this intervention? -ConfirmValidateIntervention=Are you sure you want to validate this intervention under name %s? -ConfirmModifyIntervention=Are you sure you want to modify this intervention? -ConfirmDeleteInterventionLine=Are you sure you want to delete this intervention line? -ConfirmCloneIntervention=Are you sure you want to clone this intervention? -NameAndSignatureOfInternalContact=Name and signature of intervening: -NameAndSignatureOfExternalContact=Name and signature of customer: -DocumentModelStandard=Standard document model for interventions -InterventionCardsAndInterventionLines=Interventions and lines of interventions -InterventionClassifyBilled=Classify "Billed" -InterventionClassifyUnBilled=Classify "Unbilled" -InterventionClassifyDone=Classify "Done" -StatusInterInvoiced=Billed -SendInterventionRef=Submission of intervention %s -SendInterventionByMail=Send intervention by email -InterventionCreatedInDolibarr=Intervention %s created -InterventionValidatedInDolibarr=Intervention %s validated -InterventionModifiedInDolibarr=Intervention %s modified -InterventionClassifiedBilledInDolibarr=Intervention %s set as billed -InterventionClassifiedUnbilledInDolibarr=Intervention %s set as unbilled -InterventionSentByEMail=Intervention %s sent by email -InterventionDeletedInDolibarr=Intervention %s deleted -InterventionsArea=Interventions area -DraftFichinter=Draft interventions -LastModifiedInterventions=Latest %s modified interventions -FichinterToProcess=Interventions to process -TypeContact_fichinter_external_CUSTOMER=Following-up customer contact -PrintProductsOnFichinter=Print also lines of type "product" (not only services) on intervention card -PrintProductsOnFichinterDetails=interventions generated from orders -UseServicesDurationOnFichinter=Use services duration for interventions generated from orders -UseDurationOnFichinter=Hides the duration field for intervention records -UseDateWithoutHourOnFichinter=Hides hours and minutes off the date field for intervention records -InterventionStatistics=Statistics of interventions -NbOfinterventions=No. of intervention cards -NumberOfInterventionsByMonth=No. of intervention cards by month (date of validation) -AmountOfInteventionNotIncludedByDefault=Amount of intervention is not included by default into profit (in most cases, timesheets are used to count time spent). Add option PROJECT_INCLUDE_INTERVENTION_AMOUNT_IN_PROFIT to 1 into home-setup-other to include them. -InterId=Intervention id -InterRef=Intervention ref. -InterDateCreation=Date creation intervention -InterDuration=Duration intervention -InterStatus=Status intervention -InterNote=Note intervention -InterLine=Line of intervention -InterLineId=Line id intervention -InterLineDate=Line date intervention -InterLineDuration=Line duration intervention -InterLineDesc=Line description intervention -RepeatableIntervention=Template of intervention -ToCreateAPredefinedIntervention=To create a predefined or recurring intervention, create a common intervention and convert it into intervention template -ConfirmReopenIntervention=Are you sure you want to open back the intervention %s? -GenerateInter=Generate intervention diff --git a/htdocs/langs/ar_IQ/intracommreport.lang b/htdocs/langs/ar_IQ/intracommreport.lang deleted file mode 100644 index 93c46f112bb..00000000000 --- a/htdocs/langs/ar_IQ/intracommreport.lang +++ /dev/null @@ -1,40 +0,0 @@ -Module68000Name = Intracomm report -Module68000Desc = Intracomm report management (Support for French DEB/DES format) -IntracommReportSetup = Intracommreport module setup -IntracommReportAbout = About intracommreport - -# Setup -INTRACOMMREPORT_NUM_AGREMENT=Numéro d'agrément (délivré par le CISD de rattachement) -INTRACOMMREPORT_TYPE_ACTEUR=Type d'acteur -INTRACOMMREPORT_ROLE_ACTEUR=Rôle joué par l'acteur -INTRACOMMREPORT_NIV_OBLIGATION_INTRODUCTION=Niveau d'obligation sur les introductions -INTRACOMMREPORT_NIV_OBLIGATION_EXPEDITION=Niveau d'obligation sur les expéditions -INTRACOMMREPORT_CATEG_FRAISDEPORT=Catégorie de services de type "Frais de port" - -INTRACOMMREPORT_NUM_DECLARATION=Numéro de déclarant - -# Menu -MenuIntracommReport=Intracomm report -MenuIntracommReportNew=New declaration -MenuIntracommReportList=List - -# View -NewDeclaration=New declaration -Declaration=Declaration -AnalysisPeriod=Analysis period -TypeOfDeclaration=Type of declaration -DEB=Goods exchange declaration (DEB) -DES=Services exchange declaration (DES) - -# Export page -IntracommReportTitle=Preparation of an XML file in ProDouane format - -# List -IntracommReportList=List of generated declarations -IntracommReportNumber=Numero of declaration -IntracommReportPeriod=Period of analysis -IntracommReportTypeDeclaration=Type of declaration -IntracommReportDownload=download XML file - -# Invoice -IntracommReportTransportMode=Transport mode diff --git a/htdocs/langs/ar_IQ/knowledgemanagement.lang b/htdocs/langs/ar_IQ/knowledgemanagement.lang deleted file mode 100644 index 99425830e53..00000000000 --- a/htdocs/langs/ar_IQ/knowledgemanagement.lang +++ /dev/null @@ -1,49 +0,0 @@ -# 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 . - -# -# Generic -# - -# Module label 'ModuleKnowledgeManagementName' -ModuleKnowledgeManagementName = Knowledge Management System -# Module description 'ModuleKnowledgeManagementDesc' -ModuleKnowledgeManagementDesc=Manage a Knowledge Management (KM) or Help-Desk base - -# -# Admin page -# -KnowledgeManagementSetup = Knowledge Management System setup -Settings = Settings -KnowledgeManagementSetupPage = Knowledge Management System setup page - - -# -# About page -# -About = About -KnowledgeManagementAbout = About Knowledge Management -KnowledgeManagementAboutPage = Knowledge Management about page - -KnowledgeManagementArea = Knowledge Management -MenuKnowledgeRecord = Knowledge base -ListKnowledgeRecord = List of articles -NewKnowledgeRecord = New article -ValidateReply = Validate solution -KnowledgeRecords = Articles -KnowledgeRecord = Article -KnowledgeRecordExtraFields = Extrafields for Article -GroupOfTicket=Group of tickets -YouCanLinkArticleToATicketCategory=You can link an article to a ticket group (so the article will be suggested during qualification of new tickets) diff --git a/htdocs/langs/ar_IQ/languages.lang b/htdocs/langs/ar_IQ/languages.lang deleted file mode 100644 index 023edb64c52..00000000000 --- a/htdocs/langs/ar_IQ/languages.lang +++ /dev/null @@ -1,110 +0,0 @@ -# Dolibarr language file - Source file is en_US - languages -Language_am_ET=Ethiopian -Language_ar_AR=Arabic -Language_ar_EG=Arabic (Egypt) -Language_ar_MA=Arabic (Moroco) -Language_ar_SA=Arabic -Language_ar_TN=Arabic (Tunisia) -Language_ar_IQ=Arabic (Iraq) -Language_az_AZ=Azerbaijani -Language_bn_BD=Bengali -Language_bn_IN=Bengali (India) -Language_bg_BG=Bulgarian -Language_bs_BA=Bosnian -Language_ca_ES=Catalan -Language_cs_CZ=Czech -Language_da_DA=Danish -Language_da_DK=Danish -Language_de_DE=German -Language_de_AT=German (Austria) -Language_de_CH=German (Switzerland) -Language_el_GR=Greek -Language_el_CY=Greek (Cyprus) -Language_en_AU=English (Australia) -Language_en_CA=English (Canada) -Language_en_GB=English (United Kingdom) -Language_en_IN=English (India) -Language_en_NZ=English (New Zealand) -Language_en_SA=English (Saudi Arabia) -Language_en_SG=English (Singapore) -Language_en_US=English (United States) -Language_en_ZA=English (South Africa) -Language_es_ES=Spanish -Language_es_AR=Spanish (Argentina) -Language_es_BO=Spanish (Bolivia) -Language_es_CL=Spanish (Chile) -Language_es_CO=Spanish (Colombia) -Language_es_DO=Spanish (Dominican Republic) -Language_es_EC=Spanish (Ecuador) -Language_es_GT=Spanish (Guatemala) -Language_es_HN=Spanish (Honduras) -Language_es_MX=Spanish (Mexico) -Language_es_PA=Spanish (Panama) -Language_es_PY=Spanish (Paraguay) -Language_es_PE=Spanish (Peru) -Language_es_PR=Spanish (Puerto Rico) -Language_es_US=Spanish (USA) -Language_es_UY=Spanish (Uruguay) -Language_es_GT=Spanish (Guatemala) -Language_es_VE=Spanish (Venezuela) -Language_et_EE=Estonian -Language_eu_ES=Basque -Language_fa_IR=Persian -Language_fi_FI=Finnish -Language_fr_BE=French (Belgium) -Language_fr_CA=French (Canada) -Language_fr_CH=French (Switzerland) -Language_fr_CI=French (Cost Ivory) -Language_fr_CM=French (Cameroun) -Language_fr_FR=French -Language_fr_GA=French (Gabon) -Language_fr_NC=French (New Caledonia) -Language_fr_SN=French (Senegal) -Language_fy_NL=Frisian -Language_gl_ES=Galician -Language_he_IL=Hebrew -Language_hi_IN=Hindi (India) -Language_hr_HR=Croatian -Language_hu_HU=Hungarian -Language_id_ID=Indonesian -Language_is_IS=Icelandic -Language_it_IT=Italian -Language_it_CH=Italian (Switzerland) -Language_ja_JP=Japanese -Language_ka_GE=Georgian -Language_km_KH=Khmer -Language_kn_IN=Kannada -Language_ko_KR=Korean -Language_lo_LA=Lao -Language_lt_LT=Lithuanian -Language_lv_LV=Latvian -Language_mk_MK=Macedonian -Language_mn_MN=Mongolian -Language_nb_NO=Norwegian (Bokmål) -Language_ne_NP=Nepali -Language_nl_BE=Dutch (Belgium) -Language_nl_NL=Dutch -Language_pl_PL=Polish -Language_pt_AO=Portuguese (Angola) -Language_pt_BR=Portuguese (Brazil) -Language_pt_PT=Portuguese -Language_ro_MD=Romanian (Moldavia) -Language_ro_RO=Romanian -Language_ru_RU=Russian -Language_ru_UA=Russian (Ukraine) -Language_tr_TR=Turkish -Language_sl_SI=Slovenian -Language_sv_SV=Swedish -Language_sv_SE=Swedish -Language_sq_AL=Albanian -Language_sk_SK=Slovakian -Language_sr_RS=Serbian -Language_sw_SW=Kiswahili -Language_th_TH=Thai -Language_uk_UA=Ukrainian -Language_uz_UZ=Uzbek -Language_vi_VN=Vietnamese -Language_zh_CN=Chinese -Language_zh_TW=Chinese (Traditional) -Language_zh_HK=Chinese (Hong Kong) -Language_bh_MY=Malay diff --git a/htdocs/langs/ar_IQ/ldap.lang b/htdocs/langs/ar_IQ/ldap.lang deleted file mode 100644 index 8b6f0864215..00000000000 --- a/htdocs/langs/ar_IQ/ldap.lang +++ /dev/null @@ -1,27 +0,0 @@ -# Dolibarr language file - Source file is en_US - ldap -YouMustChangePassNextLogon=Password for user %s on the domain %s must be changed. -UserMustChangePassNextLogon=User must change password on the domain %s -LDAPInformationsForThisContact=Information in LDAP database for this contact -LDAPInformationsForThisUser=Information in LDAP database for this user -LDAPInformationsForThisGroup=Information in LDAP database for this group -LDAPInformationsForThisMember=Information in LDAP database for this member -LDAPInformationsForThisMemberType=Information in LDAP database for this member type -LDAPAttributes=LDAP attributes -LDAPCard=LDAP card -LDAPRecordNotFound=Record not found in LDAP database -LDAPUsers=Users in LDAP database -LDAPFieldStatus=Status -LDAPFieldFirstSubscriptionDate=First subscription date -LDAPFieldFirstSubscriptionAmount=First subscription amount -LDAPFieldLastSubscriptionDate=Latest subscription date -LDAPFieldLastSubscriptionAmount=Latest subscription amount -LDAPFieldSkype=Skype id -LDAPFieldSkypeExample=Example: skypeName -UserSynchronized=User synchronized -GroupSynchronized=Group synchronized -MemberSynchronized=Member synchronized -MemberTypeSynchronized=Member type synchronized -ContactSynchronized=Contact synchronized -ForceSynchronize=Force synchronizing Dolibarr -> LDAP -ErrorFailedToReadLDAP=Failed to read LDAP database. Check LDAP module setup and database accessibility. -PasswordOfUserInLDAP=Password of user in LDAP diff --git a/htdocs/langs/ar_IQ/link.lang b/htdocs/langs/ar_IQ/link.lang deleted file mode 100644 index 1ffcd41a18b..00000000000 --- a/htdocs/langs/ar_IQ/link.lang +++ /dev/null @@ -1,11 +0,0 @@ -# Dolibarr language file - Source file is en_US - languages -LinkANewFile=Link a new file/document -LinkedFiles=Linked files and documents -NoLinkFound=No registered links -LinkComplete=The file has been linked successfully -ErrorFileNotLinked=The file could not be linked -LinkRemoved=The link %s has been removed -ErrorFailedToDeleteLink= Failed to remove link '%s' -ErrorFailedToUpdateLink= Failed to update link '%s' -URLToLink=URL to link -OverwriteIfExists=Overwrite file if exists diff --git a/htdocs/langs/ar_IQ/loan.lang b/htdocs/langs/ar_IQ/loan.lang deleted file mode 100644 index d271ed0c140..00000000000 --- a/htdocs/langs/ar_IQ/loan.lang +++ /dev/null @@ -1,34 +0,0 @@ -# Dolibarr language file - Source file is en_US - loan -Loan=Loan -Loans=Loans -NewLoan=New Loan -ShowLoan=Show Loan -PaymentLoan=Loan payment -LoanPayment=Loan payment -ShowLoanPayment=Show Loan Payment -LoanCapital=Capital -Insurance=Insurance -Interest=Interest -Nbterms=Number of terms -Term=Term -LoanAccountancyCapitalCode=Accounting account capital -LoanAccountancyInsuranceCode=Accounting account insurance -LoanAccountancyInterestCode=Accounting account interest -ConfirmDeleteLoan=Confirm deleting this loan -LoanDeleted=Loan Deleted Successfully -ConfirmPayLoan=Confirm classify paid this loan -LoanPaid=Loan Paid -ListLoanAssociatedProject=List of loan associated with the project -AddLoan=Create loan -FinancialCommitment=Financial commitment -InterestAmount=Interest -CapitalRemain=Capital remain -TermPaidAllreadyPaid = This term is allready paid -CantUseScheduleWithLoanStartedToPaid = Can't use scheduler for a loan with payment started -CantModifyInterestIfScheduleIsUsed = You can't modify interest if you use schedule -# Admin -ConfigLoan=Configuration of the module loan -LOAN_ACCOUNTING_ACCOUNT_CAPITAL=Accounting account capital by default -LOAN_ACCOUNTING_ACCOUNT_INTEREST=Accounting account interest by default -LOAN_ACCOUNTING_ACCOUNT_INSURANCE=Accounting account insurance by default -CreateCalcSchedule=Edit financial commitment diff --git a/htdocs/langs/ar_IQ/mailmanspip.lang b/htdocs/langs/ar_IQ/mailmanspip.lang deleted file mode 100644 index bab4b3576b4..00000000000 --- a/htdocs/langs/ar_IQ/mailmanspip.lang +++ /dev/null @@ -1,27 +0,0 @@ -# Dolibarr language file - Source file is en_US - mailmanspip -MailmanSpipSetup=Mailman and SPIP module Setup -MailmanTitle=Mailman mailing list system -TestSubscribe=To test subscription to Mailman lists -TestUnSubscribe=To test unsubscribe from Mailman lists -MailmanCreationSuccess=Subscription test was executed successfully -MailmanDeletionSuccess=Unsubscription test was executed successfully -SynchroMailManEnabled=A Mailman update will be performed -SynchroSpipEnabled=A Spip update will be performed -DescADHERENT_MAILMAN_ADMINPW=Mailman administrator password -DescADHERENT_MAILMAN_URL=URL for Mailman subscriptions -DescADHERENT_MAILMAN_UNSUB_URL=URL for Mailman unsubscriptions -DescADHERENT_MAILMAN_LISTS=List(s) for automatic inscription of new members (separated by a comma) -SPIPTitle=SPIP Content Management System -DescADHERENT_SPIP_SERVEUR=SPIP Server -DescADHERENT_SPIP_DB=SPIP database name -DescADHERENT_SPIP_USER=SPIP database login -DescADHERENT_SPIP_PASS=SPIP database password -AddIntoSpip=Add into SPIP -AddIntoSpipConfirmation=Are you sure you want to add this member into SPIP? -AddIntoSpipError=Failed to add the user in SPIP -DeleteIntoSpip=Remove from SPIP -DeleteIntoSpipConfirmation=Are you sure you want to remove this member from SPIP? -DeleteIntoSpipError=Failed to suppress the user from SPIP -SPIPConnectionFailed=Failed to connect to SPIP -SuccessToAddToMailmanList=%s successfully added to mailman list %s or SPIP database -SuccessToRemoveToMailmanList=%s successfully removed from mailman list %s or SPIP database diff --git a/htdocs/langs/ar_IQ/mails.lang b/htdocs/langs/ar_IQ/mails.lang deleted file mode 100644 index 1c0dd638eeb..00000000000 --- a/htdocs/langs/ar_IQ/mails.lang +++ /dev/null @@ -1,179 +0,0 @@ -# Dolibarr language file - Source file is en_US - mails -Mailing=EMailing -EMailing=EMailing -EMailings=EMailings -AllEMailings=All eMailings -MailCard=EMailing card -MailRecipients=Recipients -MailRecipient=Recipient -MailTitle=Description -MailFrom=Sender -MailErrorsTo=Errors to -MailReply=Reply to -MailTo=Receiver(s) -MailToUsers=To user(s) -MailCC=Copy to -MailToCCUsers=Copy to users(s) -MailCCC=Cached copy to -MailTopic=Email subject -MailText=Message -MailFile=Attached files -MailMessage=Email body -SubjectNotIn=Not in Subject -BodyNotIn=Not in Body -ShowEMailing=Show emailing -ListOfEMailings=List of emailings -NewMailing=New emailing -EditMailing=Edit emailing -ResetMailing=Resend emailing -DeleteMailing=Delete emailing -DeleteAMailing=Delete an emailing -PreviewMailing=Preview emailing -CreateMailing=Create emailing -TestMailing=Test email -ValidMailing=Valid emailing -MailingStatusDraft=Draft -MailingStatusValidated=Validated -MailingStatusSent=Sent -MailingStatusSentPartialy=Sent partially -MailingStatusSentCompletely=Sent completely -MailingStatusError=Error -MailingStatusNotSent=Not sent -MailSuccessfulySent=Email (from %s to %s) successfully accepted for delivery -MailingSuccessfullyValidated=EMailing successfully validated -MailUnsubcribe=Unsubscribe -MailingStatusNotContact=Don't contact anymore -MailingStatusReadAndUnsubscribe=Read and unsubscribe -ErrorMailRecipientIsEmpty=Email recipient is empty -WarningNoEMailsAdded=No new Email to add to recipient's list. -ConfirmValidMailing=Are you sure you want to validate this emailing? -ConfirmResetMailing=Warning, by re-initializing emailing %s, you will allow the re-sending this email in a bulk mailing. Are you sure you want to do this? -ConfirmDeleteMailing=Are you sure you want to delete this emailing? -NbOfUniqueEMails=No. of unique emails -NbOfEMails=No. of EMails -TotalNbOfDistinctRecipients=Number of distinct recipients -NoTargetYet=No recipients defined yet (Go on tab 'Recipients') -NoRecipientEmail=No recipient email for %s -RemoveRecipient=Remove recipient -YouCanAddYourOwnPredefindedListHere=To create your email selector module, see htdocs/core/modules/mailings/README. -EMailTestSubstitutionReplacedByGenericValues=When using test mode, substitutions variables are replaced by generic values -MailingAddFile=Attach this file -NoAttachedFiles=No attached files -BadEMail=Bad value for Email -ConfirmCloneEMailing=Are you sure you want to clone this emailing? -CloneContent=Clone message -CloneReceivers=Cloner recipients -DateLastSend=Date of latest sending -DateSending=Date sending -SentTo=Sent to %s -MailingStatusRead=Read -YourMailUnsubcribeOK=The email %s is correctly unsubscribe from mailing list -ActivateCheckReadKey=Key used to encrypt URL used for "Read Receipt" and "Unsubscribe" feature -EMailSentToNRecipients=Email sent to %s recipients. -EMailSentForNElements=Email sent for %s elements. -XTargetsAdded=%s recipients added into target list -OnlyPDFattachmentSupported=If the PDF documents were already generated for the objects to send, they will be attached to email. If not, no email will be sent (also, note that only pdf documents are supported as attachments in mass sending in this version). -AllRecipientSelected=The recipients of the %s record selected (if their email is known). -GroupEmails=Group emails -OneEmailPerRecipient=One email per recipient (by default, one email per record selected) -WarningIfYouCheckOneRecipientPerEmail=Warning, if you check this box, it means only one email will be sent for several different record selected, so, if your message contains substitution variables that refers to data of a record, it becomes not possible to replace them. -ResultOfMailSending=Result of mass Email sending -NbSelected=Number selected -NbIgnored=Number ignored -NbSent=Number sent -SentXXXmessages=%s message(s) sent. -ConfirmUnvalidateEmailing=Are you sure you want to change email %s to draft status? -MailingModuleDescContactsWithThirdpartyFilter=Contact with customer filters -MailingModuleDescContactsByCompanyCategory=Contacts by third-party category -MailingModuleDescContactsByCategory=Contacts by categories -MailingModuleDescContactsByFunction=Contacts by position -MailingModuleDescEmailsFromFile=Emails from file -MailingModuleDescEmailsFromUser=Emails input by user -MailingModuleDescDolibarrUsers=Users with Emails -MailingModuleDescThirdPartiesByCategories=Third parties (by categories) -SendingFromWebInterfaceIsNotAllowed=Sending from web interface is not allowed. -EmailCollectorFilterDesc=All filters must match to have an email being collected - -# Libelle des modules de liste de destinataires mailing -LineInFile=Line %s in file -RecipientSelectionModules=Defined requests for recipient's selection -MailSelectedRecipients=Selected recipients -MailingArea=EMailings area -LastMailings=Latest %s emailings -TargetsStatistics=Targets statistics -NbOfCompaniesContacts=Unique contacts/addresses -MailNoChangePossible=Recipients for validated emailing can't be changed -SearchAMailing=Search mailing -SendMailing=Send emailing -SentBy=Sent by -MailingNeedCommand=Sending an emailing can be performed from command line. Ask your server administrator to launch the following command to send the emailing to all recipients: -MailingNeedCommand2=You can however send them online by adding parameter MAILING_LIMIT_SENDBYWEB with value of max number of emails you want to send by session. For this, go on Home - Setup - Other. -ConfirmSendingEmailing=If you want to send emailing directly from this screen, please confirm you are sure you want to send emailing now from your browser ? -LimitSendingEmailing=Note: Sending of emailings from web interface is done in several times for security and timeout reasons, %s recipients at a time for each sending session. -TargetsReset=Clear list -ToClearAllRecipientsClickHere=Click here to clear the recipient list for this emailing -ToAddRecipientsChooseHere=Add recipients by choosing from the lists -NbOfEMailingsReceived=Mass emailings received -NbOfEMailingsSend=Mass emailings sent -IdRecord=ID record -DeliveryReceipt=Delivery Ack. -YouCanUseCommaSeparatorForSeveralRecipients=You can use the comma separator to specify several recipients. -TagCheckMail=Track mail opening -TagUnsubscribe=Unsubscribe link -TagSignature=Signature of sending user -EMailRecipient=Recipient Email -TagMailtoEmail=Recipient Email (including html "mailto:" link) -NoEmailSentBadSenderOrRecipientEmail=No email sent. Bad sender or recipient email. Verify user profile. -# Module Notifications -Notifications=Notifications -NotificationsAuto=Notifications Auto. -NoNotificationsWillBeSent=No automatic email notifications are planned for this event type and company -ANotificationsWillBeSent=1 automatic notification will be sent by email -SomeNotificationsWillBeSent=%s automatic notifications will be sent by email -AddNewNotification=Subscribe to a new automatic email notification (target/event) -ListOfActiveNotifications=List of all active subscriptions (targets/events) for automatic email notification -ListOfNotificationsDone=List of all automatic email notifications sent -MailSendSetupIs=Configuration of email sending has been setup to '%s'. This mode can't be used to send mass emailing. -MailSendSetupIs2=You must first go, with an admin account, into menu %sHome - Setup - EMails%s to change parameter '%s' to use mode '%s'. With this mode, you can enter setup of the SMTP server provided by your Internet Service Provider and use Mass emailing feature. -MailSendSetupIs3=If you have any questions on how to setup your SMTP server, you can ask to %s. -YouCanAlsoUseSupervisorKeyword=You can also add the keyword __SUPERVISOREMAIL__ to have email being sent to the supervisor of user (works only if an email is defined for this supervisor) -NbOfTargetedContacts=Current number of targeted contact emails -UseFormatFileEmailToTarget=Imported file must have format email;name;firstname;other -UseFormatInputEmailToTarget=Enter a string with format email;name;firstname;other -MailAdvTargetRecipients=Recipients (advanced selection) -AdvTgtTitle=Fill input fields to preselect the third parties or contacts/addresses to target -AdvTgtSearchTextHelp=Use %% as wildcards. For example to find all item like jean, joe, jim, you can input j%%, you can also use ; as separator for value, and use ! for except this value. For example jean;joe;jim%%;!jimo;!jima%% will target all jean, joe, start with jim but not jimo and not everything that starts with jima -AdvTgtSearchIntHelp=Use interval to select int or float value -AdvTgtMinVal=Minimum value -AdvTgtMaxVal=Maximum value -AdvTgtSearchDtHelp=Use interval to select date value -AdvTgtStartDt=Start dt. -AdvTgtEndDt=End dt. -AdvTgtTypeOfIncudeHelp=Target Email of third party and email of contact of the third party, or just third-party email or just contact email -AdvTgtTypeOfIncude=Type of targeted email -AdvTgtContactHelp=Use only if you target contact into "Type of targeted email" -AddAll=Add all -RemoveAll=Remove all -ItemsCount=Item(s) -AdvTgtNameTemplate=Filter name -AdvTgtAddContact=Add emails according to criteria -AdvTgtLoadFilter=Load filter -AdvTgtDeleteFilter=Delete filter -AdvTgtSaveFilter=Save filter -AdvTgtCreateFilter=Create filter -AdvTgtOrCreateNewFilter=Name of new filter -NoContactWithCategoryFound=No category found linked to some contacts/addresses -NoContactLinkedToThirdpartieWithCategoryFound=No category found linked to some thirdparties -OutGoingEmailSetup=Outgoing emails -InGoingEmailSetup=Incoming emails -OutGoingEmailSetupForEmailing=Outgoing emails (for module %s) -DefaultOutgoingEmailSetup=Same configuration than the global Outgoing email setup -Information=Information -ContactsWithThirdpartyFilter=Contacts with third-party filter -Unanswered=Unanswered -Answered=Answered -IsNotAnAnswer=Is not answer (initial email) -IsAnAnswer=Is an answer of an initial email -RecordCreatedByEmailCollector=Record created by the Email Collector %s from email %s -DefaultBlacklistMailingStatus=Default contact status for refuse bulk emailing -DefaultStatusEmptyMandatory=Empty but mandatory diff --git a/htdocs/langs/ar_IQ/main.lang b/htdocs/langs/ar_IQ/main.lang index 6c1ef6aa659..2e691473326 100644 --- a/htdocs/langs/ar_IQ/main.lang +++ b/htdocs/langs/ar_IQ/main.lang @@ -1,9 +1,5 @@ # Dolibarr language file - Source file is en_US - main DIRECTION=ltr -# Note for Chinese: -# msungstdlight or cid0ct are for traditional Chinese (traditional does not render with Ubuntu pdf reader) -# stsongstdlight or cid0cs are for simplified Chinese -# To read Chinese pdf with Linux: sudo apt-get install poppler-data FONTFORPDF=helvetica FONTSIZEFORPDF=10 SeparatorDecimal=. @@ -23,1129 +19,3 @@ FormatDateHourShort=%m/%d/%Y %I:%M %p FormatDateHourSecShort=%m/%d/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -DatabaseConnection=Database connection -NoTemplateDefined=No template available for this email type -AvailableVariables=Available substitution variables -NoTranslation=No translation -Translation=Translation -CurrentTimeZone=TimeZone PHP (server) -EmptySearchString=Enter non empty search criterias -EnterADateCriteria=Enter a date criteria -NoRecordFound=No record found -NoRecordDeleted=No record deleted -NotEnoughDataYet=Not enough data -NoError=No error -Error=Error -Errors=Errors -ErrorFieldRequired=Field '%s' is required -ErrorFieldFormat=Field '%s' has a bad value -ErrorFileDoesNotExists=File %s does not exist -ErrorFailedToOpenFile=Failed to open file %s -ErrorCanNotCreateDir=Cannot create dir %s -ErrorCanNotReadDir=Cannot read dir %s -ErrorConstantNotDefined=Parameter %s not defined -ErrorUnknown=Unknown error -ErrorSQL=SQL Error -ErrorLogoFileNotFound=Logo file '%s' was not found -ErrorGoToGlobalSetup=Go to 'Company/Organization' setup to fix this -ErrorGoToModuleSetup=Go to Module setup to fix this -ErrorFailedToSendMail=Failed to send mail (sender=%s, receiver=%s) -ErrorFileNotUploaded=File was not uploaded. Check that size does not exceed maximum allowed, that free space is available on disk and that there is not already a file with same name in this directory. -ErrorInternalErrorDetected=Error detected -ErrorWrongHostParameter=Wrong host parameter -ErrorYourCountryIsNotDefined=Your country is not defined. Go to Home-Setup-Edit and post the form again. -ErrorRecordIsUsedByChild=Failed to delete this record. This record is used by at least one child record. -ErrorWrongValue=Wrong value -ErrorWrongValueForParameterX=Wrong value for parameter %s -ErrorNoRequestInError=No request in error -ErrorServiceUnavailableTryLater=Service not available at the moment. Try again later. -ErrorDuplicateField=Duplicate value in a unique field -ErrorSomeErrorWereFoundRollbackIsDone=Some errors were found. Changes have been rolled back. -ErrorConfigParameterNotDefined=Parameter %s is not defined in the Dolibarr config file conf.php. -ErrorCantLoadUserFromDolibarrDatabase=Failed to find user %s in Dolibarr database. -ErrorNoVATRateDefinedForSellerCountry=Error, no vat rates defined for country '%s'. -ErrorNoSocialContributionForSellerCountry=Error, no social/fiscal taxes type defined for country '%s'. -ErrorFailedToSaveFile=Error, failed to save file. -ErrorCannotAddThisParentWarehouse=You are trying to add a parent warehouse which is already a child of a existing warehouse -MaxNbOfRecordPerPage=Max. number of records per page -NotAuthorized=You are not authorized to do that. -SetDate=Set date -SelectDate=Select a date -SeeAlso=See also %s -SeeHere=See here -ClickHere=Click here -Here=Here -Apply=Apply -BackgroundColorByDefault=Default background color -FileRenamed=The file was successfully renamed -FileGenerated=The file was successfully generated -FileSaved=The file was successfully saved -FileUploaded=The file was successfully uploaded -FileTransferComplete=File(s) uploaded successfully -FilesDeleted=File(s) successfully deleted -FileWasNotUploaded=A file is selected for attachment but was not yet uploaded. Click on "Attach file" for this. -NbOfEntries=No. of entries -GoToWikiHelpPage=Read online help (Internet access needed) -GoToHelpPage=Read help -DedicatedPageAvailable=There is a dedicated help page related to your current screen -HomePage=Home Page -RecordSaved=Record saved -RecordDeleted=Record deleted -RecordGenerated=Record generated -LevelOfFeature=Level of features -NotDefined=Not defined -DolibarrInHttpAuthenticationSoPasswordUseless=Dolibarr authentication mode is set to %s in configuration file conf.php.
    This means that the password database is external to Dolibarr, so changing this field may have no effect. -Administrator=Administrator -Undefined=Undefined -PasswordForgotten=Password forgotten? -NoAccount=No account? -SeeAbove=See above -HomeArea=Home -LastConnexion=Last login -PreviousConnexion=Previous login -PreviousValue=Previous value -ConnectedOnMultiCompany=Connected on environment -ConnectedSince=Connected since -AuthenticationMode=Authentication mode -RequestedUrl=Requested URL -DatabaseTypeManager=Database type manager -RequestLastAccessInError=Latest database access request error -ReturnCodeLastAccessInError=Return code for latest database access request error -InformationLastAccessInError=Information for latest database access request error -DolibarrHasDetectedError=Dolibarr has detected a technical error -YouCanSetOptionDolibarrMainProdToZero=You can read log file or set option $dolibarr_main_prod to '0' in your config file to get more information. -InformationToHelpDiagnose=This information can be useful for diagnostic purposes (you can set option $dolibarr_main_prod to '1' to remove such notices) -MoreInformation=More information -TechnicalInformation=Technical information -TechnicalID=Technical ID -LineID=Line ID -NotePublic=Note (public) -NotePrivate=Note (private) -PrecisionUnitIsLimitedToXDecimals=Dolibarr was setup to limit precision of unit prices to %s decimals. -DoTest=Test -ToFilter=Filter -NoFilter=No filter -WarningYouHaveAtLeastOneTaskLate=Warning, you have at least one element that has exceeded the tolerance time. -yes=yes -Yes=Yes -no=no -No=No -All=All -Home=Home -Help=Help -OnlineHelp=Online help -PageWiki=Wiki page -MediaBrowser=Media browser -Always=Always -Never=Never -Under=under -Period=Period -PeriodEndDate=End date for period -SelectedPeriod=Selected period -PreviousPeriod=Previous period -Activate=Activate -Activated=Activated -Closed=Closed -Closed2=Closed -NotClosed=Not closed -Enabled=Enabled -Enable=Enable -Deprecated=Deprecated -Disable=Disable -Disabled=Disabled -Add=Add -AddLink=Add link -RemoveLink=Remove link -AddToDraft=Add to draft -Update=Update -Close=Close -CloseAs=Set status to -CloseBox=Remove widget from your dashboard -Confirm=Confirm -ConfirmSendCardByMail=Do you really want to send the content of this card by mail to %s? -Delete=Delete -Remove=Remove -Resiliate=Terminate -Cancel=Cancel -Modify=Modify -Edit=Edit -Validate=Validate -ValidateAndApprove=Validate and Approve -ToValidate=To validate -NotValidated=Not validated -Save=Save -SaveAs=Save As -SaveAndStay=Save and stay -SaveAndNew=Save and new -TestConnection=Test connection -ToClone=Clone -ConfirmCloneAsk=Are you sure you want to clone the object %s? -ConfirmClone=Choose the data you want to clone: -NoCloneOptionsSpecified=No data to clone defined. -Of=of -Go=Go -Run=Run -CopyOf=Copy of -Show=Show -Hide=Hide -ShowCardHere=Show card -Search=Search -SearchOf=Search -SearchMenuShortCut=Ctrl + shift + f -QuickAdd=Quick add -QuickAddMenuShortCut=Ctrl + shift + l -Valid=Valid -Approve=Approve -Disapprove=Disapprove -ReOpen=Re-Open -Upload=Upload -ToLink=Link -Select=Select -SelectAll=Select all -Choose=Choose -Resize=Resize -ResizeOrCrop=Resize or Crop -Recenter=Recenter -Author=Author -User=User -Users=Users -Group=Group -Groups=Groups -NoUserGroupDefined=No user group defined -Password=Password -PasswordRetype=Retype your password -NoteSomeFeaturesAreDisabled=Note that a lot of features/modules are disabled in this demonstration. -Name=Name -NameSlashCompany=Name / Company -Person=Person -Parameter=Parameter -Parameters=Parameters -Value=Value -PersonalValue=Personal value -NewObject=New %s -NewValue=New value -OldValue=Old value %s -CurrentValue=Current value -Code=Code -Type=Type -Language=Language -MultiLanguage=Multi-language -Note=Note -Title=Title -Label=Label -RefOrLabel=Ref. or label -Info=Log -Family=Family -Description=Description -Designation=Description -DescriptionOfLine=Description of line -DateOfLine=Date of line -DurationOfLine=Duration of line -Model=Doc template -DefaultModel=Default doc template -Action=Event -About=About -Number=Number -NumberByMonth=Total reports by month -AmountByMonth=Amount by month -Numero=Number -Limit=Limit -Limits=Limits -Logout=Logout -NoLogoutProcessWithAuthMode=No applicative disconnect feature with authentication mode %s -Connection=Login -Setup=Setup -Alert=Alert -MenuWarnings=Alerts -Previous=Previous -Next=Next -Cards=Cards -Card=Card -Now=Now -HourStart=Start hour -Deadline=Deadline -Date=Date -DateAndHour=Date and hour -DateToday=Today's date -DateReference=Reference date -DateStart=Start date -DateEnd=End date -DateCreation=Creation date -DateCreationShort=Creat. date -IPCreation=Creation IP -DateModification=Modification date -DateModificationShort=Modif. date -IPModification=Modification IP -DateLastModification=Latest modification date -DateValidation=Validation date -DateSigning=Signing date -DateClosing=Closing date -DateDue=Due date -DateValue=Value date -DateValueShort=Value date -DateOperation=Operation date -DateOperationShort=Oper. Date -DateLimit=Limit date -DateRequest=Request date -DateProcess=Process date -DateBuild=Report build date -DatePayment=Date of payment -DateApprove=Approving date -DateApprove2=Approving date (second approval) -RegistrationDate=Registration date -UserCreation=Creation user -UserModification=Modification user -UserValidation=Validation user -UserCreationShort=Creat. user -UserModificationShort=Modif. user -UserValidationShort=Valid. user -DurationYear=year -DurationMonth=month -DurationWeek=week -DurationDay=day -DurationYears=years -DurationMonths=months -DurationWeeks=weeks -DurationDays=days -Year=Year -Month=Month -Week=Week -WeekShort=Week -Day=Day -Hour=Hour -Minute=Minute -Second=Second -Years=Years -Months=Months -Days=Days -days=days -Hours=Hours -Minutes=Minutes -Seconds=Seconds -Weeks=Weeks -Today=Today -Yesterday=Yesterday -Tomorrow=Tomorrow -Morning=Morning -Afternoon=Afternoon -Quadri=Quadri -MonthOfDay=Month of the day -DaysOfWeek=Days of week -HourShort=H -MinuteShort=mn -Rate=Rate -CurrencyRate=Currency conversion rate -UseLocalTax=Include tax -Bytes=Bytes -KiloBytes=Kilobytes -MegaBytes=Megabytes -GigaBytes=Gigabytes -TeraBytes=Terabytes -UserAuthor=Ceated by -UserModif=Updated by -b=b. -Kb=Kb -Mb=Mb -Gb=Gb -Tb=Tb -Cut=Cut -Copy=Copy -Paste=Paste -Default=Default -DefaultValue=Default value -DefaultValues=Default values/filters/sorting -Price=Price -PriceCurrency=Price (currency) -UnitPrice=Unit price -UnitPriceHT=Unit price (excl.) -UnitPriceHTCurrency=Unit price (excl.) (currency) -UnitPriceTTC=Unit price -PriceU=U.P. -PriceUHT=U.P. (net) -PriceUHTCurrency=U.P (net) (currency) -PriceUTTC=U.P. (inc. tax) -Amount=Amount -AmountInvoice=Invoice amount -AmountInvoiced=Amount invoiced -AmountInvoicedHT=Amount invoiced (excl. tax) -AmountInvoicedTTC=Amount invoiced (inc. tax) -AmountPayment=Payment amount -AmountHTShort=Amount (excl.) -AmountTTCShort=Amount (inc. tax) -AmountHT=Amount (excl. tax) -AmountTTC=Amount (inc. tax) -AmountVAT=Amount tax -MulticurrencyAlreadyPaid=Already paid, original currency -MulticurrencyRemainderToPay=Remain to pay, original currency -MulticurrencyPaymentAmount=Payment amount, original currency -MulticurrencyAmountHT=Amount (excl. tax), original currency -MulticurrencyAmountTTC=Amount (inc. of tax), original currency -MulticurrencyAmountVAT=Amount tax, original currency -MulticurrencySubPrice=Amount sub price multi currency -AmountLT1=Amount tax 2 -AmountLT2=Amount tax 3 -AmountLT1ES=Amount RE -AmountLT2ES=Amount IRPF -AmountTotal=Total amount -AmountAverage=Average amount -PriceQtyMinHT=Price quantity min. (excl. tax) -PriceQtyMinHTCurrency=Price quantity min. (excl. tax) (currency) -PercentOfOriginalObject=Percent of original object -AmountOrPercent=Amount or percent -Percentage=Percentage -Total=Total -SubTotal=Subtotal -TotalHTShort=Total (excl.) -TotalHT100Short=Total 100%% (excl.) -TotalHTShortCurrency=Total (excl. in currency) -TotalTTCShort=Total (inc. tax) -TotalHT=Total (excl. tax) -TotalHTforthispage=Total (excl. tax) for this page -Totalforthispage=Total for this page -TotalTTC=Total (inc. tax) -TotalTTCToYourCredit=Total (inc. tax) to your credit -TotalVAT=Total tax -TotalVATIN=Total IGST -TotalLT1=Total tax 2 -TotalLT2=Total tax 3 -TotalLT1ES=Total RE -TotalLT2ES=Total IRPF -TotalLT1IN=Total CGST -TotalLT2IN=Total SGST -HT=Excl. tax -TTC=Inc. tax -INCVATONLY=Inc. VAT -INCT=Inc. all taxes -VAT=Sales tax -VATIN=IGST -VATs=Sales taxes -VATINs=IGST taxes -LT1=Sales tax 2 -LT1Type=Sales tax 2 type -LT2=Sales tax 3 -LT2Type=Sales tax 3 type -LT1ES=RE -LT2ES=IRPF -LT1IN=CGST -LT2IN=SGST -LT1GC=Additionnal cents -VATRate=Tax Rate -RateOfTaxN=Rate of tax %s -VATCode=Tax Rate code -VATNPR=Tax Rate NPR -DefaultTaxRate=Default tax rate -Average=Average -Sum=Sum -Delta=Delta -StatusToPay=To pay -RemainToPay=Remain to pay -Module=Module/Application -Modules=Modules/Applications -Option=Option -Filters=Filters -List=List -FullList=Full list -FullConversation=Full conversation -Statistics=Statistics -OtherStatistics=Other statistics -Status=Status -Favorite=Favorite -ShortInfo=Info. -Ref=Ref. -ExternalRef=Ref. extern -RefSupplier=Ref. vendor -RefPayment=Ref. payment -CommercialProposalsShort=Commercial proposals -Comment=Comment -Comments=Comments -ActionsToDo=Events to do -ActionsToDoShort=To do -ActionsDoneShort=Done -ActionNotApplicable=Not applicable -ActionRunningNotStarted=To start -ActionRunningShort=In progress -ActionDoneShort=Finished -ActionUncomplete=Incomplete -LatestLinkedEvents=Latest %s linked events -CompanyFoundation=Company/Organization -Accountant=Accountant -ContactsForCompany=Contacts for this third party -ContactsAddressesForCompany=Contacts/addresses for this third party -AddressesForCompany=Addresses for this third party -ActionsOnCompany=Events for this third party -ActionsOnContact=Events for this contact/address -ActionsOnContract=Events for this contract -ActionsOnMember=Events about this member -ActionsOnProduct=Events about this product -NActionsLate=%s late -ToDo=To do -Completed=Completed -Running=In progress -RequestAlreadyDone=Request already recorded -Filter=Filter -FilterOnInto=Search criteria '%s' into fields %s -RemoveFilter=Remove filter -ChartGenerated=Chart generated -ChartNotGenerated=Chart not generated -GeneratedOn=Build on %s -Generate=Generate -Duration=Duration -TotalDuration=Total duration -Summary=Summary -DolibarrStateBoard=Database Statistics -DolibarrWorkBoard=Open Items -NoOpenedElementToProcess=No open element to process -Available=Available -NotYetAvailable=Not yet available -NotAvailable=Not available -Categories=Tags/categories -Category=Tag/category -By=By -From=From -FromDate=From -FromLocation=From -to=to -To=to -ToDate=to -ToLocation=to -at=at -and=and -or=or -Other=Other -Others=Others -OtherInformations=Other information -Quantity=Quantity -Qty=Qty -ChangedBy=Changed by -ApprovedBy=Approved by -ApprovedBy2=Approved by (second approval) -Approved=Approved -Refused=Refused -ReCalculate=Recalculate -ResultKo=Failure -Reporting=Reporting -Reportings=Reporting -Draft=Draft -Drafts=Drafts -StatusInterInvoiced=Invoiced -Validated=Validated -ValidatedToProduce=Validated (To produce) -Opened=Open -OpenAll=Open (All) -ClosedAll=Closed (All) -New=New -Discount=Discount -Unknown=Unknown -General=General -Size=Size -OriginalSize=Original size -Received=Received -Paid=Paid -Topic=Subject -ByCompanies=By third parties -ByUsers=By user -Links=Links -Link=Link -Rejects=Rejects -Preview=Preview -NextStep=Next step -Datas=Data -None=None -NoneF=None -NoneOrSeveral=None or several -Late=Late -LateDesc=An item is defined as Delayed as per the system configuration in menu Home - Setup - Alerts. -NoItemLate=No late item -Photo=Picture -Photos=Pictures -AddPhoto=Add picture -DeletePicture=Picture delete -ConfirmDeletePicture=Confirm picture deletion? -Login=Login -LoginEmail=Login (email) -LoginOrEmail=Login or Email -CurrentLogin=Current login -EnterLoginDetail=Enter login details -January=January -February=February -March=March -April=April -May=May -June=June -July=July -August=August -September=September -October=October -November=November -December=December -Month01=January -Month02=February -Month03=March -Month04=April -Month05=May -Month06=June -Month07=July -Month08=August -Month09=September -Month10=October -Month11=November -Month12=December -MonthShort01=Jan -MonthShort02=Feb -MonthShort03=Mar -MonthShort04=Apr -MonthShort05=May -MonthShort06=Jun -MonthShort07=Jul -MonthShort08=Aug -MonthShort09=Sep -MonthShort10=Oct -MonthShort11=Nov -MonthShort12=Dec -MonthVeryShort01=J -MonthVeryShort02=F -MonthVeryShort03=M -MonthVeryShort04=A -MonthVeryShort05=M -MonthVeryShort06=J -MonthVeryShort07=J -MonthVeryShort08=A -MonthVeryShort09=S -MonthVeryShort10=O -MonthVeryShort11=N -MonthVeryShort12=D -AttachedFiles=Attached files and documents -JoinMainDoc=Join main document -DateFormatYYYYMM=YYYY-MM -DateFormatYYYYMMDD=YYYY-MM-DD -DateFormatYYYYMMDDHHMM=YYYY-MM-DD HH:SS -ReportName=Report name -ReportPeriod=Report period -ReportDescription=Description -Report=Report -Keyword=Keyword -Origin=Origin -Legend=Legend -Fill=Fill -Reset=Reset -File=File -Files=Files -NotAllowed=Not allowed -ReadPermissionNotAllowed=Read permission not allowed -AmountInCurrency=Amount in %s currency -Example=Example -Examples=Examples -NoExample=No example -FindBug=Report a bug -NbOfThirdParties=Number of third parties -NbOfLines=Number of lines -NbOfObjects=Number of objects -NbOfObjectReferers=Number of related items -Referers=Related items -TotalQuantity=Total quantity -DateFromTo=From %s to %s -DateFrom=From %s -DateUntil=Until %s -Check=Check -Uncheck=Uncheck -Internal=Internal -External=External -Internals=Internal -Externals=External -Warning=Warning -Warnings=Warnings -BuildDoc=Build Doc -Entity=Environment -Entities=Entities -CustomerPreview=Customer preview -SupplierPreview=Vendor preview -ShowCustomerPreview=Show customer preview -ShowSupplierPreview=Show vendor preview -RefCustomer=Ref. customer -InternalRef=Internal ref. -Currency=Currency -InfoAdmin=Information for administrators -Undo=Undo -Redo=Redo -ExpandAll=Expand all -UndoExpandAll=Undo expand -SeeAll=See all -Reason=Reason -FeatureNotYetSupported=Feature not yet supported -CloseWindow=Close window -Response=Response -Priority=Priority -SendByMail=Send by email -MailSentBy=Email sent by -NotSent=Not sent -TextUsedInTheMessageBody=Email body -SendAcknowledgementByMail=Send confirmation email -SendMail=Send email -Email=Email -NoEMail=No email -AlreadyRead=Already read -NotRead=Unread -NoMobilePhone=No mobile phone -Owner=Owner -FollowingConstantsWillBeSubstituted=The following constants will be replaced with the corresponding value. -Refresh=Refresh -BackToList=Back to list -BackToTree=Back to tree -GoBack=Go back -CanBeModifiedIfOk=Can be modified if valid -CanBeModifiedIfKo=Can be modified if not valid -ValueIsValid=Value is valid -ValueIsNotValid=Value is not valid -RecordCreatedSuccessfully=Record created successfully -RecordModifiedSuccessfully=Record modified successfully -RecordsModified=%s record(s) modified -RecordsDeleted=%s record(s) deleted -RecordsGenerated=%s record(s) generated -AutomaticCode=Automatic code -FeatureDisabled=Feature disabled -MoveBox=Move widget -Offered=Offered -NotEnoughPermissions=You don't have permission for this action -SessionName=Session name -Method=Method -Receive=Receive -CompleteOrNoMoreReceptionExpected=Complete or nothing more expected -ExpectedValue=Expected Value -ExpectedQty=Expected Qty -PartialWoman=Partial -TotalWoman=Total -NeverReceived=Never received -Canceled=Canceled -YouCanChangeValuesForThisListFromDictionarySetup=You can change values for this list from menu Setup - Dictionaries -YouCanChangeValuesForThisListFrom=You can change values for this list from menu %s -YouCanSetDefaultValueInModuleSetup=You can set the default value used when creating a new record in module setup -Color=Color -Documents=Linked files -Documents2=Documents -UploadDisabled=Upload disabled -MenuAccountancy=Accounting -MenuECM=Documents -MenuAWStats=AWStats -MenuMembers=Members -MenuAgendaGoogle=Google agenda -MenuTaxesAndSpecialExpenses=Taxes | Special expenses -ThisLimitIsDefinedInSetup=Dolibarr limit (Menu home-setup-security): %s Kb, PHP limit: %s Kb -ThisLimitIsDefinedInSetupAt=Dolibarr limit (Menu %s): %s Kb, PHP limit (Param %s): %s Kb -NoFileFound=No documents uploaded -CurrentUserLanguage=Current language -CurrentTheme=Current theme -CurrentMenuManager=Current menu manager -Browser=Browser -Layout=Layout -Screen=Screen -DisabledModules=Disabled modules -For=For -ForCustomer=For customer -Signature=Signature -DateOfSignature=Date of signature -HidePassword=Show command with password hidden -UnHidePassword=Show real command with clear password -Root=Root -RootOfMedias=Root of public medias (/medias) -Informations=Information -Page=Page -Notes=Notes -AddNewLine=Add new line -AddFile=Add file -FreeZone=Free-text product -FreeLineOfType=Free-text item, type: -CloneMainAttributes=Clone object with its main attributes -ReGeneratePDF=Re-generate PDF -PDFMerge=PDF Merge -Merge=Merge -DocumentModelStandardPDF=Standard PDF template -PrintContentArea=Show page to print main content area -MenuManager=Menu manager -WarningYouAreInMaintenanceMode=Warning, you are in maintenance mode: only login %s is allowed to use the application in this mode. -CoreErrorTitle=System error -CoreErrorMessage=Sorry, an error occurred. Contact your system administrator to check the logs or disable $dolibarr_main_prod=1 to get more information. -CreditCard=Credit card -ValidatePayment=Validate payment -CreditOrDebitCard=Credit or debit card -FieldsWithAreMandatory=Fields with %s are mandatory -FieldsWithIsForPublic=Fields with %s are shown in public list of members. If you don't want this, uncheck the "public" box. -AccordingToGeoIPDatabase=(according to GeoIP conversion) -Line=Line -NotSupported=Not supported -RequiredField=Required field -Result=Result -ToTest=Test -ValidateBefore=Item must be validated before using this feature -Visibility=Visibility -Totalizable=Totalizable -TotalizableDesc=This field is totalizable in list -Private=Private -Hidden=Hidden -Resources=Resources -Source=Source -Prefix=Prefix -Before=Before -After=After -IPAddress=IP address -Frequency=Frequency -IM=Instant messaging -NewAttribute=New attribute -AttributeCode=Attribute code -URLPhoto=URL of photo/logo -SetLinkToAnotherThirdParty=Link to another third party -LinkTo=Link to -LinkToProposal=Link to proposal -LinkToOrder=Link to order -LinkToInvoice=Link to invoice -LinkToTemplateInvoice=Link to template invoice -LinkToSupplierOrder=Link to purchase order -LinkToSupplierProposal=Link to vendor proposal -LinkToSupplierInvoice=Link to vendor invoice -LinkToContract=Link to contract -LinkToIntervention=Link to intervention -LinkToTicket=Link to ticket -CreateDraft=Create draft -SetToDraft=Back to draft -ClickToEdit=Click to edit -ClickToRefresh=Click to refresh -EditWithEditor=Edit with CKEditor -EditWithTextEditor=Edit with Text editor -EditHTMLSource=Edit HTML Source -ObjectDeleted=Object %s deleted -ByCountry=By country -ByTown=By town -ByDate=By date -ByMonthYear=By month/year -ByYear=By year -ByMonth=By month -ByDay=By day -BySalesRepresentative=By sales representative -LinkedToSpecificUsers=Linked to a particular user contact -NoResults=No results -AdminTools=Admin Tools -SystemTools=System tools -ModulesSystemTools=Modules tools -Test=Test -Element=Element -NoPhotoYet=No pictures available yet -Dashboard=Dashboard -MyDashboard=My Dashboard -Deductible=Deductible -from=from -toward=toward -Access=Access -SelectAction=Select action -SelectTargetUser=Select target user/employee -HelpCopyToClipboard=Use Ctrl+C to copy to clipboard -SaveUploadedFileWithMask=Save file on server with name "%s" (otherwise "%s") -OriginFileName=Original filename -SetDemandReason=Set source -SetBankAccount=Define Bank Account -AccountCurrency=Account currency -ViewPrivateNote=View notes -XMoreLines=%s line(s) hidden -ShowMoreLines=Show more/less lines -PublicUrl=Public URL -AddBox=Add box -SelectElementAndClick=Select an element and click on %s -PrintFile=Print File %s -ShowTransaction=Show entry on bank account -ShowIntervention=Show intervention -ShowContract=Show contract -GoIntoSetupToChangeLogo=Go to Home - Setup - Company to change logo or go to Home - Setup - Display to hide. -Deny=Deny -Denied=Denied -ListOf=List of %s -ListOfTemplates=List of templates -Gender=Gender -Genderman=Male -Genderwoman=Female -Genderother=Other -ViewList=List view -ViewGantt=Gantt view -ViewKanban=Kanban view -Mandatory=Mandatory -Hello=Hello -GoodBye=GoodBye -Sincerely=Sincerely -ConfirmDeleteObject=Are you sure you want to delete this object? -DeleteLine=Delete line -ConfirmDeleteLine=Are you sure you want to delete this line? -ErrorPDFTkOutputFileNotFound=Error: the file was not generated. Please check that the 'pdftk' command is installed in a directory included in the $PATH environment variable (linux/unix only) or contact your system administrator. -NoPDFAvailableForDocGenAmongChecked=No PDF were available for the document generation among checked record -TooManyRecordForMassAction=Too many records selected for mass action. The action is restricted to a list of %s records. -NoRecordSelected=No record selected -MassFilesArea=Area for files built by mass actions -ShowTempMassFilesArea=Show area of files built by mass actions -ConfirmMassDeletion=Bulk Delete confirmation -ConfirmMassDeletionQuestion=Are you sure you want to delete the %s selected record(s)? -RelatedObjects=Related Objects -ClassifyBilled=Classify billed -ClassifyUnbilled=Classify unbilled -Progress=Progress -ProgressShort=Progr. -FrontOffice=Front office -BackOffice=Back office -Submit=Submit -View=View -Export=Export -Exports=Exports -ExportFilteredList=Export filtered list -ExportList=Export list -ExportOptions=Export Options -IncludeDocsAlreadyExported=Include docs already exported -ExportOfPiecesAlreadyExportedIsEnable=Export of pieces already exported is enable -ExportOfPiecesAlreadyExportedIsDisable=Export of pieces already exported is disable -AllExportedMovementsWereRecordedAsExported=All exported movements were recorded as exported -NotAllExportedMovementsCouldBeRecordedAsExported=Not all exported movements could be recorded as exported -Miscellaneous=Miscellaneous -Calendar=Calendar -GroupBy=Group by... -ViewFlatList=View flat list -ViewAccountList=View ledger -ViewSubAccountList=View subaccount ledger -RemoveString=Remove string '%s' -SomeTranslationAreUncomplete=Some of the languages offered may be only partially translated or may contain errors. Please help to correct your language by registering at https://transifex.com/projects/p/dolibarr/ to add your improvements. -DirectDownloadLink=Public download link -PublicDownloadLinkDesc=Only the link is required to download the file -DirectDownloadInternalLink=Private download link -PrivateDownloadLinkDesc=You need to be logged and you need permissions to view or download the file -Download=Download -DownloadDocument=Download document -ActualizeCurrency=Update currency rate -Fiscalyear=Fiscal year -ModuleBuilder=Module and Application Builder -SetMultiCurrencyCode=Set currency -BulkActions=Bulk actions -ClickToShowHelp=Click to show tooltip help -WebSite=Website -WebSites=Websites -WebSiteAccounts=Website accounts -ExpenseReport=Expense report -ExpenseReports=Expense reports -HR=HR -HRAndBank=HR and Bank -AutomaticallyCalculated=Automatically calculated -TitleSetToDraft=Go back to draft -ConfirmSetToDraft=Are you sure you want to go back to Draft status? -ImportId=Import id -Events=Events -EMailTemplates=Email templates -FileNotShared=File not shared to external public -Project=Project -Projects=Projects -LeadOrProject=Lead | Project -LeadsOrProjects=Leads | Projects -Lead=Lead -Leads=Leads -ListOpenLeads=List open leads -ListOpenProjects=List open projects -NewLeadOrProject=New lead or project -Rights=Permissions -LineNb=Line no. -IncotermLabel=Incoterms -TabLetteringCustomer=Customer lettering -TabLetteringSupplier=Vendor lettering -Monday=Monday -Tuesday=Tuesday -Wednesday=Wednesday -Thursday=Thursday -Friday=Friday -Saturday=Saturday -Sunday=Sunday -MondayMin=Mo -TuesdayMin=Tu -WednesdayMin=We -ThursdayMin=Th -FridayMin=Fr -SaturdayMin=Sa -SundayMin=Su -Day1=Monday -Day2=Tuesday -Day3=Wednesday -Day4=Thursday -Day5=Friday -Day6=Saturday -Day0=Sunday -ShortMonday=M -ShortTuesday=T -ShortWednesday=W -ShortThursday=T -ShortFriday=F -ShortSaturday=S -ShortSunday=S -one=one -two=two -three=three -four=four -five=five -six=six -seven=seven -eight=eight -nine=nine -ten=ten -eleven=eleven -twelve=twelve -thirteen=thirdteen -fourteen=fourteen -fifteen=fifteen -sixteen=sixteen -seventeen=seventeen -eighteen=eighteen -nineteen=nineteen -twenty=twenty -thirty=thirty -forty=forty -fifty=fifty -sixty=sixty -seventy=seventy -eighty=eighty -ninety=ninety -hundred=hundred -thousand=thousand -million=million -billion=billion -trillion=trillion -quadrillion=quadrillion -SelectMailModel=Select an email template -SetRef=Set ref -Select2ResultFoundUseArrows=Some results found. Use arrows to select. -Select2NotFound=No result found -Select2Enter=Enter -Select2MoreCharacter=or more character -Select2MoreCharacters=or more characters -Select2MoreCharactersMore=Search syntax:
    | OR (a|b)
    * Any character (a*b)
    ^ Start with (^ab)
    $ End with (ab$)
    -Select2LoadingMoreResults=Loading more results... -Select2SearchInProgress=Search in progress... -SearchIntoThirdparties=Third parties -SearchIntoContacts=Contacts -SearchIntoMembers=Members -SearchIntoUsers=Users -SearchIntoProductsOrServices=Products or services -SearchIntoBatch=Lots / Serials -SearchIntoProjects=Projects -SearchIntoMO=Manufacturing Orders -SearchIntoTasks=Tasks -SearchIntoCustomerInvoices=Customer invoices -SearchIntoSupplierInvoices=Vendor invoices -SearchIntoCustomerOrders=Sales orders -SearchIntoSupplierOrders=Purchase orders -SearchIntoCustomerProposals=Commercial proposals -SearchIntoSupplierProposals=Vendor proposals -SearchIntoInterventions=Interventions -SearchIntoContracts=Contracts -SearchIntoCustomerShipments=Customer shipments -SearchIntoExpenseReports=Expense reports -SearchIntoLeaves=Leave -SearchIntoTickets=Tickets -SearchIntoCustomerPayments=Customer payments -SearchIntoVendorPayments=Vendor payments -SearchIntoMiscPayments=Miscellaneous payments -CommentLink=Comments -NbComments=Number of comments -CommentPage=Comments space -CommentAdded=Comment added -CommentDeleted=Comment deleted -Everybody=Everybody -PayedBy=Paid by -PayedTo=Paid to -Monthly=Monthly -Quarterly=Quarterly -Annual=Annual -Local=Local -Remote=Remote -LocalAndRemote=Local and Remote -KeyboardShortcut=Keyboard shortcut -AssignedTo=Assigned to -Deletedraft=Delete draft -ConfirmMassDraftDeletion=Draft mass delete confirmation -FileSharedViaALink=File shared with a public link -SelectAThirdPartyFirst=Select a third party first... -YouAreCurrentlyInSandboxMode=You are currently in the %s "sandbox" mode -Inventory=Inventory -AnalyticCode=Analytic code -TMenuMRP=MRP -ShowCompanyInfos=Show company infos -ShowMoreInfos=Show More Infos -NoFilesUploadedYet=Please upload a document first -SeePrivateNote=See private note -PaymentInformation=Payment information -ValidFrom=Valid from -ValidUntil=Valid until -NoRecordedUsers=No users -ToClose=To close -ToRefuse=To refuse -ToProcess=To process -ToApprove=To approve -GlobalOpenedElemView=Global view -NoArticlesFoundForTheKeyword=No article found for the keyword '%s' -NoArticlesFoundForTheCategory=No article found for the category -ToAcceptRefuse=To accept | refuse -ContactDefault_agenda=Event -ContactDefault_commande=Order -ContactDefault_contrat=Contract -ContactDefault_facture=Invoice -ContactDefault_fichinter=Intervention -ContactDefault_invoice_supplier=Supplier Invoice -ContactDefault_order_supplier=Purchase Order -ContactDefault_project=Project -ContactDefault_project_task=Task -ContactDefault_propal=Proposal -ContactDefault_supplier_proposal=Supplier Proposal -ContactDefault_ticket=Ticket -ContactAddedAutomatically=Contact added from contact thirdparty roles -More=More -ShowDetails=Show details -CustomReports=Custom reports -StatisticsOn=Statistics on -SelectYourGraphOptionsFirst=Select your graph options to build a graph -Measures=Measures -XAxis=X-Axis -YAxis=Y-Axis -StatusOfRefMustBe=Status of %s must be %s -DeleteFileHeader=Confirm file delete -DeleteFileText=Do you really want delete this file? -ShowOtherLanguages=Show other languages -SwitchInEditModeToAddTranslation=Switch in edit mode to add translations for this language -NotUsedForThisCustomer=Not used for this customer -AmountMustBePositive=Amount must be positive -ByStatus=By status -InformationMessage=Information -Used=Used -ASAP=As Soon As Possible -CREATEInDolibarr=Record %s created -MODIFYInDolibarr=Record %s modified -DELETEInDolibarr=Record %s deleted -VALIDATEInDolibarr=Record %s validated -APPROVEDInDolibarr=Record %s approved -DefaultMailModel=Default Mail Model -PublicVendorName=Public name of vendor -DateOfBirth=Date of birth -SecurityTokenHasExpiredSoActionHasBeenCanceledPleaseRetry=Security token has expired, so action has been canceled. Please try again. -UpToDate=Up-to-date -OutOfDate=Out-of-date -EventReminder=Event Reminder -UpdateForAllLines=Update for all lines -OnHold=On hold -Civility=Civility -AffectTag=Affect Tag -CreateExternalUser=Create external user -ConfirmAffectTag=Bulk Tag Affect -ConfirmAffectTagQuestion=Are you sure you want to affect tags to the %s selected record(s)? -CategTypeNotFound=No tag type found for type of records -CopiedToClipboard=Copied to clipboard -InformationOnLinkToContract=This amount is only the total of all the lines of the contract. No notion of time is taken into consideration. -ConfirmCancel=Are you sure you want to cancel -EmailMsgID=Email MsgID -SetToEnabled=Set to enabled -SetToDisabled=Set to disabled -ConfirmMassEnabling=mass enabling confirmation -ConfirmMassEnablingQuestion=Are you sure you want to enable the %s selected record(s)? -ConfirmMassDisabling=mass disabling confirmation -ConfirmMassDisablingQuestion=Are you sure you want to disable the %s selected record(s)? -RecordsEnabled=%s record(s) enabled -RecordsDisabled=%s record(s) disabled -RecordEnabled=Record enabled -RecordDisabled=Record disabled -Forthcoming=Forthcoming -Currently=Currently diff --git a/htdocs/langs/ar_IQ/margins.lang b/htdocs/langs/ar_IQ/margins.lang index ad5406409b4..ec02ad138e3 100644 --- a/htdocs/langs/ar_IQ/margins.lang +++ b/htdocs/langs/ar_IQ/margins.lang @@ -1,45 +1,2 @@ -# Dolibarr language file - Source file is en_US - marges - -Margin=Margin -Margins=Margins -TotalMargin=Total Margin -MarginOnProducts=Margin / Products -MarginOnServices=Margin / Services -MarginRate=Margin rate -MarkRate=Mark rate -DisplayMarginRates=Display margin rates -DisplayMarkRates=Display mark rates -InputPrice=Input price -margin=Profit margins management -margesSetup=Profit margins management setup -MarginDetails=Margin details -ProductMargins=Product margins -CustomerMargins=Customer margins -SalesRepresentativeMargins=Sales representative margins -ContactOfInvoice=Contact of invoice -UserMargins=User margins -ProductService=Product or Service -AllProducts=All products and services -ChooseProduct/Service=Choose product or service -ForceBuyingPriceIfNull=Force buying/cost price to selling price if not defined +# Dolibarr language file - Source file is en_US - margins ForceBuyingPriceIfNullDetails=If buying/cost price not provided when we add a new line, and this option is "ON", the margin will be 0 on the new line (buying/cost price = selling price). If this option is "OFF" (recommended), margin will be equal to the value suggested by default (and may be 100% if no default value can be found). -MARGIN_METHODE_FOR_DISCOUNT=Margin method for global discounts -UseDiscountAsProduct=As a product -UseDiscountAsService=As a service -UseDiscountOnTotal=On subtotal -MARGIN_METHODE_FOR_DISCOUNT_DETAILS=Defines if a global discount is treated as a product, a service, or only on subtotal for margin calculation. -MARGIN_TYPE=Buying/Cost price suggested by default for margin calculation -MargeType1=Margin on Best vendor price -MargeType2=Margin on Weighted Average Price (WAP) -MargeType3=Margin on Cost Price -MarginTypeDesc=* Margin on best buying price = Selling price - Best vendor price defined on product card
    * Margin on Weighted Average Price (WAP) = Selling price - Product Weighted Average Price (WAP) or best vendor price if WAP not yet defined
    * Margin on Cost price = Selling price - Cost price defined on product card or WAP if cost price not defined, or best vendor price if WAP not yet defined -CostPrice=Cost price -UnitCharges=Unit charges -Charges=Charges -AgentContactType=Commercial agent contact type -AgentContactTypeDetails=Define what contact type (linked on invoices) will be used for margin report per contact/address. Note that reading statistics on a contact is not reliable since in most cases the contact may not be defined explicitely on the invoices. -rateMustBeNumeric=Rate must be a numeric value -markRateShouldBeLesserThan100=Mark rate should be lower than 100 -ShowMarginInfos=Show margin infos -CheckMargins=Margins detail -MarginPerSaleRepresentativeWarning=The report of margin per user use the link between third parties and sale representatives to calculate the margin of each sale representative. Because some thirdparties may not have any dedicated sale representative and some third parties may be linked to several, some amounts may not be included into this report (if there is no sale representative) and some may appear on different lines (for each sale representative). diff --git a/htdocs/langs/ar_IQ/members.lang b/htdocs/langs/ar_IQ/members.lang index d8b9c2f59f3..45f5a38babe 100644 --- a/htdocs/langs/ar_IQ/members.lang +++ b/htdocs/langs/ar_IQ/members.lang @@ -1,217 +1,25 @@ # Dolibarr language file - Source file is en_US - members -MembersArea=Members area -MemberCard=Member card -SubscriptionCard=Subscription card -Member=Member -Members=Members -ShowMember=Show member card -UserNotLinkedToMember=User not linked to a member -ThirdpartyNotLinkedToMember=Third party not linked to a member MembersTickets=Members Tickets -FundationMembers=Foundation members -ListOfValidatedPublicMembers=List of validated public members -ErrorThisMemberIsNotPublic=This member is not public -ErrorMemberIsAlreadyLinkedToThisThirdParty=Another member (name: %s, login: %s) is already linked to a third party %s. Remove this link first because a third party can't be linked to only a member (and vice versa). -ErrorUserPermissionAllowsToLinksToItselfOnly=For security reasons, you must be granted permissions to edit all users to be able to link a member to a user that is not yours. -SetLinkToUser=Link to a Dolibarr user -SetLinkToThirdParty=Link to a Dolibarr third party -MembersCards=Business cards for members -MembersList=List of members -MembersListToValid=List of draft members (to be validated) -MembersListValid=List of valid members -MembersListUpToDate=List of valid members with up-to-date subscription -MembersListNotUpToDate=List of valid members with out-of-date subscription -MembersListExcluded=List of excluded members -MembersListResiliated=List of terminated members -MembersListQualified=List of qualified members -MenuMembersToValidate=Draft members -MenuMembersValidated=Validated members -MenuMembersExcluded=Excluded members -MenuMembersResiliated=Terminated members MembersWithSubscriptionToReceive=Members with subscription to receive -MembersWithSubscriptionToReceiveShort=Subscription to receive DateSubscription=Subscription date DateEndSubscription=Subscription end date -EndSubscription=Subscription Ends SubscriptionId=Subscription id -WithoutSubscription=Without subscription -MemberId=Member id -NewMember=New member -MemberType=Member type -MemberTypeId=Member type id -MemberTypeLabel=Member type label -MembersTypes=Members types -MemberStatusDraft=Draft (needs to be validated) -MemberStatusDraftShort=Draft MemberStatusActive=Validated (waiting subscription) -MemberStatusActiveShort=Validated -MemberStatusActiveLate=Subscription expired -MemberStatusActiveLateShort=Expired -MemberStatusPaid=Subscription up to date -MemberStatusPaidShort=Up to date -MemberStatusExcluded=Excluded member -MemberStatusExcludedShort=Excluded -MemberStatusResiliated=Terminated member -MemberStatusResiliatedShort=Terminated -MembersStatusToValid=Draft members -MembersStatusExcluded=Excluded members -MembersStatusResiliated=Terminated members -MemberStatusNoSubscription=Validated (no subscription needed) -MemberStatusNoSubscriptionShort=Validated -SubscriptionNotNeeded=No subscription needed -NewCotisation=New contribution -PaymentSubscription=New contribution payment -SubscriptionEndDate=Subscription's end date -MembersTypeSetup=Members type setup -MemberTypeModified=Member type modified -DeleteAMemberType=Delete a member type -ConfirmDeleteMemberType=Are you sure you want to delete this member type? -MemberTypeDeleted=Member type deleted -MemberTypeCanNotBeDeleted=Member type can not be deleted NewSubscription=New subscription -NewSubscriptionDesc=This form allows you to record your subscription as a new member of the foundation. If you want to renew your subscription (if already a member), please contact foundation board instead by email %s. Subscription=Subscription Subscriptions=Subscriptions -SubscriptionLate=Late SubscriptionNotReceived=Subscription never received ListOfSubscriptions=List of subscriptions -SendCardByMail=Send card by email -AddMember=Create member -NoTypeDefinedGoToSetup=No member types defined. Go to menu "Members types" -NewMemberType=New member type -WelcomeEMail=Welcome email SubscriptionRequired=Subscription required -DeleteType=Delete -VoteAllowed=Vote allowed -Physical=Individual -Moral=Corporation -MorAndPhy=Corporation and Individual -Reenable=Re-Enable -ExcludeMember=Exclude a member -ConfirmExcludeMember=Are you sure you want to exclude this member ? -ResiliateMember=Terminate a member -ConfirmResiliateMember=Are you sure you want to terminate this member? -DeleteMember=Delete a member -ConfirmDeleteMember=Are you sure you want to delete this member (Deleting a member will delete all his subscriptions)? -DeleteSubscription=Delete a subscription -ConfirmDeleteSubscription=Are you sure you want to delete this subscription? -Filehtpasswd=htpasswd file -ValidateMember=Validate a member -ConfirmValidateMember=Are you sure you want to validate this member? -FollowingLinksArePublic=The following links are open pages not protected by any Dolibarr permission. They are not formatted pages, provided as example to show how to list members database. -PublicMemberList=Public member list -BlankSubscriptionForm=Public self-subscription form -BlankSubscriptionFormDesc=Dolibarr can provide you a public URL/website to allow external visitors to ask to subscribe to the foundation. If an online payment module is enabled, a payment form may also be automatically provided. -EnablePublicSubscriptionForm=Enable the public website with self-subscription form -ForceMemberType=Force the member type ExportDataset_member_1=Members and subscriptions -ImportDataset_member_1=Members -LastMembersModified=Latest %s modified members -LastSubscriptionsModified=Latest %s modified subscriptions -String=String -Text=Text -Int=Int -DateAndTime=Date and time -PublicMemberCard=Member public card -SubscriptionNotRecorded=Subscription not recorded AddSubscription=Create subscription ShowSubscription=Show subscription -# Label of email templates -SendingAnEMailToMember=Sending information email to member -SendingEmailOnAutoSubscription=Sending email on auto registration -SendingEmailOnMemberValidation=Sending email on new member validation -SendingEmailOnNewSubscription=Sending email on new subscription -SendingReminderForExpiredSubscription=Sending reminder for expired subscriptions -SendingEmailOnCancelation=Sending email on cancelation -SendingReminderActionComm=Sending reminder for agenda event -# Topic of email templates -YourMembershipRequestWasReceived=Your membership was received. -YourMembershipWasValidated=Your membership was validated -YourSubscriptionWasRecorded=Your new subscription was recorded -SubscriptionReminderEmail=Subscription reminder -YourMembershipWasCanceled=Your membership was canceled -CardContent=Content of your member card -# Text of email templates -ThisIsContentOfYourMembershipRequestWasReceived=We want to let you know that your membership request was received.

    -ThisIsContentOfYourMembershipWasValidated=We want to let you know that your membership was validated with the following information:

    -ThisIsContentOfYourSubscriptionWasRecorded=We want to let you know that your new subscription was recorded.

    -ThisIsContentOfSubscriptionReminderEmail=We want to let you know that your subscription is about to expire or has already expired (__MEMBER_LAST_SUBSCRIPTION_DATE_END__). We hope you will renew it.

    -ThisIsContentOfYourCard=This is a summary of the information we have about you. Please contact us if anything is incorrect.

    -DescADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT=Subject of the notification email received in case of auto-inscription of a guest -DescADHERENT_AUTOREGISTER_NOTIF_MAIL=Content of the notification email received in case of auto-inscription of a guest -DescADHERENT_EMAIL_TEMPLATE_AUTOREGISTER=Email template to use to send email to a member on member autosubscription -DescADHERENT_EMAIL_TEMPLATE_MEMBER_VALIDATION=Email template to use to send email to a member on member validation -DescADHERENT_EMAIL_TEMPLATE_SUBSCRIPTION=Email template to use to send email to a member on new subscription recording -DescADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION=Email template to use to send email reminder when subscription is about to expire -DescADHERENT_EMAIL_TEMPLATE_CANCELATION=Email template to use to send email to a member on member cancelation -DescADHERENT_EMAIL_TEMPLATE_EXCLUSION=Email template to use to send email to a member on member exclusion -DescADHERENT_MAIL_FROM=Sender Email for automatic emails -DescADHERENT_ETIQUETTE_TYPE=Format of labels page -DescADHERENT_ETIQUETTE_TEXT=Text printed on member address sheets -DescADHERENT_CARD_TYPE=Format of cards page -DescADHERENT_CARD_HEADER_TEXT=Text printed on top of member cards -DescADHERENT_CARD_TEXT=Text printed on member cards (align on left) -DescADHERENT_CARD_TEXT_RIGHT=Text printed on member cards (align on right) -DescADHERENT_CARD_FOOTER_TEXT=Text printed on bottom of member cards -ShowTypeCard=Show type '%s' -HTPasswordExport=htpassword file generation NoThirdPartyAssociatedToMember=No third party associated to this member -MembersAndSubscriptions= Members and Subscriptions -MoreActions=Complementary action on recording +MembersAndSubscriptions=Members and Subscriptions MoreActionsOnSubscription=Complementary action, suggested by default when recording a subscription -MoreActionBankDirect=Create a direct entry on bank account -MoreActionBankViaInvoice=Create an invoice, and a payment on bank account -MoreActionInvoiceOnly=Create an invoice with no payment -LinkToGeneratedPages=Generate visit cards -LinkToGeneratedPagesDesc=This screen allows you to generate PDF files with business cards for all your members or a particular member. -DocForAllMembersCards=Generate business cards for all members -DocForOneMemberCards=Generate business cards for a particular member -DocForLabels=Generate address sheets SubscriptionPayment=Subscription payment -LastSubscriptionDate=Date of latest subscription payment -LastSubscriptionAmount=Amount of latest subscription -LastMemberType=Last Member type -MembersStatisticsByCountries=Members statistics by country -MembersStatisticsByState=Members statistics by state/province -MembersStatisticsByTown=Members statistics by town -MembersStatisticsByRegion=Members statistics by region -NbOfMembers=Total number of members -NbOfActiveMembers=Total number of current active members -NoValidatedMemberYet=No validated members found -MembersByCountryDesc=This screen shows you the statistics of members by countries. Graphs and charts depend on the availability of the Google online graph service as well as on the availability of a working internet connection. -MembersByStateDesc=This screen show you statistics of members by state/provinces/canton. -MembersByTownDesc=This screen show you statistics of members by town. -MembersByNature=This screen show you statistics of members by nature. -MembersByRegion=This screen show you statistics of members by region. -MembersStatisticsDesc=Choose statistics you want to read... -MenuMembersStats=Statistics -LastMemberDate=Latest membership date -LatestSubscriptionDate=Latest subscription date -MemberNature=Nature of the member -MembersNature=Nature of the members -Public=Information is public -NewMemberbyWeb=New member added. Awaiting approval -NewMemberForm=New member form -SubscriptionsStatistics=Subscriptions statistics NbOfSubscriptions=Number of subscriptions -AmountOfSubscriptions=Amount collected from subscriptions -TurnoverOrBudget=Turnover (for a company) or Budget (for a foundation) DefaultAmount=Default amount of subscription CanEditAmount=Visitor can choose/edit amount of its subscription -MEMBER_NEWFORM_PAYONLINE=Jump on integrated online payment page -ByProperties=By nature -MembersStatisticsByProperties=Members statistics by nature VATToUseForSubscriptions=VAT rate to use for subscriptions -NoVatOnSubscription=No VAT for subscriptions ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS=Product used for subscription line into invoice: %s -NameOrCompany=Name or company -SubscriptionRecorded=Subscription recorded -NoEmailSentToMember=No email sent to member -EmailSentToMember=Email sent to member at %s -SendReminderForExpiredSubscriptionTitle=Send reminder by email for expired subscription -SendReminderForExpiredSubscription=Send reminder by email to members when subscription is about to expire (parameter is number of days before end of subscription to send the remind. It can be a list of days separated by a semicolon, for example '10;5;0;-5') -MembershipPaid=Membership paid for current period (until %s) -YouMayFindYourInvoiceInThisEmail=You may find your invoice attached to this email -XMembersClosed=%s member(s) closed -XExternalUserCreated=%s external user(s) created -ForceMemberNature=Force member nature (Individual or Corporation) diff --git a/htdocs/langs/ar_IQ/modulebuilder.lang b/htdocs/langs/ar_IQ/modulebuilder.lang deleted file mode 100644 index 23a098be2e5..00000000000 --- a/htdocs/langs/ar_IQ/modulebuilder.lang +++ /dev/null @@ -1,146 +0,0 @@ -# Dolibarr language file - Source file is en_US - loan -ModuleBuilderDesc=This tool must be used only by experienced users or developers. It provides utilities to build or edit your own module. Documentation for alternative manual development is here. -EnterNameOfModuleDesc=Enter name of the module/application to create with no spaces. Use uppercase to separate words (For example: MyModule, EcommerceForShop, SyncWithMySystem...) -EnterNameOfObjectDesc=Enter name of the object to create with no spaces. Use uppercase to separate words (For example: MyObject, Student, Teacher...). The CRUD class file, but also API file, pages to list/add/edit/delete object and SQL files will be generated. -ModuleBuilderDesc2=Path where modules are generated/edited (first directory for external modules defined into %s): %s -ModuleBuilderDesc3=Generated/editable modules found: %s -ModuleBuilderDesc4=A module is detected as 'editable' when the file %s exists in root of module directory -NewModule=New module -NewObjectInModulebuilder=New object -ModuleKey=Module key -ObjectKey=Object key -ModuleInitialized=Module initialized -FilesForObjectInitialized=Files for new object '%s' initialized -FilesForObjectUpdated=Files for object '%s' updated (.sql files and .class.php file) -ModuleBuilderDescdescription=Enter here all general information that describe your module. -ModuleBuilderDescspecifications=You can enter here a detailed description of the specifications of your module that is not already structured into other tabs. So you have within easy reach all the rules to develop. Also this text content will be included into the generated documentation (see last tab). You can use Markdown format, but it is recommended to use Asciidoc format (comparison between .md and .asciidoc: http://asciidoctor.org/docs/user-manual/#compared-to-markdown). -ModuleBuilderDescobjects=Define here the objects you want to manage with your module. A CRUD DAO class, SQL files, page to list record of objects, to create/edit/view a record and an API will be generated. -ModuleBuilderDescmenus=This tab is dedicated to define menu entries provided by your module. -ModuleBuilderDescpermissions=This tab is dedicated to define the new permissions you want to provide with your module. -ModuleBuilderDesctriggers=This is the view of triggers provided by your module. To include code executed when a triggered business event is launched, just edit this file. -ModuleBuilderDeschooks=This tab is dedicated to hooks. -ModuleBuilderDescwidgets=This tab is dedicated to manage/build widgets. -ModuleBuilderDescbuildpackage=You can generate here a "ready to distribute" package file (a normalized .zip file) of your module and a "ready to distribute" documentation file. Just click on button to build the package or documentation file. -EnterNameOfModuleToDeleteDesc=You can delete your module. WARNING: All coding files of module (generated or created manually) AND structured data and documentation will be deleted! -EnterNameOfObjectToDeleteDesc=You can delete an object. WARNING: All coding files (generated or created manually) related to object will be deleted! -DangerZone=Danger zone -BuildPackage=Build package -BuildPackageDesc=You can generate a zip package of your application so your are ready to distribute it on any Dolibarr. You can also distribute it or sell it on marketplace like DoliStore.com. -BuildDocumentation=Build documentation -ModuleIsNotActive=This module is not activated yet. Go to %s to make it live or click here -ModuleIsLive=This module has been activated. Any change may break a current live feature. -DescriptionLong=Long description -EditorName=Name of editor -EditorUrl=URL of editor -DescriptorFile=Descriptor file of module -ClassFile=File for PHP DAO CRUD class -ApiClassFile=File for PHP API class -PageForList=PHP page for list of record -PageForCreateEditView=PHP page to create/edit/view a record -PageForAgendaTab=PHP page for event tab -PageForDocumentTab=PHP page for document tab -PageForNoteTab=PHP page for note tab -PageForContactTab=PHP page for contact tab -PathToModulePackage=Path to zip of module/application package -PathToModuleDocumentation=Path to file of module/application documentation (%s) -SpaceOrSpecialCharAreNotAllowed=Spaces or special characters are not allowed. -FileNotYetGenerated=File not yet generated -RegenerateClassAndSql=Force update of .class and .sql files -RegenerateMissingFiles=Generate missing files -SpecificationFile=File of documentation -LanguageFile=File for language -ObjectProperties=Object Properties -ConfirmDeleteProperty=Are you sure you want to delete the property %s? This will change code in PHP class but also remove column from table definition of object. -NotNull=Not NULL -NotNullDesc=1=Set database to NOT NULL. -1=Allow null values and force value to NULL if empty ('' or 0). -SearchAll=Used for 'search all' -DatabaseIndex=Database index -FileAlreadyExists=File %s already exists -TriggersFile=File for triggers code -HooksFile=File for hooks code -ArrayOfKeyValues=Array of key-val -ArrayOfKeyValuesDesc=Array of keys and values if field is a combo list with fixed values -WidgetFile=Widget file -CSSFile=CSS file -JSFile=Javascript file -ReadmeFile=Readme file -ChangeLog=ChangeLog file -TestClassFile=File for PHP Unit Test class -SqlFile=Sql file -PageForLib=File for the common PHP library -PageForObjLib=File for the PHP library dedicated to object -SqlFileExtraFields=Sql file for complementary attributes -SqlFileKey=Sql file for keys -SqlFileKeyExtraFields=Sql file for keys of complementary attributes -AnObjectAlreadyExistWithThisNameAndDiffCase=An object already exists with this name and a different case -UseAsciiDocFormat=You can use Markdown format, but it is recommended to use Asciidoc format (omparison between .md and .asciidoc: http://asciidoctor.org/docs/user-manual/#compared-to-markdown) -IsAMeasure=Is a measure -DirScanned=Directory scanned -NoTrigger=No trigger -NoWidget=No widget -GoToApiExplorer=API explorer -ListOfMenusEntries=List of menu entries -ListOfDictionariesEntries=List of dictionaries entries -ListOfPermissionsDefined=List of defined permissions -SeeExamples=See examples here -EnabledDesc=Condition to have this field active (Examples: 1 or $conf->global->MYMODULE_MYOPTION) -VisibleDesc=Is the field visible ? (Examples: 0=Never 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 end view form only (not create, not update).

    Using a negative value means field is not shown by default on list but can be selected for viewing).

    It can be an expression, for example:
    preg_match('/public/', $_SERVER['PHP_SELF'])?0:1
    ($user->rights->holiday->define_holiday ? 1 : 0) -DisplayOnPdfDesc=Display this field on compatible PDF documents, you can manage position with "Position" field.
    Currently, known compatibles PDF models are : eratosthene (order), espadon (ship), sponge (invoices), cyan (propal/quotation), cornas (supplier order)

    For document :
    0 = not displayed
    1 = display
    2 = display only if not empty

    For document lines :
    0 = not displayed
    1 = displayed in a column
    3 = display in line description column after the description
    4 = display in description column after the description only if not empty -DisplayOnPdf=Display on PDF -IsAMeasureDesc=Can the value of field be cumulated to get a total into list? (Examples: 1 or 0) -SearchAllDesc=Is the field used to make a search from the quick search tool? (Examples: 1 or 0) -SpecDefDesc=Enter here all documentation you want to provide with your module that is not already defined by other tabs. You can use .md or better, the rich .asciidoc syntax. -LanguageDefDesc=Enter in this files, all the key and the translation for each language file. -MenusDefDesc=Define here the menus provided by your module -DictionariesDefDesc=Define here the dictionaries provided by your module -PermissionsDefDesc=Define here the new permissions provided by your module -MenusDefDescTooltip=The menus provided by your module/application are defined into the array $this->menus into the module descriptor file. You can edit manually this file or use the embedded editor.

    Note: Once defined (and module re-activated), menus are also visible into the menu editor available to administrator users on %s. -DictionariesDefDescTooltip=The dictionaries provided by your module/application are defined into the array $this->dictionaries into the module descriptor file. You can edit manually this file or use the embedded editor.

    Note: Once defined (and module re-activated), dictionaries are also visible into the setup area to administrator users on %s. -PermissionsDefDescTooltip=The permissions provided by your module/application are defined into the array $this->rights into the module descriptor file. You can edit manually this file or use the embedded editor.

    Note: Once defined (and module re-activated), permissions are visible into the default permissions setup %s. -HooksDefDesc=Define in the module_parts['hooks'] property, in the module descriptor, the context of hooks you want to manage (list of contexts can be found by a search on 'initHooks(' in core code).
    Edit the hook file to add code of your hooked functions (hookable functions can be found by a search on 'executeHooks' in core code). -TriggerDefDesc=Define in the trigger file the code you want to execute for each business event executed. -SeeIDsInUse=See IDs in use in your installation -SeeReservedIDsRangeHere=See range of reserved IDs -ToolkitForDevelopers=Toolkit for Dolibarr developers -TryToUseTheModuleBuilder=If you have knowledge of SQL and PHP, you may use the native module builder wizard.
    Enable the module %s and use the wizard by clicking the on the top right menu.
    Warning: This is an advanced developer feature, do not experiment on your production site! -SeeTopRightMenu=See on the top right menu -AddLanguageFile=Add language file -YouCanUseTranslationKey=You can use here a key that is the translation key found into language file (see tab "Languages") -DropTableIfEmpty=(Destroy table if empty) -TableDoesNotExists=The table %s does not exists -TableDropped=Table %s deleted -InitStructureFromExistingTable=Build the structure array string of an existing table -UseAboutPage=Disable the about page -UseDocFolder=Disable the documentation folder -UseSpecificReadme=Use a specific ReadMe -ContentOfREADMECustomized=Note: The content of the README.md file has been replaced with the specific value defined into setup of ModuleBuilder. -RealPathOfModule=Real path of module -ContentCantBeEmpty=Content of file can't be empty -WidgetDesc=You can generate and edit here the widgets that will be embedded with your module. -CSSDesc=You can generate and edit here a file with personalized CSS embedded with your module. -JSDesc=You can generate and edit here a file with personalized Javascript embedded with your module. -CLIDesc=You can generate here some command line scripts you want to provide with your module. -CLIFile=CLI File -NoCLIFile=No CLI files -UseSpecificEditorName = Use a specific editor name -UseSpecificEditorURL = Use a specific editor URL -UseSpecificFamily = Use a specific family -UseSpecificAuthor = Use a specific author -UseSpecificVersion = Use a specific initial version -IncludeRefGeneration=The reference of object must be generated automatically -IncludeRefGenerationHelp=Check this if you want to include code to manage the generation automatically of the reference -IncludeDocGeneration=I want to generate some documents from the object -IncludeDocGenerationHelp=If you check this, some code will be generated to add a "Generate document" box on the record. -ShowOnCombobox=Show value into combobox -KeyForTooltip=Key for tooltip -CSSClass=CSS for edit/create form -CSSViewClass=CSS for read form -CSSListClass=CSS for list -NotEditable=Not editable -ForeignKey=Foreign key -TypeOfFieldsHelp=Type of fields:
    varchar(99), double(24,8), real, text, html, datetime, timestamp, integer, integer:ClassName:relativepath/to/classfile.class.php[:1[:filter]] ('1' means we add a + button after the combo to create the record, 'filter' can be 'status=1 AND fk_user = __USER_ID AND entity IN (__SHARED_ENTITIES__)' for example) -AsciiToHtmlConverter=Ascii to HTML converter -AsciiToPdfConverter=Ascii to PDF converter -TableNotEmptyDropCanceled=Table not empty. Drop has been canceled. -ModuleBuilderNotAllowed=The module builder is available but not allowed to your user. -ImportExportProfiles=Import and export profiles diff --git a/htdocs/langs/ar_IQ/mrp.lang b/htdocs/langs/ar_IQ/mrp.lang deleted file mode 100644 index 2414a92cefb..00000000000 --- a/htdocs/langs/ar_IQ/mrp.lang +++ /dev/null @@ -1,103 +0,0 @@ -Mrp=Manufacturing Orders -MOs=Manufacturing orders -ManufacturingOrder=Manufacturing Order -MRPDescription=Module to manage production and Manufacturing Orders (MO). -MRPArea=MRP Area -MrpSetupPage=Setup of module MRP -MenuBOM=Bills of material -LatestBOMModified=Latest %s Bills of materials modified -LatestMOModified=Latest %s Manufacturing Orders modified -Bom=Bills of Material -BillOfMaterials=Bill of Materials -BOMsSetup=Setup of module BOM -ListOfBOMs=List of bills of material - BOM -ListOfManufacturingOrders=List of Manufacturing Orders -NewBOM=New bill of materials -ProductBOMHelp=Product to create (or disassemble) with this BOM.
    Note: Products with the property 'Nature of product' = 'Raw material' are not visible into this list. -BOMsNumberingModules=BOM numbering templates -BOMsModelModule=BOM document templates -MOsNumberingModules=MO numbering templates -MOsModelModule=MO document templates -FreeLegalTextOnBOMs=Free text on document of BOM -WatermarkOnDraftBOMs=Watermark on draft BOM -FreeLegalTextOnMOs=Free text on document of MO -WatermarkOnDraftMOs=Watermark on draft MO -ConfirmCloneBillOfMaterials=Are you sure you want to clone the bill of materials %s ? -ConfirmCloneMo=Are you sure you want to clone the Manufacturing Order %s ? -ManufacturingEfficiency=Manufacturing efficiency -ConsumptionEfficiency=Consumption efficiency -ValueOfMeansLoss=Value of 0.95 means an average of 5%% of loss during the production -ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss of produced product -DeleteBillOfMaterials=Delete Bill Of Materials -DeleteMo=Delete Manufacturing Order -ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? -MenuMRP=Manufacturing Orders -NewMO=New Manufacturing Order -QtyToProduce=Qty to produce -DateStartPlannedMo=Date start planned -DateEndPlannedMo=Date end planned -KeepEmptyForAsap=Empty means 'As Soon As Possible' -EstimatedDuration=Estimated duration -EstimatedDurationDesc=Estimated duration to manufacture (or disassemble) this product using this BOM -ConfirmValidateBom=Are you sure you want to validate the BOM with the reference %s (you will be able to use it to build new Manufacturing Orders) -ConfirmCloseBom=Are you sure you want to cancel this BOM (you won't be able to use it to build new Manufacturing Orders anymore) ? -ConfirmReopenBom=Are you sure you want to re-open this BOM (you will be able to use it to build new Manufacturing Orders) -StatusMOProduced=Produced -QtyFrozen=Frozen Qty -QuantityFrozen=Frozen Quantity -QuantityConsumedInvariable=When this flag is set, the quantity consumed is always the value defined and is not relative to the quantity produced. -DisableStockChange=Stock change disabled -DisableStockChangeHelp=When this flag is set, there is no stock change on this product, whatever is the quantity consumed -BomAndBomLines=Bills Of Material and lines -BOMLine=Line of BOM -WarehouseForProduction=Warehouse for production -CreateMO=Create MO -ToConsume=To consume -ToProduce=To produce -QtyAlreadyConsumed=Qty already consumed -QtyAlreadyProduced=Qty already produced -QtyRequiredIfNoLoss=Qty required if there is no loss (Manufacturing efficiency is 100%%) -ConsumeOrProduce=Consume or Produce -ConsumeAndProduceAll=Consume and Produce All -Manufactured=Manufactured -TheProductXIsAlreadyTheProductToProduce=The product to add is already the product to produce. -ForAQuantityOf=For a quantity to produce of %s -ForAQuantityToConsumeOf=For a quantity to disassemble of %s -ConfirmValidateMo=Are you sure you want to validate this Manufacturing Order? -ConfirmProductionDesc=By clicking on '%s', you will validate the consumption and/or production for the quantities set. This will also update the stock and record stock movements. -ProductionForRef=Production of %s -AutoCloseMO=Close automatically the Manufacturing Order if quantities to consume and to produce are reached -NoStockChangeOnServices=No stock change on services -ProductQtyToConsumeByMO=Product quantity still to consume by open MO -ProductQtyToProduceByMO=Product quantity still to produce by open MO -AddNewConsumeLines=Add new line to consume -ProductsToConsume=Products to consume -ProductsToProduce=Products to produce -UnitCost=Unit cost -TotalCost=Total cost -BOMTotalCost=The cost to produce this BOM based on cost of each quantity and product to consume (use Cost price if defined, else Average Weighted Price if defined, else the Best purchase price) -GoOnTabProductionToProduceFirst=You must first have started the production to close a Manufacturing Order (See tab '%s'). But you can Cancel it. -ErrorAVirtualProductCantBeUsedIntoABomOrMo=A kit can't be used into a BOM or a MO -Workstation=Workstation -Workstations=Workstations -WorkstationsDescription=Workstations management -WorkstationSetup = Workstations setup -WorkstationSetupPage = Workstations setup page -WorkstationList=Workstation list -WorkstationCreate=Add new workstation -ConfirmEnableWorkstation=Are you sure you want to enable workstation %s ? -EnableAWorkstation=Enable a workstation -ConfirmDisableWorkstation=Are you sure you want to disable workstation %s ? -DisableAWorkstation=Disable a workstation -DeleteWorkstation=Delete -NbOperatorsRequired=Number of operators required -THMOperatorEstimated=Estimated operator THM -THMMachineEstimated=Estimated machine THM -WorkstationType=Workstation type -Human=Human -Machine=Machine -HumanMachine=Human / Machine -WorkstationArea=Workstation area -Machines=Machines -THMEstimatedHelp=This rate makes it possible to define a forecast cost of the item diff --git a/htdocs/langs/ar_IQ/multicurrency.lang b/htdocs/langs/ar_IQ/multicurrency.lang deleted file mode 100644 index 26313c6bfb9..00000000000 --- a/htdocs/langs/ar_IQ/multicurrency.lang +++ /dev/null @@ -1,38 +0,0 @@ -# Dolibarr language file - Source file is en_US - multicurrency -MultiCurrency=Multi currency -ErrorAddRateFail=Error in added rate -ErrorAddCurrencyFail=Error in added currency -ErrorDeleteCurrencyFail=Error delete fail -multicurrency_syncronize_error=Synchronization error: %s -MULTICURRENCY_USE_RATE_ON_DOCUMENT_DATE=Use the date of the document to find the currency rate, instead of using the latest known rate -multicurrency_useOriginTx=When an object is created from another, keep the original rate from the source object (otherwise use the latest known rate) -CurrencyLayerAccount=CurrencyLayer API -CurrencyLayerAccount_help_to_synchronize=You must create an account on website %s to use this functionality.
    Get your API key.
    If you use a free account, you can't change the source currency (USD by default).
    If your main currency is not USD, the application will automatically recalculate it.

    You are limited to 1000 synchronizations per month. -multicurrency_appId=API key -multicurrency_appCurrencySource=Source currency -multicurrency_alternateCurrencySource=Alternate source currency -CurrenciesUsed=Currencies used -CurrenciesUsed_help_to_add=Add the different currencies and rates you need to use on your proposals, orders etc. -rate=rate -MulticurrencyReceived=Received, original currency -MulticurrencyRemainderToTake=Remaining amount, original currency -MulticurrencyPaymentAmount=Payment amount, original currency -AmountToOthercurrency=Amount To (in currency of receiving account) -CurrencyRateSyncSucceed=Currency rate synchronization done successfuly -MULTICURRENCY_USE_CURRENCY_ON_DOCUMENT=Use the currency of the document for online payments -TabTitleMulticurrencyRate=Rate list -ListCurrencyRate=List of exchange rates for the currency -CreateRate=Create a rate -FormCreateRate=Rate creation -FormUpdateRate=Rate modification -successRateCreate=Rate for currency %s has been added to the database -ConfirmDeleteLineRate=Are you sure you want to remove the %s rate for currency %s on %s date? -DeleteLineRate=Clear rate -successRateDelete=Rate deleted -errorRateDelete=Error when deleting the rate -successUpdateRate=Modification made -ErrorUpdateRate=Error when changing the rate -Codemulticurrency=currency code -UpdateRate=change the rate -CancelUpdate=cancel -NoEmptyRate=The rate field must not be empty diff --git a/htdocs/langs/ar_IQ/oauth.lang b/htdocs/langs/ar_IQ/oauth.lang deleted file mode 100644 index 075ff49a895..00000000000 --- a/htdocs/langs/ar_IQ/oauth.lang +++ /dev/null @@ -1,32 +0,0 @@ -# Dolibarr language file - Source file is en_US - oauth -ConfigOAuth=OAuth Configuration -OAuthServices=OAuth Services -ManualTokenGeneration=Manual token generation -TokenManager=Token Manager -IsTokenGenerated=Is token generated ? -NoAccessToken=No access token saved into local database -HasAccessToken=A token was generated and saved into local database -NewTokenStored=Token received and saved -ToCheckDeleteTokenOnProvider=Click here to check/delete authorization saved by %s OAuth provider -TokenDeleted=Token deleted -RequestAccess=Click here to request/renew access and receive a new token to save -DeleteAccess=Click here to delete token -UseTheFollowingUrlAsRedirectURI=Use the following URL as the Redirect URI when creating your credentials with your OAuth provider: -ListOfSupportedOauthProviders=Enter the credentials provided by your OAuth2 provider. Only supported OAuth2 providers are listedd here. These services may be used by other modules that need OAuth2 authentication. -OAuthSetupForLogin=Page to generate an OAuth token -SeePreviousTab=See previous tab -OAuthIDSecret=OAuth ID and Secret -TOKEN_REFRESH=Token Refresh Present -TOKEN_EXPIRED=Token expired -TOKEN_EXPIRE_AT=Token expire at -TOKEN_DELETE=Delete saved token -OAUTH_GOOGLE_NAME=OAuth Google service -OAUTH_GOOGLE_ID=OAuth Google Id -OAUTH_GOOGLE_SECRET=OAuth Google Secret -OAUTH_GOOGLE_DESC=Go to this page then "Credentials" to create OAuth credentials -OAUTH_GITHUB_NAME=OAuth GitHub service -OAUTH_GITHUB_ID=OAuth GitHub Id -OAUTH_GITHUB_SECRET=OAuth GitHub Secret -OAUTH_GITHUB_DESC=Go to this page then "Register a new application" to create OAuth credentials -OAUTH_STRIPE_TEST_NAME=OAuth Stripe Test -OAUTH_STRIPE_LIVE_NAME=OAuth Stripe Live diff --git a/htdocs/langs/ar_IQ/opensurvey.lang b/htdocs/langs/ar_IQ/opensurvey.lang deleted file mode 100644 index 7d26151fa16..00000000000 --- a/htdocs/langs/ar_IQ/opensurvey.lang +++ /dev/null @@ -1,61 +0,0 @@ -# Dolibarr language file - Source file is en_US - opensurvey -Survey=Poll -Surveys=Polls -OrganizeYourMeetingEasily=Organize your meetings and polls easily. First select the type of poll... -NewSurvey=New poll -OpenSurveyArea=Polls area -AddACommentForPoll=You can add a comment into poll... -AddComment=Add comment -CreatePoll=Create poll -PollTitle=Poll title -ToReceiveEMailForEachVote=Receive an email for each vote -TypeDate=Type date -TypeClassic=Type standard -OpenSurveyStep2=Select your dates among the free days (grey). The selected days are green. You can unselect a day previously selected by clicking again on it -RemoveAllDays=Remove all days -CopyHoursOfFirstDay=Copy hours of first day -RemoveAllHours=Remove all hours -SelectedDays=Selected days -TheBestChoice=The best choice currently is -TheBestChoices=The best choices currently are -with=with -OpenSurveyHowTo=If you agree to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line. -CommentsOfVoters=Comments of voters -ConfirmRemovalOfPoll=Are you sure you want to remove this poll (and all votes) -RemovePoll=Remove poll -UrlForSurvey=URL to communicate to get a direct access to poll -PollOnChoice=You are creating a poll to make a multi-choice for a poll. First enter all possible choices for your poll: -CreateSurveyDate=Create a date poll -CreateSurveyStandard=Create a standard poll -CheckBox=Simple checkbox -YesNoList=List (empty/yes/no) -PourContreList=List (empty/for/against) -AddNewColumn=Add new column -TitleChoice=Choice label -ExportSpreadsheet=Export result spreadsheet -ExpireDate=Limit date -NbOfSurveys=Number of polls -NbOfVoters=No. of voters -SurveyResults=Results -PollAdminDesc=You are allowed to change all vote lines of this poll with button "Edit". You can, as well, remove a column or a line with %s. You can also add a new column with %s. -5MoreChoices=5 more choices -Against=Against -YouAreInivitedToVote=You are invited to vote for this poll -VoteNameAlreadyExists=This name was already used for this poll -AddADate=Add a date -AddStartHour=Add start hour -AddEndHour=Add end hour -votes=vote(s) -NoCommentYet=No comments have been posted for this poll yet -CanComment=Voters can comment in the poll -CanSeeOthersVote=Voters can see other people's vote -SelectDayDesc=For each selected day, you can choose, or not, meeting hours in the following format:
    - empty,
    - "8h", "8H" or "8:00" to give a meeting's start hour,
    - "8-11", "8h-11h", "8H-11H" or "8:00-11:00" to give a meeting's start and end hour,
    - "8h15-11h15", "8H15-11H15" or "8:15-11:15" for the same thing but with minutes. -BackToCurrentMonth=Back to current month -ErrorOpenSurveyFillFirstSection=You haven't filled the first section of the poll creation -ErrorOpenSurveyOneChoice=Enter at least one choice -ErrorInsertingComment=There was an error while inserting your comment -MoreChoices=Enter more choices for the voters -SurveyExpiredInfo=The poll has been closed or voting delay has expired. -EmailSomeoneVoted=%s has filled a line.\nYou can find your poll at the link: \n%s -ShowSurvey=Show survey -UserMustBeSameThanUserUsedToVote=You must have voted and use the same user name that the one used to vote, to post a comment diff --git a/htdocs/langs/ar_IQ/orders.lang b/htdocs/langs/ar_IQ/orders.lang index 5dab5b99bf1..90fedaf49f7 100644 --- a/htdocs/langs/ar_IQ/orders.lang +++ b/htdocs/langs/ar_IQ/orders.lang @@ -1,193 +1,2 @@ # Dolibarr language file - Source file is en_US - orders -OrdersArea=Customers orders area -SuppliersOrdersArea=Purchase orders area -OrderCard=Order card -OrderId=Order Id -Order=Order -PdfOrderTitle=Order -Orders=Orders -OrderLine=Order line -OrderDate=Order date -OrderDateShort=Order date -OrderToProcess=Order to process -NewOrder=New order -NewSupplierOrderShort=New order -NewOrderSupplier=New Purchase Order -ToOrder=Make order -MakeOrder=Make order -SupplierOrder=Purchase order -SuppliersOrders=Purchase orders SaleOrderLines=Sale order lines -PurchaseOrderLines=Puchase order lines -SuppliersOrdersRunning=Current purchase orders -CustomerOrder=Sales Order -CustomersOrders=Sales Orders -CustomersOrdersRunning=Current sales orders -CustomersOrdersAndOrdersLines=Sales orders and order details -OrdersDeliveredToBill=Sales orders delivered to bill -OrdersToBill=Sales orders delivered -OrdersInProcess=Sales orders in process -OrdersToProcess=Sales orders to process -SuppliersOrdersToProcess=Purchase orders to process -SuppliersOrdersAwaitingReception=Purchase orders awaiting reception -AwaitingReception=Awaiting reception -StatusOrderCanceledShort=Canceled -StatusOrderDraftShort=Draft -StatusOrderValidatedShort=Validated -StatusOrderSentShort=In process -StatusOrderSent=Shipment in process -StatusOrderOnProcessShort=Ordered -StatusOrderProcessedShort=Processed -StatusOrderDelivered=Delivered -StatusOrderDeliveredShort=Delivered -StatusOrderToBillShort=Delivered -StatusOrderApprovedShort=Approved -StatusOrderRefusedShort=Refused -StatusOrderToProcessShort=To process -StatusOrderReceivedPartiallyShort=Partially received -StatusOrderReceivedAllShort=Products received -StatusOrderCanceled=Canceled -StatusOrderDraft=Draft (needs to be validated) -StatusOrderValidated=Validated -StatusOrderOnProcess=Ordered - Standby reception -StatusOrderOnProcessWithValidation=Ordered - Standby reception or validation -StatusOrderProcessed=Processed -StatusOrderToBill=Delivered -StatusOrderApproved=Approved -StatusOrderRefused=Refused -StatusOrderReceivedPartially=Partially received -StatusOrderReceivedAll=All products received -ShippingExist=A shipment exists -QtyOrdered=Qty ordered -ProductQtyInDraft=Product quantity into draft orders -ProductQtyInDraftOrWaitingApproved=Product quantity into draft or approved orders, not yet ordered -MenuOrdersToBill=Orders delivered -MenuOrdersToBill2=Billable orders -ShipProduct=Ship product -CreateOrder=Create Order -RefuseOrder=Refuse order -ApproveOrder=Approve order -Approve2Order=Approve order (second level) -ValidateOrder=Validate order -UnvalidateOrder=Unvalidate order -DeleteOrder=Delete order -CancelOrder=Cancel order -OrderReopened= Order %s re-open -AddOrder=Create order -AddSupplierOrderShort=Create order -AddPurchaseOrder=Create purchase order -AddToDraftOrders=Add to draft order -ShowOrder=Show order -OrdersOpened=Orders to process -NoDraftOrders=No draft orders -NoOrder=No order -NoSupplierOrder=No purchase order -LastOrders=Latest %s sales orders -LastCustomerOrders=Latest %s sales orders -LastSupplierOrders=Latest %s purchase orders -LastModifiedOrders=Latest %s modified orders -AllOrders=All orders -NbOfOrders=Number of orders -OrdersStatistics=Order's statistics -OrdersStatisticsSuppliers=Purchase order statistics -NumberOfOrdersByMonth=Number of orders by month -AmountOfOrdersByMonthHT=Amount of orders by month (excl. tax) -ListOfOrders=List of orders -CloseOrder=Close order -ConfirmCloseOrder=Are you sure you want to set this order to delivered? Once an order is delivered, it can be set to billed. -ConfirmDeleteOrder=Are you sure you want to delete this order? -ConfirmValidateOrder=Are you sure you want to validate this order under name %s? -ConfirmUnvalidateOrder=Are you sure you want to restore order %s to draft status? -ConfirmCancelOrder=Are you sure you want to cancel this order? -ConfirmMakeOrder=Are you sure you want to confirm you made this order on %s? -GenerateBill=Generate invoice -ClassifyShipped=Classify delivered -DraftOrders=Draft orders -DraftSuppliersOrders=Draft purchase orders -OnProcessOrders=In process orders -RefOrder=Ref. order -RefCustomerOrder=Ref. order for customer -RefOrderSupplier=Ref. order for vendor -RefOrderSupplierShort=Ref. order vendor -SendOrderByMail=Send order by mail -ActionsOnOrder=Events on order -NoArticleOfTypeProduct=No article of type 'product' so no shippable article for this order -OrderMode=Order method -AuthorRequest=Request author -UserWithApproveOrderGrant=Users granted with "approve orders" permission. -PaymentOrderRef=Payment of order %s -ConfirmCloneOrder=Are you sure you want to clone this order %s? -DispatchSupplierOrder=Receiving purchase order %s -FirstApprovalAlreadyDone=First approval already done -SecondApprovalAlreadyDone=Second approval already done -SupplierOrderReceivedInDolibarr=Purchase Order %s received %s -SupplierOrderSubmitedInDolibarr=Purchase Order %s submitted -SupplierOrderClassifiedBilled=Purchase Order %s set billed -OtherOrders=Other orders -##### Types de contacts ##### -TypeContact_commande_internal_SALESREPFOLL=Representative following-up sales order -TypeContact_commande_internal_SHIPPING=Representative following-up shipping -TypeContact_commande_external_BILLING=Customer invoice contact -TypeContact_commande_external_SHIPPING=Customer shipping contact -TypeContact_commande_external_CUSTOMER=Customer contact following-up order -TypeContact_order_supplier_internal_SALESREPFOLL=Representative following-up purchase order -TypeContact_order_supplier_internal_SHIPPING=Representative following-up shipping -TypeContact_order_supplier_external_BILLING=Vendor invoice contact -TypeContact_order_supplier_external_SHIPPING=Vendor shipping contact -TypeContact_order_supplier_external_CUSTOMER=Vendor contact following-up order -Error_COMMANDE_SUPPLIER_ADDON_NotDefined=Constant COMMANDE_SUPPLIER_ADDON not defined -Error_COMMANDE_ADDON_NotDefined=Constant COMMANDE_ADDON not defined -Error_OrderNotChecked=No orders to invoice selected -# Order modes (how we receive order). Not the "why" are keys stored into dict.lang -OrderByMail=Mail -OrderByFax=Fax -OrderByEMail=Email -OrderByWWW=Online -OrderByPhone=Phone -# Documents models -PDFEinsteinDescription=A complete order model (old implementation of Eratosthene template) -PDFEratostheneDescription=A complete order model -PDFEdisonDescription=A simple order model -PDFProformaDescription=A complete Proforma invoice template -CreateInvoiceForThisCustomer=Bill orders -CreateInvoiceForThisSupplier=Bill orders -NoOrdersToInvoice=No orders billable -CloseProcessedOrdersAutomatically=Classify "Processed" all selected orders. -OrderCreation=Order creation -Ordered=Ordered -OrderCreated=Your orders have been created -OrderFail=An error happened during your orders creation -CreateOrders=Create orders -ToBillSeveralOrderSelectCustomer=To create an invoice for several orders, click first onto customer, then choose "%s". -OptionToSetOrderBilledNotEnabled=Option from module Workflow, to set order to 'Billed' automatically when invoice is validated, is not enabled, so you will have to set the status of orders to 'Billed' manually after the invoice has been generated. -IfValidateInvoiceIsNoOrderStayUnbilled=If invoice validation is 'No', the order will remain to status 'Unbilled' until the invoice is validated. -CloseReceivedSupplierOrdersAutomatically=Close order to status "%s" automatically if all products are received. -SetShippingMode=Set shipping mode -WithReceptionFinished=With reception finished -#### supplier orders status -StatusSupplierOrderCanceledShort=Canceled -StatusSupplierOrderDraftShort=Draft -StatusSupplierOrderValidatedShort=Validated -StatusSupplierOrderSentShort=In process -StatusSupplierOrderSent=Shipment in process -StatusSupplierOrderOnProcessShort=Ordered -StatusSupplierOrderProcessedShort=Processed -StatusSupplierOrderDelivered=Delivered -StatusSupplierOrderDeliveredShort=Delivered -StatusSupplierOrderToBillShort=Delivered -StatusSupplierOrderApprovedShort=Approved -StatusSupplierOrderRefusedShort=Refused -StatusSupplierOrderToProcessShort=To process -StatusSupplierOrderReceivedPartiallyShort=Partially received -StatusSupplierOrderReceivedAllShort=Products received -StatusSupplierOrderCanceled=Canceled -StatusSupplierOrderDraft=Draft (needs to be validated) -StatusSupplierOrderValidated=Validated -StatusSupplierOrderOnProcess=Ordered - Standby reception -StatusSupplierOrderOnProcessWithValidation=Ordered - Standby reception or validation -StatusSupplierOrderProcessed=Processed -StatusSupplierOrderToBill=Delivered -StatusSupplierOrderApproved=Approved -StatusSupplierOrderRefused=Refused -StatusSupplierOrderReceivedPartially=Partially received -StatusSupplierOrderReceivedAll=All products received diff --git a/htdocs/langs/ar_IQ/other.lang b/htdocs/langs/ar_IQ/other.lang deleted file mode 100644 index ea280968ef4..00000000000 --- a/htdocs/langs/ar_IQ/other.lang +++ /dev/null @@ -1,297 +0,0 @@ -# Dolibarr language file - Source file is en_US - other -SecurityCode=Security code -NumberingShort=N° -Tools=Tools -TMenuTools=Tools -ToolsDesc=All tools not included in other menu entries are grouped here.
    All the tools can be accessed via the left menu. -Birthday=Birthday -BirthdayAlertOn=birthday alert active -BirthdayAlertOff=birthday alert inactive -TransKey=Translation of the key TransKey -MonthOfInvoice=Month (number 1-12) of invoice date -TextMonthOfInvoice=Month (text) of invoice date -PreviousMonthOfInvoice=Previous month (number 1-12) of invoice date -TextPreviousMonthOfInvoice=Previous month (text) of invoice date -NextMonthOfInvoice=Following month (number 1-12) of invoice date -TextNextMonthOfInvoice=Following month (text) of invoice date -PreviousMonth=Previous month -CurrentMonth=Current month -ZipFileGeneratedInto=Zip file generated into %s. -DocFileGeneratedInto=Doc file generated into %s. -JumpToLogin=Disconnected. Go to login page... -MessageForm=Message on online payment form -MessageOK=Message on the return page for a validated payment -MessageKO=Message on the return page for a canceled payment -ContentOfDirectoryIsNotEmpty=Content of this directory is not empty. -DeleteAlsoContentRecursively=Check to delete all content recursively -PoweredBy=Powered by -YearOfInvoice=Year of invoice date -PreviousYearOfInvoice=Previous year of invoice date -NextYearOfInvoice=Following year of invoice date -DateNextInvoiceBeforeGen=Date of next invoice (before generation) -DateNextInvoiceAfterGen=Date of next invoice (after generation) -GraphInBarsAreLimitedToNMeasures=Grapics are limited to %s measures in 'Bars' mode. The mode 'Lines' was automatically selected instead. -OnlyOneFieldForXAxisIsPossible=Only 1 field is currently possible as X-Axis. Only the first selected field has been selected. -AtLeastOneMeasureIsRequired=At least 1 field for measure is required -AtLeastOneXAxisIsRequired=At least 1 field for X-Axis is required -LatestBlogPosts=Latest Blog Posts -Notify_ORDER_VALIDATE=Sales order validated -Notify_ORDER_SENTBYMAIL=Sales order sent by mail -Notify_ORDER_SUPPLIER_SENTBYMAIL=Purchase order sent by email -Notify_ORDER_SUPPLIER_VALIDATE=Purchase order recorded -Notify_ORDER_SUPPLIER_APPROVE=Purchase order approved -Notify_ORDER_SUPPLIER_REFUSE=Purchase order refused -Notify_PROPAL_VALIDATE=Customer proposal validated -Notify_PROPAL_CLOSE_SIGNED=Customer proposal closed signed -Notify_PROPAL_CLOSE_REFUSED=Customer proposal closed refused -Notify_PROPAL_SENTBYMAIL=Commercial proposal sent by mail -Notify_WITHDRAW_TRANSMIT=Transmission withdrawal -Notify_WITHDRAW_CREDIT=Credit withdrawal -Notify_WITHDRAW_EMIT=Perform withdrawal -Notify_COMPANY_CREATE=Third party created -Notify_COMPANY_SENTBYMAIL=Mails sent from third party card -Notify_BILL_VALIDATE=Customer invoice validated -Notify_BILL_UNVALIDATE=Customer invoice unvalidated -Notify_BILL_PAYED=Customer invoice paid -Notify_BILL_CANCEL=Customer invoice canceled -Notify_BILL_SENTBYMAIL=Customer invoice sent by mail -Notify_BILL_SUPPLIER_VALIDATE=Vendor invoice validated -Notify_BILL_SUPPLIER_PAYED=Vendor invoice paid -Notify_BILL_SUPPLIER_SENTBYMAIL=Vendor invoice sent by mail -Notify_BILL_SUPPLIER_CANCELED=Vendor invoice cancelled -Notify_CONTRACT_VALIDATE=Contract validated -Notify_FICHINTER_VALIDATE=Intervention validated -Notify_FICHINTER_ADD_CONTACT=Added contact to Intervention -Notify_FICHINTER_SENTBYMAIL=Intervention sent by mail -Notify_SHIPPING_VALIDATE=Shipping validated -Notify_SHIPPING_SENTBYMAIL=Shipping sent by mail -Notify_MEMBER_VALIDATE=Member validated -Notify_MEMBER_MODIFY=Member modified -Notify_MEMBER_SUBSCRIPTION=Member subscribed -Notify_MEMBER_RESILIATE=Member terminated -Notify_MEMBER_DELETE=Member deleted -Notify_PROJECT_CREATE=Project creation -Notify_TASK_CREATE=Task created -Notify_TASK_MODIFY=Task modified -Notify_TASK_DELETE=Task deleted -Notify_EXPENSE_REPORT_VALIDATE=Expense report validated (approval required) -Notify_EXPENSE_REPORT_APPROVE=Expense report approved -Notify_HOLIDAY_VALIDATE=Leave request validated (approval required) -Notify_HOLIDAY_APPROVE=Leave request approved -Notify_ACTION_CREATE=Added action to Agenda -SeeModuleSetup=See setup of module %s -NbOfAttachedFiles=Number of attached files/documents -TotalSizeOfAttachedFiles=Total size of attached files/documents -MaxSize=Maximum size -AttachANewFile=Attach a new file/document -LinkedObject=Linked object -NbOfActiveNotifications=Number of notifications (no. of recipient emails) -PredefinedMailTest=__(Hello)__\nThis is a test mail sent to __EMAIL__.\nThe lines are separated by a carriage return.\n\n__USER_SIGNATURE__ -PredefinedMailTestHtml=__(Hello)__
    This is a test mail sent to __EMAIL__ (the word test must be in bold).
    The lines are separated by a carriage return.

    __USER_SIGNATURE__ -PredefinedMailContentContract=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendInvoice=__(Hello)__\n\nPlease find invoice __REF__ attached \n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendInvoiceReminder=__(Hello)__\n\nWe would like to remind you that the invoice __REF__ seems to have not been paid. A copy of the invoice is attached as a reminder.\n\n__ONLINE_PAYMENT_TEXT_AND_URL__\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendProposal=__(Hello)__\n\nPlease find commercial proposal __REF__ attached \n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendSupplierProposal=__(Hello)__\n\nPlease find price request __REF__ attached\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendOrder=__(Hello)__\n\nPlease find order __REF__ attached\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendSupplierOrder=__(Hello)__\n\nPlease find our order __REF__ attached\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendSupplierInvoice=__(Hello)__\n\nPlease find invoice __REF__ attached\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendShipping=__(Hello)__\n\nPlease find shipping __REF__ attached\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendFichInter=__(Hello)__\n\nPlease find intervention __REF__ attached\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentLink=You can click on the link below to make your payment if it is not already done.\n\n%s\n\n -PredefinedMailContentGeneric=__(Hello)__\n\n\n__(Sincerely)__\n\n__USER_SIGNATURE__ -PredefinedMailContentSendActionComm=Event reminder "__EVENT_LABEL__" on __EVENT_DATE__ at __EVENT_TIME__

    This is an automatic message, please do not reply. -DemoDesc=Dolibarr is a compact ERP/CRM supporting several business modules. A demo showcasing all modules makes no sense as this scenario never occurs (several hundred available). So, several demo profiles are available. -ChooseYourDemoProfil=Choose the demo profile that best suits your needs... -ChooseYourDemoProfilMore=...or build your own profile
    (manual module selection) -DemoFundation=Manage members of a foundation -DemoFundation2=Manage members and bank account of a foundation -DemoCompanyServiceOnly=Company or freelance selling service only -DemoCompanyShopWithCashDesk=Manage a shop with a cash desk -DemoCompanyProductAndStocks=Shop selling products with Point Of Sales -DemoCompanyManufacturing=Company manufacturing products -DemoCompanyAll=Company with multiple activities (all main modules) -CreatedBy=Created by %s -ModifiedBy=Modified by %s -ValidatedBy=Validated by %s -SignedBy=Signed by %s -ClosedBy=Closed by %s -CreatedById=User id who created -ModifiedById=User id who made latest change -ValidatedById=User id who validated -CanceledById=User id who canceled -ClosedById=User id who closed -CreatedByLogin=User login who created -ModifiedByLogin=User login who made latest change -ValidatedByLogin=User login who validated -CanceledByLogin=User login who canceled -ClosedByLogin=User login who closed -FileWasRemoved=File %s was removed -DirWasRemoved=Directory %s was removed -FeatureNotYetAvailable=Feature not yet available in the current version -FeatureNotAvailableOnDevicesWithoutMouse=Feature not available on devices without mouse -FeaturesSupported=Supported features -Width=Width -Height=Height -Depth=Depth -Top=Top -Bottom=Bottom -Left=Left -Right=Right -CalculatedWeight=Calculated weight -CalculatedVolume=Calculated volume -Weight=Weight -WeightUnitton=ton -WeightUnitkg=kg -WeightUnitg=g -WeightUnitmg=mg -WeightUnitpound=pound -WeightUnitounce=ounce -Length=Length -LengthUnitm=m -LengthUnitdm=dm -LengthUnitcm=cm -LengthUnitmm=mm -Surface=Area -SurfaceUnitm2=m² -SurfaceUnitdm2=dm² -SurfaceUnitcm2=cm² -SurfaceUnitmm2=mm² -SurfaceUnitfoot2=ft² -SurfaceUnitinch2=in² -Volume=Volume -VolumeUnitm3=m³ -VolumeUnitdm3=dm³ (L) -VolumeUnitcm3=cm³ (ml) -VolumeUnitmm3=mm³ (µl) -VolumeUnitfoot3=ft³ -VolumeUnitinch3=in³ -VolumeUnitounce=ounce -VolumeUnitlitre=litre -VolumeUnitgallon=gallon -SizeUnitm=m -SizeUnitdm=dm -SizeUnitcm=cm -SizeUnitmm=mm -SizeUnitinch=inch -SizeUnitfoot=foot -SizeUnitpoint=point -BugTracker=Bug tracker -SendNewPasswordDesc=This form allows you to request a new password. It will be sent to your email address.
    Change will become effective once you click on the confirmation link in the email.
    Check your inbox. -BackToLoginPage=Back to login page -AuthenticationDoesNotAllowSendNewPassword=Authentication mode is %s.
    In this mode, Dolibarr can't know nor change your password.
    Contact your system administrator if you want to change your password. -EnableGDLibraryDesc=Install or enable GD library on your PHP installation to use this option. -ProfIdShortDesc=Prof Id %s is an information depending on third party country.
    For example, for country %s, it's code %s. -DolibarrDemo=Dolibarr ERP/CRM demo -StatsByNumberOfUnits=Statistics for sum of qty of products/services -StatsByNumberOfEntities=Statistics for number of referring entities (no. of invoices, or orders...) -NumberOfProposals=Number of proposals -NumberOfCustomerOrders=Number of sales orders -NumberOfCustomerInvoices=Number of customer invoices -NumberOfSupplierProposals=Number of vendor proposals -NumberOfSupplierOrders=Number of purchase orders -NumberOfSupplierInvoices=Number of vendor invoices -NumberOfContracts=Number of contracts -NumberOfMos=Number of manufacturing orders -NumberOfUnitsProposals=Number of units on proposals -NumberOfUnitsCustomerOrders=Number of units on sales orders -NumberOfUnitsCustomerInvoices=Number of units on customer invoices -NumberOfUnitsSupplierProposals=Number of units on vendor proposals -NumberOfUnitsSupplierOrders=Number of units on purchase orders -NumberOfUnitsSupplierInvoices=Number of units on vendor invoices -NumberOfUnitsContracts=Number of units on contracts -NumberOfUnitsMos=Number of units to produce in manufacturing orders -EMailTextInterventionAddedContact=A new intervention %s has been assigned to you. -EMailTextInterventionValidated=The intervention %s has been validated. -EMailTextInvoiceValidated=Invoice %s has been validated. -EMailTextInvoicePayed=Invoice %s has been paid. -EMailTextProposalValidated=Proposal %s has been validated. -EMailTextProposalClosedSigned=Proposal %s has been closed signed. -EMailTextOrderValidated=Order %s has been validated. -EMailTextOrderApproved=Order %s has been approved. -EMailTextOrderValidatedBy=Order %s has been recorded by %s. -EMailTextOrderApprovedBy=Order %s has been approved by %s. -EMailTextOrderRefused=Order %s has been refused. -EMailTextOrderRefusedBy=Order %s has been refused by %s. -EMailTextExpeditionValidated=Shipping %s has been validated. -EMailTextExpenseReportValidated=Expense report %s has been validated. -EMailTextExpenseReportApproved=Expense report %s has been approved. -EMailTextHolidayValidated=Leave request %s has been validated. -EMailTextHolidayApproved=Leave request %s has been approved. -EMailTextActionAdded=The action %s has been added to the Agenda. -ImportedWithSet=Importation data set -DolibarrNotification=Automatic notification -ResizeDesc=Enter new width OR new height. Ratio will be kept during resizing... -NewLength=New width -NewHeight=New height -NewSizeAfterCropping=New size after cropping -DefineNewAreaToPick=Define new area on image to pick (left click on image then drag until you reach the opposite corner) -CurrentInformationOnImage=This tool was designed to help you to resize or crop an image. This is the information on the current edited image -ImageEditor=Image editor -YouReceiveMailBecauseOfNotification=You receive this message because your email has been added to list of targets to be informed of particular events into %s software of %s. -YouReceiveMailBecauseOfNotification2=This event is the following: -ThisIsListOfModules=This is a list of modules preselected by this demo profile (only most common modules are visible in this demo). Edit this to have a more personalized demo and click on "Start". -UseAdvancedPerms=Use the advanced permissions of some modules -FileFormat=File format -SelectAColor=Choose a color -AddFiles=Add Files -StartUpload=Start upload -CancelUpload=Cancel upload -FileIsTooBig=Files is too big -PleaseBePatient=Please be patient... -NewPassword=New password -ResetPassword=Reset password -RequestToResetPasswordReceived=A request to change your password has been received. -NewKeyIs=This is your new keys to login -NewKeyWillBe=Your new key to login to software will be -ClickHereToGoTo=Click here to go to %s -YouMustClickToChange=You must however first click on the following link to validate this password change -ConfirmPasswordChange=Confirm password change -ForgetIfNothing=If you didn't request this change, just forget this email. Your credentials are kept safe. -IfAmountHigherThan=If amount higher than %s -SourcesRepository=Repository for sources -Chart=Chart -PassEncoding=Password encoding -PermissionsAdd=Permissions added -PermissionsDelete=Permissions removed -YourPasswordMustHaveAtLeastXChars=Your password must have at least %s chars -YourPasswordHasBeenReset=Your password has been reset successfully -ApplicantIpAddress=IP address of applicant -SMSSentTo=SMS sent to %s -MissingIds=Missing ids -ThirdPartyCreatedByEmailCollector=Third party created by email collector from email MSGID %s -ContactCreatedByEmailCollector=Contact/address created by email collector from email MSGID %s -ProjectCreatedByEmailCollector=Project created by email collector from email MSGID %s -TicketCreatedByEmailCollector=Ticket created by email collector from email MSGID %s -OpeningHoursFormatDesc=Use a - to separate opening and closing hours.
    Use a space to enter different ranges.
    Example: 8-12 14-18 -SuffixSessionName=Suffix for session name - -##### Export ##### -ExportsArea=Exports area -AvailableFormats=Available formats -LibraryUsed=Library used -LibraryVersion=Library version -ExportableDatas=Exportable data -NoExportableData=No exportable data (no modules with exportable data loaded, or missing permissions) -##### External sites ##### -WebsiteSetup=Setup of module website -WEBSITE_PAGEURL=URL of page -WEBSITE_TITLE=Title -WEBSITE_DESCRIPTION=Description -WEBSITE_IMAGE=Image -WEBSITE_IMAGEDesc=Relative path of the image media. You can keep this empty as this is rarely used (it can be used by dynamic content to show a thumbnail in a list of blog posts). Use __WEBSITE_KEY__ in the path if path depends on website name (for example: image/__WEBSITE_KEY__/stories/myimage.png). -WEBSITE_KEYWORDS=Keywords -LinesToImport=Lines to import - -MemoryUsage=Memory usage -RequestDuration=Duration of request -ProductsPerPopularity=Products/Services by popularity -PopuProp=Products/Services by popularity in Proposals -PopuCom=Products/Services by popularity in Orders -ProductStatistics=Products/Services Statistics -NbOfQtyInOrders=Qty in orders -SelectTheTypeOfObjectToAnalyze=Select an object to view its statistics... - -ConfirmBtnCommonContent = Are you sure you want to "%s" ? -ConfirmBtnCommonTitle = Confirm your action -CloseDialog = Close diff --git a/htdocs/langs/ar_IQ/partnership.lang b/htdocs/langs/ar_IQ/partnership.lang deleted file mode 100644 index 606c3a0df3b..00000000000 --- a/htdocs/langs/ar_IQ/partnership.lang +++ /dev/null @@ -1,91 +0,0 @@ -# Copyright (C) 2021 NextGestion -# -# 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 . - -# -# Generic -# -ModulePartnershipName=Partnership management -PartnershipDescription=Module Partnership management -PartnershipDescriptionLong= Module Partnership management - -AddPartnership=Add partnership -CancelPartnershipForExpiredMembers=Partnership: Cancel partnership of members with expired subscriptions -PartnershipCheckBacklink=Partnership: Check referring backlink - -# -# Menu -# -NewPartnership=New Partnership -ListOfPartnerships=List of partnership - -# -# Admin page -# -PartnershipSetup=Partnership setup -PartnershipAbout=About Partnership -PartnershipAboutPage=Partnership about page -partnershipforthirdpartyormember=Partner status must be set on a 'thirdparty' or a 'member' -PARTNERSHIP_IS_MANAGED_FOR=Partnership managed for -PARTNERSHIP_BACKLINKS_TO_CHECK=Backlinks to check -PARTNERSHIP_NBDAYS_AFTER_MEMBER_EXPIRATION_BEFORE_CANCEL=Nb of days before cancelling status of a partnership when a subscription has expired -ReferingWebsiteCheck=Check of website referring -ReferingWebsiteCheckDesc=You can enable a feature to check that your partners has added a backlink to your website domains on their own website. - -# -# Object -# -DeletePartnership=Delete a partnership -PartnershipDedicatedToThisThirdParty=Partnership dedicated to this third party -PartnershipDedicatedToThisMember=Partnership dedicated to this member -DatePartnershipStart=Start date -DatePartnershipEnd=End date -ReasonDecline=Decline reason -ReasonDeclineOrCancel=Decline reason -PartnershipAlreadyExist=Partnership already exist -ManagePartnership=Manage partnership -BacklinkNotFoundOnPartnerWebsite=Backlink not found on partner website -ConfirmClosePartnershipAsk=Are you sure you want to cancel this partnership? -PartnershipType=Partnership type - -# -# Template Mail -# -SendingEmailOnPartnershipWillSoonBeCanceled=Partnership will soon be canceled -SendingEmailOnPartnershipRefused=Partnership refused -SendingEmailOnPartnershipAccepted=Partnership accepted -SendingEmailOnPartnershipCanceled=Partnership canceled - -YourPartnershipWillSoonBeCanceledTopic=Partnership will soon be canceled -YourPartnershipRefusedTopic=Partnership refused -YourPartnershipAcceptedTopic=Partnership accepted -YourPartnershipCanceledTopic=Partnership canceled - -YourPartnershipWillSoonBeCanceledContent=We inform you that your partnership will soon be canceled (Backlink not found) -YourPartnershipRefusedContent=We inform you that your partnership request has been refused. -YourPartnershipAcceptedContent=We inform you that your partnership request has been accepted. -YourPartnershipCanceledContent=We inform you that your partnership has been canceled. - -CountLastUrlCheckError=Number of errors for last URL check -LastCheckBacklink=Date of last URL check -ReasonDeclineOrCancel=Decline reason - -# -# Status -# -PartnershipDraft=Draft -PartnershipAccepted=Accepted -PartnershipRefused=Refused -PartnershipCanceled=Canceled -PartnershipManagedFor=Partners are diff --git a/htdocs/langs/ar_IQ/paybox.lang b/htdocs/langs/ar_IQ/paybox.lang deleted file mode 100644 index 6f320c03181..00000000000 --- a/htdocs/langs/ar_IQ/paybox.lang +++ /dev/null @@ -1,30 +0,0 @@ -# Dolibarr language file - Source file is en_US - paybox -PayBoxSetup=PayBox module setup -PayBoxDesc=This module offer pages to allow payment on Paybox by customers. This can be used for a free payment or for a payment on a particular Dolibarr object (invoice, order, ...) -FollowingUrlAreAvailableToMakePayments=Following URLs are available to offer a page to a customer to make a payment on Dolibarr objects -PaymentForm=Payment form -WelcomeOnPaymentPage=Welcome to our online payment service -ThisScreenAllowsYouToPay=This screen allow you to make an online payment to %s. -ThisIsInformationOnPayment=This is information on payment to do -ToComplete=To complete -YourEMail=Email to receive payment confirmation -Creditor=Creditor -PaymentCode=Payment code -PayBoxDoPayment=Pay with Paybox -YouWillBeRedirectedOnPayBox=You will be redirected on secured Paybox page to input you credit card information -Continue=Next -SetupPayBoxToHavePaymentCreatedAutomatically=Setup your Paybox with url %s to have payment created automatically when validated by Paybox. -YourPaymentHasBeenRecorded=This page confirms that your payment has been recorded. Thank you. -YourPaymentHasNotBeenRecorded=Your payment has NOT been recorded and the transaction has been canceled. Thank you. -AccountParameter=Account parameters -UsageParameter=Usage parameters -InformationToFindParameters=Help to find your %s account information -PAYBOX_CGI_URL_V2=Url of Paybox CGI module for payment -CSSUrlForPaymentForm=CSS style sheet url for payment form -NewPayboxPaymentReceived=New Paybox payment received -NewPayboxPaymentFailed=New Paybox payment tried but failed -PAYBOX_PAYONLINE_SENDEMAIL=Email notification after payment attempt (success or fail) -PAYBOX_PBX_SITE=Value for PBX SITE -PAYBOX_PBX_RANG=Value for PBX Rang -PAYBOX_PBX_IDENTIFIANT=Value for PBX ID -PAYBOX_HMAC_KEY=HMAC key diff --git a/htdocs/langs/ar_IQ/paypal.lang b/htdocs/langs/ar_IQ/paypal.lang deleted file mode 100644 index 5eb5f389445..00000000000 --- a/htdocs/langs/ar_IQ/paypal.lang +++ /dev/null @@ -1,36 +0,0 @@ -# Dolibarr language file - Source file is en_US - paypal -PaypalSetup=PayPal module setup -PaypalDesc=This module allows payment by customers via PayPal. This can be used for a ad-hoc payment or for a payment related to a Dolibarr object (invoice, order, ...) -PaypalOrCBDoPayment=Pay with PayPal (Card or PayPal) -PaypalDoPayment=Pay with PayPal -PAYPAL_API_SANDBOX=Mode test/sandbox -PAYPAL_API_USER=API username -PAYPAL_API_PASSWORD=API password -PAYPAL_API_SIGNATURE=API signature -PAYPAL_SSLVERSION=Curl SSL Version -PAYPAL_API_INTEGRAL_OR_PAYPALONLY=Offer "integral" payment (Credit card+PayPal) or "PayPal" only -PaypalModeIntegral=Integral -PaypalModeOnlyPaypal=PayPal only -ONLINE_PAYMENT_CSS_URL=Optional URL of CSS stylesheet on online payment page -ThisIsTransactionId=This is id of transaction: %s -PAYPAL_ADD_PAYMENT_URL=Include the PayPal payment url when you send a document by email -NewOnlinePaymentReceived=New online payment received -NewOnlinePaymentFailed=New online payment tried but failed -ONLINE_PAYMENT_SENDEMAIL=Email address for notifications after each payment attempt (for success and fail) -ReturnURLAfterPayment=Return URL after payment -ValidationOfOnlinePaymentFailed=Validation of online payment failed -PaymentSystemConfirmPaymentPageWasCalledButFailed=Payment confirmation page was called by payment system returned an error -SetExpressCheckoutAPICallFailed=SetExpressCheckout API call failed. -DoExpressCheckoutPaymentAPICallFailed=DoExpressCheckoutPayment API call failed. -DetailedErrorMessage=Detailed Error Message -ShortErrorMessage=Short Error Message -ErrorCode=Error Code -ErrorSeverityCode=Error Severity Code -OnlinePaymentSystem=Online payment system -PaypalLiveEnabled=PayPal "live" mode enabled (otherwise test/sandbox mode) -PaypalImportPayment=Import PayPal payments -PostActionAfterPayment=Post actions after payments -ARollbackWasPerformedOnPostActions=A rollback was performed on all Post actions. You must complete post actions manually if they are necessary. -ValidationOfPaymentFailed=Validation of payment has failed -CardOwner=Card holder -PayPalBalance=Paypal credit diff --git a/htdocs/langs/ar_IQ/printing.lang b/htdocs/langs/ar_IQ/printing.lang index 16494583550..55eee521013 100644 --- a/htdocs/langs/ar_IQ/printing.lang +++ b/htdocs/langs/ar_IQ/printing.lang @@ -5,50 +5,3 @@ PrintingSetup=Setup of Direct Printing System PrintingDesc=This module adds a Print button to various modules to allow documents to be printed directly to a printer without needing to open the document in another application. MenuDirectPrinting=Direct Printing jobs DirectPrint=Direct print -PrintingDriverDesc=Configuration variables for printing driver. -ListDrivers=List of drivers -PrintTestDesc=List of Printers. -FileWasSentToPrinter=File %s was sent to printer -ViaModule=via the module -NoActivePrintingModuleFound=No active driver to print document. Check setup of module %s. -PleaseSelectaDriverfromList=Please select a driver from list. -PleaseConfigureDriverfromList=Please configure the selected driver from list. -SetupDriver=Driver setup -TargetedPrinter=Targeted printer -UserConf=Setup per user -PRINTGCP_INFO=Google OAuth API setup -PRINTGCP_AUTHLINK=Authentication -PRINTGCP_TOKEN_ACCESS=Google Cloud Print OAuth Token -PrintGCPDesc=This driver allows sending documents directly to a printer using Google Cloud Print. -GCP_Name=Name -GCP_displayName=Display Name -GCP_Id=Printer Id -GCP_OwnerName=Owner Name -GCP_State=Printer State -GCP_connectionStatus=Online State -GCP_Type=Printer Type -PrintIPPDesc=This driver allows sending of documents directly to a printer. It requires a Linux system with CUPS installed. -PRINTIPP_HOST=Print server -PRINTIPP_PORT=Port -PRINTIPP_USER=Login -PRINTIPP_PASSWORD=Password -NoDefaultPrinterDefined=No default printer defined -DefaultPrinter=Default printer -Printer=Printer -IPP_Uri=Printer Uri -IPP_Name=Printer Name -IPP_State=Printer State -IPP_State_reason=State reason -IPP_State_reason1=State reason1 -IPP_BW=BW -IPP_Color=Color -IPP_Device=Device -IPP_Media=Printer media -IPP_Supported=Type of media -DirectPrintingJobsDesc=This page lists printing jobs found for available printers. -GoogleAuthNotConfigured=Google OAuth has not been setup. Enable module OAuth and set a Google ID/Secret. -GoogleAuthConfigured=Google OAuth credentials were found into setup of module OAuth. -PrintingDriverDescprintgcp=Configuration variables for printing driver Google Cloud Print. -PrintingDriverDescprintipp=Configuration variables for printing driver Cups. -PrintTestDescprintgcp=List of Printers for Google Cloud Print. -PrintTestDescprintipp=List of Printers for Cups. diff --git a/htdocs/langs/ar_IQ/productbatch.lang b/htdocs/langs/ar_IQ/productbatch.lang deleted file mode 100644 index 763af20c6b4..00000000000 --- a/htdocs/langs/ar_IQ/productbatch.lang +++ /dev/null @@ -1,43 +0,0 @@ -# ProductBATCH language file - Source file is en_US - ProductBATCH -ManageLotSerial=Use lot/serial number -ProductStatusOnBatch=Yes (lot required) -ProductStatusOnSerial=Yes (unique serial number required) -ProductStatusNotOnBatch=No (lot/serial not used) -ProductStatusOnBatchShort=Lot -ProductStatusOnSerialShort=Serial -ProductStatusNotOnBatchShort=No -Batch=Lot/Serial -atleast1batchfield=Eat-by date or Sell-by date or Lot/Serial number -batch_number=Lot/Serial number -BatchNumberShort=Lot/Serial -EatByDate=Eat-by date -SellByDate=Sell-by date -DetailBatchNumber=Lot/Serial details -printBatch=Lot/Serial: %s -printEatby=Eat-by: %s -printSellby=Sell-by: %s -printQty=Qty: %d -AddDispatchBatchLine=Add a line for Shelf Life dispatching -WhenProductBatchModuleOnOptionAreForced=When module Lot/Serial is on, automatic stock decrease is forced to 'Decrease real stocks on shipping validation' and automatic increase mode is forced to 'Increase real stocks on manual dispatching into warehouses' and can't be edited. Other options can be defined as you want. -ProductDoesNotUseBatchSerial=This product does not use lot/serial number -ProductLotSetup=Setup of module lot/serial -ShowCurrentStockOfLot=Show current stock for couple product/lot -ShowLogOfMovementIfLot=Show log of movements for couple product/lot -StockDetailPerBatch=Stock detail per lot -SerialNumberAlreadyInUse=Serial number %s is already used for product %s -TooManyQtyForSerialNumber=You can only have one product %s for serial number %s -ManageLotMask=Custom mask -CustomMasks=Option to define a different numbering mask for each product -BatchLotNumberingModules=Numbering rule for automatic generation of lot number -BatchSerialNumberingModules=Numbering rule for automatic generation of serial number (for products with property 1 unique lot/serial for each product) -QtyToAddAfterBarcodeScan=Qty to add for each barcode/lot/serial scanned -LifeTime=Life span (in days) -EndOfLife=End of life -ManufacturingDate=Manufacturing date -DestructionDate=Destruction date -FirstUseDate=First use date -QCFrequency=Quality control frequency (in days) - -#Traceability - qc status -OutOfOrder=Out of order -InWorkingOrder=In working order diff --git a/htdocs/langs/ar_IQ/products.lang b/htdocs/langs/ar_IQ/products.lang deleted file mode 100644 index bf34efe3f79..00000000000 --- a/htdocs/langs/ar_IQ/products.lang +++ /dev/null @@ -1,401 +0,0 @@ -# Dolibarr language file - Source file is en_US - products -ProductRef=Product ref. -ProductLabel=Product label -ProductLabelTranslated=Translated product label -ProductDescription=Product description -ProductDescriptionTranslated=Translated product description -ProductNoteTranslated=Translated product note -ProductServiceCard=Products/Services card -TMenuProducts=Products -TMenuServices=Services -Products=Products -Services=Services -Product=Product -Service=Service -ProductId=Product/service id -Create=Create -Reference=Reference -NewProduct=New product -NewService=New service -ProductVatMassChange=Global VAT Update -ProductVatMassChangeDesc=This tool updates the VAT rate defined on ALL products and services! -MassBarcodeInit=Mass barcode init -MassBarcodeInitDesc=This page can be used to initialize a barcode on objects that does not have barcode defined. Check before that setup of module barcode is complete. -ProductAccountancyBuyCode=Accounting code (purchase) -ProductAccountancyBuyIntraCode=Accounting code (purchase intra-community) -ProductAccountancyBuyExportCode=Accounting code (purchase import) -ProductAccountancySellCode=Accounting code (sale) -ProductAccountancySellIntraCode=Accounting code (sale intra-Community) -ProductAccountancySellExportCode=Accounting code (sale export) -ProductOrService=Product or Service -ProductsAndServices=Products and Services -ProductsOrServices=Products or Services -ProductsPipeServices=Products | Services -ProductsOnSale=Products for sale -ProductsOnPurchase=Products for purchase -ProductsOnSaleOnly=Products for sale only -ProductsOnPurchaseOnly=Products for purchase only -ProductsNotOnSell=Products not for sale and not for purchase -ProductsOnSellAndOnBuy=Products for sale and for purchase -ServicesOnSale=Services for sale -ServicesOnPurchase=Services for purchase -ServicesOnSaleOnly=Services for sale only -ServicesOnPurchaseOnly=Services for purchase only -ServicesNotOnSell=Services not for sale and not for purchase -ServicesOnSellAndOnBuy=Services for sale and for purchase -LastModifiedProductsAndServices=Latest %s products/services which were modified -LastRecordedProducts=Latest %s recorded products -LastRecordedServices=Latest %s recorded services -CardProduct0=Product -CardProduct1=Service -Stock=Stock -MenuStocks=Stocks -Stocks=Stocks and location (warehouse) of products -Movements=Movements -Sell=Sell -Buy=Purchase -OnSell=For sale -OnBuy=For purchase -NotOnSell=Not for sale -ProductStatusOnSell=For sale -ProductStatusNotOnSell=Not for sale -ProductStatusOnSellShort=For sale -ProductStatusNotOnSellShort=Not for sale -ProductStatusOnBuy=For purchase -ProductStatusNotOnBuy=Not for purchase -ProductStatusOnBuyShort=For purchase -ProductStatusNotOnBuyShort=Not for purchase -UpdateVAT=Update vat -UpdateDefaultPrice=Update default price -UpdateLevelPrices=Update prices for each level -AppliedPricesFrom=Applied from -SellingPrice=Selling price -SellingPriceHT=Selling price (excl. tax) -SellingPriceTTC=Selling price (inc. tax) -SellingMinPriceTTC=Minimum Selling price (inc. tax) -CostPriceDescription=This price field (excl. tax) can be used to capture the average amount this product costs to your company. It may be any price you calculate yourself, for example, from the average buying price plus average production and distribution cost. -CostPriceUsage=This value could be used for margin calculation. -SoldAmount=Sold amount -PurchasedAmount=Purchased amount -NewPrice=New price -MinPrice=Min. selling price -EditSellingPriceLabel=Edit selling price label -CantBeLessThanMinPrice=The selling price can't be lower than minimum allowed for this product (%s without tax). This message can also appears if you type a too important discount. -ContractStatusClosed=Closed -ErrorProductAlreadyExists=A product with reference %s already exists. -ErrorProductBadRefOrLabel=Wrong value for reference or label. -ErrorProductClone=There was a problem while trying to clone the product or service. -ErrorPriceCantBeLowerThanMinPrice=Error, price can't be lower than minimum price. -Suppliers=Vendors -SupplierRef=Vendor SKU -ShowProduct=Show product -ShowService=Show service -ProductsAndServicesArea=Product and Services area -ProductsArea=Product area -ServicesArea=Services area -ListOfStockMovements=List of stock movements -BuyingPrice=Buying price -PriceForEachProduct=Products with specific prices -SupplierCard=Vendor card -PriceRemoved=Price removed -BarCode=Barcode -BarcodeType=Barcode type -SetDefaultBarcodeType=Set barcode type -BarcodeValue=Barcode value -NoteNotVisibleOnBill=Note (not visible on invoices, proposals...) -ServiceLimitedDuration=If product is a service with limited duration: -FillWithLastServiceDates=Fill with last service line dates -MultiPricesAbility=Multiple price segments per product/service (each customer is in one price segment) -MultiPricesNumPrices=Number of prices -DefaultPriceType=Base of prices per default (with versus without tax) when adding new sale prices -AssociatedProductsAbility=Enable Kits (set of several products) -VariantsAbility=Enable Variants (variations of products, for example color, size) -AssociatedProducts=Kits -AssociatedProductsNumber=Number of products composing this kit -ParentProductsNumber=Number of parent packaging product -ParentProducts=Parent products -IfZeroItIsNotAVirtualProduct=If 0, this product is not a kit -IfZeroItIsNotUsedByVirtualProduct=If 0, this product is not used by any kit -KeywordFilter=Keyword filter -CategoryFilter=Category filter -ProductToAddSearch=Search product to add -NoMatchFound=No match found -ListOfProductsServices=List of products/services -ProductAssociationList=List of products/services that are component(s) of this kit -ProductParentList=List of kits with this product as a component -ErrorAssociationIsFatherOfThis=One of selected product is parent with current product -DeleteProduct=Delete a product/service -ConfirmDeleteProduct=Are you sure you want to delete this product/service? -ProductDeleted=Product/Service "%s" deleted from database. -ExportDataset_produit_1=Products -ExportDataset_service_1=Services -ImportDataset_produit_1=Products -ImportDataset_service_1=Services -DeleteProductLine=Delete product line -ConfirmDeleteProductLine=Are you sure you want to delete this product line? -ProductSpecial=Special -QtyMin=Min. purchase quantity -PriceQtyMin=Price quantity min. -PriceQtyMinCurrency=Price (currency) for this qty. (no discount) -VATRateForSupplierProduct=VAT Rate (for this vendor/product) -DiscountQtyMin=Discount for this qty. -NoPriceDefinedForThisSupplier=No price/qty defined for this vendor/product -NoSupplierPriceDefinedForThisProduct=No vendor price/qty defined for this product -PredefinedItem=Predefined item -PredefinedProductsToSell=Predefined Product -PredefinedServicesToSell=Predefined Service -PredefinedProductsAndServicesToSell=Predefined products/services to sell -PredefinedProductsToPurchase=Predefined product to purchase -PredefinedServicesToPurchase=Predefined services to purchase -PredefinedProductsAndServicesToPurchase=Predefined products/services to purchase -NotPredefinedProducts=Not predefined products/services -GenerateThumb=Generate thumb -ServiceNb=Service #%s -ListProductServiceByPopularity=List of products/services by popularity -ListProductByPopularity=List of products by popularity -ListServiceByPopularity=List of services by popularity -Finished=Manufactured product -RowMaterial=Raw Material -ConfirmCloneProduct=Are you sure you want to clone product or service %s? -CloneContentProduct=Clone all main information of the product/service -ClonePricesProduct=Clone prices -CloneCategoriesProduct=Clone linked tags/categories -CloneCompositionProduct=Clone virtual products/services -CloneCombinationsProduct=Clone the product variants -ProductIsUsed=This product is used -NewRefForClone=Ref. of new product/service -SellingPrices=Selling prices -BuyingPrices=Buying prices -CustomerPrices=Customer prices -SuppliersPrices=Vendor prices -SuppliersPricesOfProductsOrServices=Vendor prices (of products or services) -CustomCode=Customs|Commodity|HS code -CountryOrigin=Country of origin -RegionStateOrigin=Region of origin -StateOrigin=State|Province of origin -Nature=Nature of product (raw/manufactured) -NatureOfProductShort=Nature of product -NatureOfProductDesc=Raw material or manufactured product -ShortLabel=Short label -Unit=Unit -p=u. -set=set -se=set -second=second -s=s -hour=hour -h=h -day=day -d=d -kilogram=kilogram -kg=Kg -gram=gram -g=g -meter=meter -m=m -lm=lm -m2=m² -m3=m³ -liter=liter -l=L -unitP=Piece -unitSET=Set -unitS=Second -unitH=Hour -unitD=Day -unitG=Gram -unitM=Meter -unitLM=Linear meter -unitM2=Square meter -unitM3=Cubic meter -unitL=Liter -unitT=ton -unitKG=kg -unitG=Gram -unitMG=mg -unitLB=pound -unitOZ=ounce -unitM=Meter -unitDM=dm -unitCM=cm -unitMM=mm -unitFT=ft -unitIN=in -unitM2=Square meter -unitDM2=dm² -unitCM2=cm² -unitMM2=mm² -unitFT2=ft² -unitIN2=in² -unitM3=Cubic meter -unitDM3=dm³ -unitCM3=cm³ -unitMM3=mm³ -unitFT3=ft³ -unitIN3=in³ -unitOZ3=ounce -unitgallon=gallon -ProductCodeModel=Product ref template -ServiceCodeModel=Service ref template -CurrentProductPrice=Current price -AlwaysUseNewPrice=Always use current price of product/service -AlwaysUseFixedPrice=Use the fixed price -PriceByQuantity=Different prices by quantity -DisablePriceByQty=Disable prices by quantity -PriceByQuantityRange=Quantity range -MultipriceRules=Automatic prices for segment -UseMultipriceRules=Use price segment rules (defined into product module setup) to auto calculate prices of all other segments according to first segment -PercentVariationOver=%% variation over %s -PercentDiscountOver=%% discount over %s -KeepEmptyForAutoCalculation=Keep empty to have this calculated automatically from weight or volume of products -VariantRefExample=Examples: COL, SIZE -VariantLabelExample=Examples: Color, Size -### composition fabrication -Build=Produce -ProductsMultiPrice=Products and prices for each price segment -ProductsOrServiceMultiPrice=Customer prices (of products or services, multi-prices) -ProductSellByQuarterHT=Products turnover quarterly before tax -ServiceSellByQuarterHT=Services turnover quarterly before tax -Quarter1=1st. Quarter -Quarter2=2nd. Quarter -Quarter3=3rd. Quarter -Quarter4=4th. Quarter -BarCodePrintsheet=Print barcode -PageToGenerateBarCodeSheets=With this tool, you can print sheets of barcode stickers. Choose format of your sticker page, type of barcode and value of barcode, then click on button %s. -NumberOfStickers=Number of stickers to print on page -PrintsheetForOneBarCode=Print several stickers for one barcode -BuildPageToPrint=Generate page to print -FillBarCodeTypeAndValueManually=Fill barcode type and value manually. -FillBarCodeTypeAndValueFromProduct=Fill barcode type and value from barcode of a product. -FillBarCodeTypeAndValueFromThirdParty=Fill barcode type and value from barcode of a third party. -DefinitionOfBarCodeForProductNotComplete=Definition of type or value of barcode not complete for product %s. -DefinitionOfBarCodeForThirdpartyNotComplete=Definition of type or value of barcode non complete for third party %s. -BarCodeDataForProduct=Barcode information of product %s: -BarCodeDataForThirdparty=Barcode information of third party %s: -ResetBarcodeForAllRecords=Define barcode value for all record (this will also reset barcode value already defined with new values) -PriceByCustomer=Different prices for each customer -PriceCatalogue=A single sell price per product/service -PricingRule=Rules for selling prices -AddCustomerPrice=Add price by customer -ForceUpdateChildPriceSoc=Set same price on customer's subsidiaries -PriceByCustomerLog=Log of previous customer prices -MinimumPriceLimit=Minimum price can't be lower then %s -MinimumRecommendedPrice=Minimum recommended price is: %s -PriceExpressionEditor=Price expression editor -PriceExpressionSelected=Selected price expression -PriceExpressionEditorHelp1="price = 2 + 2" or "2 + 2" for setting the price. Use ; to separate expressions -PriceExpressionEditorHelp2=You can access ExtraFields with variables like #extrafield_myextrafieldkey# and global variables with #global_mycode# -PriceExpressionEditorHelp3=In both product/service and vendor prices there are these variables available:
    #tva_tx# #localtax1_tx# #localtax2_tx# #weight# #length# #surface# #price_min# -PriceExpressionEditorHelp4=In product/service price only: #supplier_min_price#
    In vendor prices only: #supplier_quantity# and #supplier_tva_tx# -PriceExpressionEditorHelp5=Available global values: -PriceMode=Price mode -PriceNumeric=Number -DefaultPrice=Default price -DefaultPriceLog=Log of previous default prices -ComposedProductIncDecStock=Increase/Decrease stock on parent change -ComposedProduct=Child products -MinSupplierPrice=Minimum buying price -MinCustomerPrice=Minimum selling price -NoDynamicPrice=No dynamic price -DynamicPriceConfiguration=Dynamic price configuration -DynamicPriceDesc=You may define mathematical formulae to calculate Customer or Vendor prices. Such formulas can use all mathematical operators, some constants and variables. You can define here the variables you wish to use. If the variable needs an automatic update, you may define the external URL to allow Dolibarr to update the value automatically. -AddVariable=Add Variable -AddUpdater=Add Updater -GlobalVariables=Global variables -VariableToUpdate=Variable to update -GlobalVariableUpdaters=External updaters for variables -GlobalVariableUpdaterType0=JSON data -GlobalVariableUpdaterHelp0=Parses JSON data from specified URL, VALUE specifies the location of relevant value, -GlobalVariableUpdaterHelpFormat0=Format for request {"URL": "http://example.com/urlofjson", "VALUE": "array1,array2,targetvalue"} -GlobalVariableUpdaterType1=WebService data -GlobalVariableUpdaterHelp1=Parses WebService data from specified URL, NS specifies the namespace, VALUE specifies the location of relevant value, DATA should contain the data to send and METHOD is the calling WS method -GlobalVariableUpdaterHelpFormat1=Format for request is {"URL": "http://example.com/urlofws", "VALUE": "array,targetvalue", "NS": "http://example.com/urlofns", "METHOD": "myWSMethod", "DATA": {"your": "data", "to": "send"}} -UpdateInterval=Update interval (minutes) -LastUpdated=Latest update -CorrectlyUpdated=Correctly updated -PropalMergePdfProductActualFile=Files use to add into PDF Azur are/is -PropalMergePdfProductChooseFile=Select PDF files -IncludingProductWithTag=Include products/services with tag -DefaultPriceRealPriceMayDependOnCustomer=Default price, real price may depend on customer -WarningSelectOneDocument=Please select at least one document -DefaultUnitToShow=Unit -NbOfQtyInProposals=Qty in proposals -ClinkOnALinkOfColumn=Click on a link of column %s to get a detailed view... -ProductsOrServicesTranslations=Products/Services translations -TranslatedLabel=Translated label -TranslatedDescription=Translated description -TranslatedNote=Translated notes -ProductWeight=Weight for 1 product -ProductVolume=Volume for 1 product -WeightUnits=Weight unit -VolumeUnits=Volume unit -WidthUnits=Width unit -LengthUnits=Length unit -HeightUnits=Height unit -SurfaceUnits=Surface unit -SizeUnits=Size unit -DeleteProductBuyPrice=Delete buying price -ConfirmDeleteProductBuyPrice=Are you sure you want to delete this buying price? -SubProduct=Sub product -ProductSheet=Product sheet -ServiceSheet=Service sheet -PossibleValues=Possible values -GoOnMenuToCreateVairants=Go on menu %s - %s to prepare attribute variants (like colors, size, ...) -UseProductFournDesc=Add a feature to define the product description defined by the vendors (for each vendor reference) in addition to the description for customers -ProductSupplierDescription=Vendor description for the product -UseProductSupplierPackaging=Use packaging on supplier prices (recalculate quantities according to packaging set on supplier price when adding/updating line in supplier documents) -PackagingForThisProduct=Packaging -PackagingForThisProductDesc=On supplier order, you will automaticly order this quantity (or a multiple of this quantity). Cannot be less than minimum buying quantity -QtyRecalculatedWithPackaging=The quantity of the line were recalculated according to supplier packaging - -#Attributes -VariantAttributes=Variant attributes -ProductAttributes=Variant attributes for products -ProductAttributeName=Variant attribute %s -ProductAttribute=Variant attribute -ProductAttributeDeleteDialog=Are you sure you want to delete this attribute? All values will be deleted -ProductAttributeValueDeleteDialog=Are you sure you want to delete the value "%s" with reference "%s" of this attribute? -ProductCombinationDeleteDialog=Are you sure want to delete the variant of the product "%s"? -ProductCombinationAlreadyUsed=There was an error while deleting the variant. Please check it is not being used in any object -ProductCombinations=Variants -PropagateVariant=Propagate variants -HideProductCombinations=Hide products variant in the products selector -ProductCombination=Variant -NewProductCombination=New variant -EditProductCombination=Editing variant -NewProductCombinations=New variants -EditProductCombinations=Editing variants -SelectCombination=Select combination -ProductCombinationGenerator=Variants generator -Features=Features -PriceImpact=Price impact -ImpactOnPriceLevel=Impact on price level %s -ApplyToAllPriceImpactLevel= Apply to all levels -ApplyToAllPriceImpactLevelHelp=By clicking here you set the same price impact on all levels -WeightImpact=Weight impact -NewProductAttribute=New attribute -NewProductAttributeValue=New attribute value -ErrorCreatingProductAttributeValue=There was an error while creating the attribute value. It could be because there is already an existing value with that reference -ProductCombinationGeneratorWarning=If you continue, before generating new variants, all previous ones will be DELETED. Already existing ones will be updated with the new values -TooMuchCombinationsWarning=Generating lots of variants may result in high CPU, memory usage and Dolibarr not able to create them. Enabling the option "%s" may help reduce memory usage. -DoNotRemovePreviousCombinations=Do not remove previous variants -UsePercentageVariations=Use percentage variations -PercentageVariation=Percentage variation -ErrorDeletingGeneratedProducts=There was an error while trying to delete existing product variants -NbOfDifferentValues=No. of different values -NbProducts=Number of products -ParentProduct=Parent product -HideChildProducts=Hide variant products -ShowChildProducts=Show variant products -NoEditVariants=Go to Parent product card and edit variants price impact in the variants tab -ConfirmCloneProductCombinations=Would you like to copy all the product variants to the other parent product with the given reference? -CloneDestinationReference=Destination product reference -ErrorCopyProductCombinations=There was an error while copying the product variants -ErrorDestinationProductNotFound=Destination product not found -ErrorProductCombinationNotFound=Product variant not found -ActionAvailableOnVariantProductOnly=Action only available on the variant of product -ProductsPricePerCustomer=Product prices per customers -ProductSupplierExtraFields=Additional Attributes (Supplier Prices) -DeleteLinkedProduct=Delete the child product linked to the combination -PMPValue=Weighted average price -PMPValueShort=WAP diff --git a/htdocs/langs/ar_IQ/projects.lang b/htdocs/langs/ar_IQ/projects.lang deleted file mode 100644 index 77fc9970303..00000000000 --- a/htdocs/langs/ar_IQ/projects.lang +++ /dev/null @@ -1,283 +0,0 @@ -# Dolibarr language file - Source file is en_US - projects -RefProject=Ref. project -ProjectRef=Project ref. -ProjectId=Project Id -ProjectLabel=Project label -ProjectsArea=Projects Area -ProjectStatus=Project status -SharedProject=Everybody -PrivateProject=Project contacts -ProjectsImContactFor=Projects for which I am explicitly a contact -AllAllowedProjects=All project I can read (mine + public) -AllProjects=All projects -MyProjectsDesc=This view is limited to the projects that you are a contact for -ProjectsPublicDesc=This view presents all projects you are allowed to read. -TasksOnProjectsPublicDesc=This view presents all tasks on projects you are allowed to read. -ProjectsPublicTaskDesc=This view presents all projects and tasks you are allowed to read. -ProjectsDesc=This view presents all projects (your user permissions grant you permission to view everything). -TasksOnProjectsDesc=This view presents all tasks on all projects (your user permissions grant you permission to view everything). -MyTasksDesc=This view is limited to the projects or tasks that you are a contact for -OnlyOpenedProject=Only open projects are visible (projects in draft or closed status are not visible). -ClosedProjectsAreHidden=Closed projects are not visible. -TasksPublicDesc=This view presents all projects and tasks you are allowed to read. -TasksDesc=This view presents all projects and tasks (your user permissions grant you permission to view everything). -AllTaskVisibleButEditIfYouAreAssigned=All tasks for qualified projects are visible, but you can enter time only for task assigned to selected user. Assign task if you need to enter time on it. -OnlyYourTaskAreVisible=Only tasks assigned to you are visible. If you need to enter time on a task and if the task is not visible here, then you need to assign the task to yourself. -ImportDatasetTasks=Tasks of projects -ProjectCategories=Project tags/categories -NewProject=New project -AddProject=Create project -DeleteAProject=Delete a project -DeleteATask=Delete a task -ConfirmDeleteAProject=Are you sure you want to delete this project? -ConfirmDeleteATask=Are you sure you want to delete this task? -OpenedProjects=Open projects -OpenedTasks=Open tasks -OpportunitiesStatusForOpenedProjects=Leads amount of open projects by status -OpportunitiesStatusForProjects=Leads amount of projects by status -ShowProject=Show project -ShowTask=Show task -SetProject=Set project -NoProject=No project defined or owned -NbOfProjects=Number of projects -NbOfTasks=Number of tasks -TimeSpent=Time spent -TimeSpentByYou=Time spent by you -TimeSpentByUser=Time spent by user -TimesSpent=Time spent -TaskId=Task ID -RefTask=Task ref. -LabelTask=Task label -TaskTimeSpent=Time spent on tasks -TaskTimeUser=User -TaskTimeNote=Note -TaskTimeDate=Date -TasksOnOpenedProject=Tasks on open projects -WorkloadNotDefined=Workload not defined -NewTimeSpent=Time spent -MyTimeSpent=My time spent -BillTime=Bill the time spent -BillTimeShort=Bill time -TimeToBill=Time not billed -TimeBilled=Time billed -Tasks=Tasks -Task=Task -TaskDateStart=Task start date -TaskDateEnd=Task end date -TaskDescription=Task description -NewTask=New task -AddTask=Create task -AddTimeSpent=Create time spent -AddHereTimeSpentForDay=Add here time spent for this day/task -AddHereTimeSpentForWeek=Add here time spent for this week/task -Activity=Activity -Activities=Tasks/activities -MyActivities=My tasks/activities -MyProjects=My projects -MyProjectsArea=My projects Area -DurationEffective=Effective duration -ProgressDeclared=Declared real progress -TaskProgressSummary=Task progress -CurentlyOpenedTasks=Curently open tasks -TheReportedProgressIsLessThanTheCalculatedProgressionByX=The declared real progress is less %s than the progress on consumption -TheReportedProgressIsMoreThanTheCalculatedProgressionByX=The declared real progress is more %s than the progress on consumption -ProgressCalculated=Progress on consumption -WhichIamLinkedTo=which I'm linked to -WhichIamLinkedToProject=which I'm linked to project -Time=Time -TimeConsumed=Consumed -ListOfTasks=List of tasks -GoToListOfTimeConsumed=Go to list of time consumed -GanttView=Gantt View -ListWarehouseAssociatedProject=List of warehouses associated to the project -ListProposalsAssociatedProject=List of the commercial proposals related to the project -ListOrdersAssociatedProject=List of sales orders related to the project -ListInvoicesAssociatedProject=List of customer invoices related to the project -ListPredefinedInvoicesAssociatedProject=List of customer template invoices related to the project -ListSupplierOrdersAssociatedProject=List of purchase orders related to the project -ListSupplierInvoicesAssociatedProject=List of vendor invoices related to the project -ListContractAssociatedProject=List of contracts related to the project -ListShippingAssociatedProject=List of shippings related to the project -ListFichinterAssociatedProject=List of interventions related to the project -ListExpenseReportsAssociatedProject=List of expense reports related to the project -ListDonationsAssociatedProject=List of donations related to the project -ListVariousPaymentsAssociatedProject=List of miscellaneous payments related to the project -ListSalariesAssociatedProject=List of payments of salaries related to the project -ListActionsAssociatedProject=List of events related to the project -ListMOAssociatedProject=List of manufacturing orders related to the project -ListTaskTimeUserProject=List of time consumed on tasks of project -ListTaskTimeForTask=List of time consumed on task -ActivityOnProjectToday=Activity on project today -ActivityOnProjectYesterday=Activity on project yesterday -ActivityOnProjectThisWeek=Activity on project this week -ActivityOnProjectThisMonth=Activity on project this month -ActivityOnProjectThisYear=Activity on project this year -ChildOfProjectTask=Child of project/task -ChildOfTask=Child of task -TaskHasChild=Task has child -NotOwnerOfProject=Not owner of this private project -AffectedTo=Allocated to -CantRemoveProject=This project can't be removed as it is referenced by some other objects (invoice, orders or other). See tab '%s'. -ValidateProject=Validate projet -ConfirmValidateProject=Are you sure you want to validate this project? -CloseAProject=Close project -ConfirmCloseAProject=Are you sure you want to close this project? -AlsoCloseAProject=Also close project (keep it open if you still need to follow production tasks on it) -ReOpenAProject=Open project -ConfirmReOpenAProject=Are you sure you want to re-open this project? -ProjectContact=Contacts of project -TaskContact=Task contacts -ActionsOnProject=Events on project -YouAreNotContactOfProject=You are not a contact of this private project -UserIsNotContactOfProject=User is not a contact of this private project -DeleteATimeSpent=Delete time spent -ConfirmDeleteATimeSpent=Are you sure you want to delete this time spent? -DoNotShowMyTasksOnly=See also tasks not assigned to me -ShowMyTasksOnly=View only tasks assigned to me -TaskRessourceLinks=Contacts of task -ProjectsDedicatedToThisThirdParty=Projects dedicated to this third party -NoTasks=No tasks for this project -LinkedToAnotherCompany=Linked to other third party -TaskIsNotAssignedToUser=Task not assigned to user. Use button '%s' to assign task now. -ErrorTimeSpentIsEmpty=Time spent is empty -TimeRecordingRestrictedToNMonthsBack=Time recording is restricted to %s months back -ThisWillAlsoRemoveTasks=This action will also delete all tasks of project (%s tasks at the moment) and all inputs of time spent. -IfNeedToUseOtherObjectKeepEmpty=If some objects (invoice, order, ...), belonging to another third party, must be linked to the project to create, keep this empty to have the project being multi third parties. -CloneTasks=Clone tasks -CloneContacts=Clone contacts -CloneNotes=Clone notes -CloneProjectFiles=Clone project joined files -CloneTaskFiles=Clone task(s) joined files (if task(s) cloned) -CloneMoveDate=Update project/tasks dates from now? -ConfirmCloneProject=Are you sure to clone this project? -ProjectReportDate=Change task dates according to new project start date -ErrorShiftTaskDate=Impossible to shift task date according to new project start date -ProjectsAndTasksLines=Projects and tasks -ProjectCreatedInDolibarr=Project %s created -ProjectValidatedInDolibarr=Project %s validated -ProjectModifiedInDolibarr=Project %s modified -TaskCreatedInDolibarr=Task %s created -TaskModifiedInDolibarr=Task %s modified -TaskDeletedInDolibarr=Task %s deleted -OpportunityStatus=Lead status -OpportunityStatusShort=Lead status -OpportunityProbability=Lead probability -OpportunityProbabilityShort=Lead probab. -OpportunityAmount=Lead amount -OpportunityAmountShort=Lead amount -OpportunityWeightedAmount=Opportunity weighted amount -OpportunityWeightedAmountShort=Opp. weighted amount -OpportunityAmountAverageShort=Average lead amount -OpportunityAmountWeigthedShort=Weighted lead amount -WonLostExcluded=Won/Lost excluded -##### Types de contacts ##### -TypeContact_project_internal_PROJECTLEADER=Project leader -TypeContact_project_external_PROJECTLEADER=Project leader -TypeContact_project_internal_PROJECTCONTRIBUTOR=Contributor -TypeContact_project_external_PROJECTCONTRIBUTOR=Contributor -TypeContact_project_task_internal_TASKEXECUTIVE=Task executive -TypeContact_project_task_external_TASKEXECUTIVE=Task executive -TypeContact_project_task_internal_TASKCONTRIBUTOR=Contributor -TypeContact_project_task_external_TASKCONTRIBUTOR=Contributor -SelectElement=Select element -AddElement=Link to element -LinkToElementShort=Link to -# Documents models -DocumentModelBeluga=Project document template for linked objects overview -DocumentModelBaleine=Project document template for tasks -DocumentModelTimeSpent=Project report template for time spent -PlannedWorkload=Planned workload -PlannedWorkloadShort=Workload -ProjectReferers=Related items -ProjectMustBeValidatedFirst=Project must be validated first -FirstAddRessourceToAllocateTime=Assign a user resource as contact of project to allocate time -InputPerDay=Input per day -InputPerWeek=Input per week -InputPerMonth=Input per month -InputDetail=Input detail -TimeAlreadyRecorded=This is time spent already recorded for this task/day and user %s -ProjectsWithThisUserAsContact=Projects with this user as contact -TasksWithThisUserAsContact=Tasks assigned to this user -ResourceNotAssignedToProject=Not assigned to project -ResourceNotAssignedToTheTask=Not assigned to the task -NoUserAssignedToTheProject=No users assigned to this project -TimeSpentBy=Time spent by -TasksAssignedTo=Tasks assigned to -AssignTaskToMe=Assign task to myself -AssignTaskToUser=Assign task to %s -SelectTaskToAssign=Select task to assign... -AssignTask=Assign -ProjectOverview=Overview -ManageTasks=Use projects to follow tasks and/or report time spent (timesheets) -ManageOpportunitiesStatus=Use projects to follow leads/opportinuties -ProjectNbProjectByMonth=No. of created projects by month -ProjectNbTaskByMonth=No. of created tasks by month -ProjectOppAmountOfProjectsByMonth=Amount of leads by month -ProjectWeightedOppAmountOfProjectsByMonth=Weighted amount of leads by month -ProjectOpenedProjectByOppStatus=Open project|lead by lead status -ProjectsStatistics=Statistics on projects or leads -TasksStatistics=Statistics on tasks of projects or leads -TaskAssignedToEnterTime=Task assigned. Entering time on this task should be possible. -IdTaskTime=Id task time -YouCanCompleteRef=If you want to complete the ref with some suffix, it is recommanded to add a - character to separate it, so the automatic numbering will still work correctly for next projects. For example %s-MYSUFFIX -OpenedProjectsByThirdparties=Open projects by third parties -OnlyOpportunitiesShort=Only leads -OpenedOpportunitiesShort=Open leads -NotOpenedOpportunitiesShort=Not an open lead -NotAnOpportunityShort=Not a lead -OpportunityTotalAmount=Total amount of leads -OpportunityPonderatedAmount=Weighted amount of leads -OpportunityPonderatedAmountDesc=Leads amount weighted with probability -OppStatusPROSP=Prospection -OppStatusQUAL=Qualification -OppStatusPROPO=Proposal -OppStatusNEGO=Negociation -OppStatusPENDING=Pending -OppStatusWON=Won -OppStatusLOST=Lost -Budget=Budget -AllowToLinkFromOtherCompany=Allow to link project from other company

    Supported values:
    - Keep empty: Can link any project of the company (default)
    - "all": Can link any projects, even projects of other companies
    - A list of third-party ids separated by commas: can link all projects of these third partys (Example: 123,4795,53)
    -LatestProjects=Latest %s projects -LatestModifiedProjects=Latest %s modified projects -OtherFilteredTasks=Other filtered tasks -NoAssignedTasks=No assigned tasks found (assign project/tasks to the current user from the top select box to enter time on it) -ThirdPartyRequiredToGenerateInvoice=A third party must be defined on project to be able to invoice it. -ThirdPartyRequiredToGenerateInvoice=A third party must be defined on project to be able to invoice it. -ChooseANotYetAssignedTask=Choose a task not yet assigned to you -# Comments trans -AllowCommentOnTask=Allow user comments on tasks -AllowCommentOnProject=Allow user comments on projects -DontHavePermissionForCloseProject=You do not have permissions to close the project %s -DontHaveTheValidateStatus=The project %s must be open to be closed -RecordsClosed=%s project(s) closed -SendProjectRef=Information project %s -ModuleSalaryToDefineHourlyRateMustBeEnabled=Module 'Salaries' must be enabled to define employee hourly rate to have time spent valorized -NewTaskRefSuggested=Task ref already used, a new task ref is required -TimeSpentInvoiced=Time spent billed -TimeSpentForIntervention=Time spent -TimeSpentForInvoice=Time spent -OneLinePerUser=One line per user -ServiceToUseOnLines=Service to use on lines -InvoiceGeneratedFromTimeSpent=Invoice %s has been generated from time spent on project -InterventionGeneratedFromTimeSpent=Intervention %s has been generated from time spent on project -ProjectBillTimeDescription=Check if you enter timesheet on tasks of project AND you plan to generate invoice(s) from the timesheet to bill the customer of the project (do not check if you plan to create invoice that is not based on entered timesheets). Note: To generate invoice, go on tab 'Time spent' of the project and select lines to include. -ProjectFollowOpportunity=Follow opportunity -ProjectFollowTasks=Follow tasks or time spent -Usage=Usage -UsageOpportunity=Usage: Opportunity -UsageTasks=Usage: Tasks -UsageBillTimeShort=Usage: Bill time -InvoiceToUse=Draft invoice to use -InterToUse=Draft intervention to use -NewInvoice=New invoice -NewInter=New intervention -OneLinePerTask=One line per task -OneLinePerPeriod=One line per period -OneLinePerTimeSpentLine=One line for each time spent declaration -RefTaskParent=Ref. Parent Task -ProfitIsCalculatedWith=Profit is calculated using -AddPersonToTask=Add also to tasks -UsageOrganizeEvent=Usage: Event Organization -PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE=Classify project as closed when all its tasks are completed (100%% progress) -PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Note: existing projects with all tasks at 100 %% progress won't be affected: you will have to close them manually. This option only affects open projects. -SelectLinesOfTimeSpentToInvoice=Select lines of time spent that are unbilled, then bulk action "Generate Invoice" to bill them diff --git a/htdocs/langs/ar_IQ/propal.lang b/htdocs/langs/ar_IQ/propal.lang deleted file mode 100644 index edbc08236d3..00000000000 --- a/htdocs/langs/ar_IQ/propal.lang +++ /dev/null @@ -1,92 +0,0 @@ -# Dolibarr language file - Source file is en_US - propal -Proposals=Commercial proposals -Proposal=Commercial proposal -ProposalShort=Proposal -ProposalsDraft=Draft commercial proposals -ProposalsOpened=Open commercial proposals -CommercialProposal=Commercial proposal -PdfCommercialProposalTitle=Commercial proposal -ProposalCard=Proposal card -NewProp=New commercial proposal -NewPropal=New proposal -Prospect=Prospect -DeleteProp=Delete commercial proposal -ValidateProp=Validate commercial proposal -AddProp=Create proposal -ConfirmDeleteProp=Are you sure you want to delete this commercial proposal? -ConfirmValidateProp=Are you sure you want to validate this commercial proposal under name %s? -LastPropals=Latest %s proposals -LastModifiedProposals=Latest %s modified proposals -AllPropals=All proposals -SearchAProposal=Search a proposal -NoProposal=No proposal -ProposalsStatistics=Commercial proposal's statistics -NumberOfProposalsByMonth=Number by month -AmountOfProposalsByMonthHT=Amount by month (excl. tax) -NbOfProposals=Number of commercial proposals -ShowPropal=Show proposal -PropalsDraft=Drafts -PropalsOpened=Open -PropalStatusDraft=Draft (needs to be validated) -PropalStatusValidated=Validated (proposal is open) -PropalStatusSigned=Signed (needs billing) -PropalStatusNotSigned=Not signed (closed) -PropalStatusBilled=Billed -PropalStatusDraftShort=Draft -PropalStatusValidatedShort=Validated (open) -PropalStatusClosedShort=Closed -PropalStatusSignedShort=Signed -PropalStatusNotSignedShort=Not signed -PropalStatusBilledShort=Billed -PropalsToClose=Commercial proposals to close -PropalsToBill=Signed commercial proposals to bill -ListOfProposals=List of commercial proposals -ActionsOnPropal=Events on proposal -RefProposal=Commercial proposal ref -SendPropalByMail=Send commercial proposal by mail -DatePropal=Date of proposal -DateEndPropal=Validity ending date -ValidityDuration=Validity duration -SetAcceptedRefused=Set accepted/refused -ErrorPropalNotFound=Propal %s not found -AddToDraftProposals=Add to draft proposal -NoDraftProposals=No draft proposals -CopyPropalFrom=Create commercial proposal by copying existing proposal -CreateEmptyPropal=Create empty commercial proposal or from list of products/services -DefaultProposalDurationValidity=Default commercial proposal validity duration (in days) -UseCustomerContactAsPropalRecipientIfExist=Use contact/address with type 'Contact following-up proposal' if defined instead of third party address as proposal recipient address -ConfirmClonePropal=Are you sure you want to clone the commercial proposal %s? -ConfirmReOpenProp=Are you sure you want to open back the commercial proposal %s? -ProposalsAndProposalsLines=Commercial proposal and lines -ProposalLine=Proposal line -ProposalLines=Proposal lines -AvailabilityPeriod=Availability delay -SetAvailability=Set availability delay -AfterOrder=after order -OtherProposals=Other proposals -##### Availability ##### -AvailabilityTypeAV_NOW=Immediate -AvailabilityTypeAV_1W=1 week -AvailabilityTypeAV_2W=2 weeks -AvailabilityTypeAV_3W=3 weeks -AvailabilityTypeAV_1M=1 month -##### Types de contacts ##### -TypeContact_propal_internal_SALESREPFOLL=Representative following-up proposal -TypeContact_propal_external_BILLING=Customer invoice contact -TypeContact_propal_external_CUSTOMER=Customer contact following-up proposal -TypeContact_propal_external_SHIPPING=Customer contact for delivery -# Document models -DocModelAzurDescription=A complete proposal model (old implementation of Cyan template) -DocModelCyanDescription=A complete proposal model -DefaultModelPropalCreate=Default model creation -DefaultModelPropalToBill=Default template when closing a business proposal (to be invoiced) -DefaultModelPropalClosed=Default template when closing a business proposal (unbilled) -ProposalCustomerSignature=Written acceptance, company stamp, date and signature -ProposalsStatisticsSuppliers=Vendor proposals statistics -CaseFollowedBy=Case followed by -SignedOnly=Signed only -IdProposal=Proposal ID -IdProduct=Product ID -PrParentLine=Proposal Parent Line -LineBuyPriceHT=Buy Price Amount net of tax for line - diff --git a/htdocs/langs/ar_IQ/receiptprinter.lang b/htdocs/langs/ar_IQ/receiptprinter.lang deleted file mode 100644 index 746d175e0c6..00000000000 --- a/htdocs/langs/ar_IQ/receiptprinter.lang +++ /dev/null @@ -1,82 +0,0 @@ -# Dolibarr language file - Source file is en_US - receiptprinter -ReceiptPrinterSetup=Setup of module ReceiptPrinter -PrinterAdded=Printer %s added -PrinterUpdated=Printer %s updated -PrinterDeleted=Printer %s deleted -TestSentToPrinter=Test Sent To Printer %s -ReceiptPrinter=Receipt printers -ReceiptPrinterDesc=Setup of receipt printers -ReceiptPrinterTemplateDesc=Setup of Templates -ReceiptPrinterTypeDesc=Description of Receipt Printer's type -ReceiptPrinterProfileDesc=Description of Receipt Printer's Profile -ListPrinters=List of Printers -SetupReceiptTemplate=Template Setup -CONNECTOR_DUMMY=Dummy Printer -CONNECTOR_NETWORK_PRINT=Network Printer -CONNECTOR_FILE_PRINT=Local Printer -CONNECTOR_WINDOWS_PRINT=Local Windows Printer -CONNECTOR_CUPS_PRINT=Cups Printer -CONNECTOR_DUMMY_HELP=Fake Printer for test, does nothing -CONNECTOR_NETWORK_PRINT_HELP=10.x.x.x:9100 -CONNECTOR_FILE_PRINT_HELP=/dev/usb/lp0, /dev/usb/lp1 -CONNECTOR_WINDOWS_PRINT_HELP=LPT1, COM1, smb://FooUser:secret@computername/workgroup/Receipt Printer -CONNECTOR_CUPS_PRINT_HELP=CUPS printer name, example: HPRT_TP805L -PROFILE_DEFAULT=Default Profile -PROFILE_SIMPLE=Simple Profile -PROFILE_EPOSTEP=Epos Tep Profile -PROFILE_P822D=P822D Profile -PROFILE_STAR=Star Profile -PROFILE_DEFAULT_HELP=Default Profile suitable for Epson printers -PROFILE_SIMPLE_HELP=Simple Profile No Graphics -PROFILE_EPOSTEP_HELP=Epos Tep Profile -PROFILE_P822D_HELP=P822D Profile No Graphics -PROFILE_STAR_HELP=Star Profile -DOL_LINE_FEED=Skip line -DOL_ALIGN_LEFT=Left align text -DOL_ALIGN_CENTER=Center text -DOL_ALIGN_RIGHT=Right align text -DOL_USE_FONT_A=Use font A of printer -DOL_USE_FONT_B=Use font B of printer -DOL_USE_FONT_C=Use font C of printer -DOL_PRINT_BARCODE=Print barcode -DOL_PRINT_BARCODE_CUSTOMER_ID=Print barcode customer id -DOL_CUT_PAPER_FULL=Cut ticket completely -DOL_CUT_PAPER_PARTIAL=Cut ticket partially -DOL_OPEN_DRAWER=Open cash drawer -DOL_ACTIVATE_BUZZER=Activate buzzer -DOL_PRINT_QRCODE=Print QR Code -DOL_PRINT_LOGO=Print logo of my company -DOL_PRINT_LOGO_OLD=Print logo of my company (old printers) -DOL_BOLD=Bold -DOL_BOLD_DISABLED=Disable bold -DOL_DOUBLE_HEIGHT=Double height size -DOL_DOUBLE_WIDTH=Double width size -DOL_DEFAULT_HEIGHT_WIDTH=Default height and width size -DOL_UNDERLINE=Enable underline -DOL_UNDERLINE_DISABLED=Disable underline -DOL_BEEP=Beep sound -DOL_PRINT_TEXT=Print text -DateInvoiceWithTime=Invoice date and time -YearInvoice=Invoice year -DOL_VALUE_MONTH_LETTERS=Invoice month in letters -DOL_VALUE_MONTH=Invoice month -DOL_VALUE_DAY=Invoice day -DOL_VALUE_DAY_LETTERS=Inovice day in letters -DOL_LINE_FEED_REVERSE=Line feed reverse -InvoiceID=Invoice ID -InvoiceRef=Invoice ref -DOL_PRINT_OBJECT_LINES=Invoice lines -DOL_VALUE_CUSTOMER_FIRSTNAME=Customer first name -DOL_VALUE_CUSTOMER_LASTNAME=Customer last name -DOL_VALUE_CUSTOMER_MAIL=Customer mail -DOL_VALUE_CUSTOMER_PHONE=Customer phone -DOL_VALUE_CUSTOMER_MOBILE=Customer mobile -DOL_VALUE_CUSTOMER_SKYPE=Customer Skype -DOL_VALUE_CUSTOMER_TAX_NUMBER=Customer tax number -DOL_VALUE_CUSTOMER_ACCOUNT_BALANCE=Customer account balance -DOL_VALUE_MYSOC_NAME=Your company name -VendorLastname=Vendor last name -VendorFirstname=Vendor first name -VendorEmail=Vendor email -DOL_VALUE_CUSTOMER_POINTS=Customer points -DOL_VALUE_OBJECT_POINTS=Object points diff --git a/htdocs/langs/ar_IQ/receptions.lang b/htdocs/langs/ar_IQ/receptions.lang deleted file mode 100644 index 338602e722e..00000000000 --- a/htdocs/langs/ar_IQ/receptions.lang +++ /dev/null @@ -1,47 +0,0 @@ -# Dolibarr language file - Source file is en_US - receptions -ReceptionsSetup=Product Reception setup -RefReception=Ref. reception -Reception=Reception -Receptions=Receptions -AllReceptions=All Receptions -Reception=Reception -Receptions=Receptions -ShowReception=Show Receptions -ReceptionsArea=Receptions area -ListOfReceptions=List of receptions -ReceptionMethod=Reception method -LastReceptions=Latest %s receptions -StatisticsOfReceptions=Statistics for receptions -NbOfReceptions=Number of receptions -NumberOfReceptionsByMonth=Number of receptions by month -ReceptionCard=Reception card -NewReception=New reception -CreateReception=Create reception -QtyInOtherReceptions=Qty in other receptions -OtherReceptionsForSameOrder=Other receptions for this order -ReceptionsAndReceivingForSameOrder=Receptions and receipts for this order -ReceptionsToValidate=Receptions to validate -StatusReceptionCanceled=Canceled -StatusReceptionDraft=Draft -StatusReceptionValidated=Validated (products to ship or already shipped) -StatusReceptionProcessed=Processed -StatusReceptionDraftShort=Draft -StatusReceptionValidatedShort=Validated -StatusReceptionProcessedShort=Processed -ReceptionSheet=Reception sheet -ConfirmDeleteReception=Are you sure you want to delete this reception? -ConfirmValidateReception=Are you sure you want to validate this reception with reference %s? -ConfirmCancelReception=Are you sure you want to cancel this reception? -StatsOnReceptionsOnlyValidated=Statistics conducted on receptions only validated. Date used is date of validation of reception (planed delivery date is not always known). -SendReceptionByEMail=Send reception by email -SendReceptionRef=Submission of reception %s -ActionsOnReception=Events on reception -ReceptionCreationIsDoneFromOrder=For the moment, creation of a new reception is done from the order card. -ReceptionLine=Reception line -ProductQtyInReceptionAlreadySent=Product quantity from open sales order already sent -ProductQtyInSuppliersReceptionAlreadyRecevied=Product quantity from open supplier order already received -ValidateOrderFirstBeforeReception=You must first validate the order before being able to make receptions. -ReceptionsNumberingModules=Numbering module for receptions -ReceptionsReceiptModel=Document templates for receptions -NoMorePredefinedProductToDispatch=No more predefined products to dispatch -ReceptionExist=A reception exists diff --git a/htdocs/langs/ar_IQ/recruitment.lang b/htdocs/langs/ar_IQ/recruitment.lang deleted file mode 100644 index 6b0e8117254..00000000000 --- a/htdocs/langs/ar_IQ/recruitment.lang +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (C) 2020 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 -# 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 . - -# -# Generic -# - -# Module label 'ModuleRecruitmentName' -ModuleRecruitmentName = Recruitment -# Module description 'ModuleRecruitmentDesc' -ModuleRecruitmentDesc = Manage and follow recruitment campaigns for new job positions - -# -# Admin page -# -RecruitmentSetup = Recruitment setup -Settings = Settings -RecruitmentSetupPage = Enter here the setup of main options for the recruitment module -RecruitmentArea=Recruitement area -PublicInterfaceRecruitmentDesc=Public pages of jobs are public URLs to show and answer to open jobs. There is one different link for each open job, found on each job record. -EnablePublicRecruitmentPages=Enable public pages of open jobs - -# -# About page -# -About = About -RecruitmentAbout = About Recruitment -RecruitmentAboutPage = Recruitment about page -NbOfEmployeesExpected=Expected nb of employees -JobLabel=Label of job position -WorkPlace=Work place -DateExpected=Expected date -FutureManager=Future manager -ResponsibleOfRecruitement=Responsible of recruitment -IfJobIsLocatedAtAPartner=If job is located at a partner place -PositionToBeFilled=Job position -PositionsToBeFilled=Job positions -ListOfPositionsToBeFilled=List of job positions -NewPositionToBeFilled=New job positions - -JobOfferToBeFilled=Job position to be filled -ThisIsInformationOnJobPosition=Information of the job position to be filled -ContactForRecruitment=Contact for recruitment -EmailRecruiter=Email recruiter -ToUseAGenericEmail=To use a generic email. If not defined, the email of the responsible of recruitment will be used -NewCandidature=New application -ListOfCandidatures=List of applications -RequestedRemuneration=Requested remuneration -ProposedRemuneration=Proposed remuneration -ContractProposed=Contract proposed -ContractSigned=Contract signed -ContractRefused=Contract refused -RecruitmentCandidature=Application -JobPositions=Job positions -RecruitmentCandidatures=Applications -InterviewToDo=Interview to do -AnswerCandidature=Application answer -YourCandidature=Your application -YourCandidatureAnswerMessage=Thanks you for your application.
    ... -JobClosedTextCandidateFound=The job position is closed. The position has been filled. -JobClosedTextCanceled=The job position is closed. -ExtrafieldsJobPosition=Complementary attributes (job positions) -ExtrafieldsApplication=Complementary attributes (job applications) -MakeOffer=Make an offer diff --git a/htdocs/langs/ar_IQ/resource.lang b/htdocs/langs/ar_IQ/resource.lang deleted file mode 100644 index e8574dc680f..00000000000 --- a/htdocs/langs/ar_IQ/resource.lang +++ /dev/null @@ -1,39 +0,0 @@ -# Dolibarr language file - Source file is en_US - resource -MenuResourceIndex=Resources -MenuResourceAdd=New resource -DeleteResource=Delete resource -ConfirmDeleteResourceElement=Confirm delete the resource for this element -NoResourceInDatabase=No resource in database. -NoResourceLinked=No resource linked -ActionsOnResource=Events about this resource -ResourcePageIndex=Resources list -ResourceSingular=Resource -ResourceCard=Resource card -AddResource=Create a resource -ResourceFormLabel_ref=Resource name -ResourceType=Resource type -ResourceFormLabel_description=Resource description - -ResourcesLinkedToElement=Resources linked to element - -ShowResource=Show resource - -ResourceElementPage=Element resources -ResourceCreatedWithSuccess=Resource successfully created -RessourceLineSuccessfullyDeleted=Resource line successfully deleted -RessourceLineSuccessfullyUpdated=Resource line successfully updated -ResourceLinkedWithSuccess=Resource linked with success - -ConfirmDeleteResource=Confirm to delete this resource -RessourceSuccessfullyDeleted=Resource successfully deleted -DictionaryResourceType=Type of resources - -SelectResource=Select resource - -IdResource=Id resource -AssetNumber=Serial number -ResourceTypeCode=Resource type code -ImportDataset_resource_1=Resources - -ErrorResourcesAlreadyInUse=Some resources are in use -ErrorResourceUseInEvent=%s used in %s event diff --git a/htdocs/langs/ar_IQ/salaries.lang b/htdocs/langs/ar_IQ/salaries.lang deleted file mode 100644 index 12905040b1a..00000000000 --- a/htdocs/langs/ar_IQ/salaries.lang +++ /dev/null @@ -1,24 +0,0 @@ -# Dolibarr language file - Source file is en_US - salaries -SALARIES_ACCOUNTING_ACCOUNT_PAYMENT=Accounting account used for user third parties -SALARIES_ACCOUNTING_ACCOUNT_PAYMENT_Desc=The dedicated accounting account defined on user card will be used for Subledger accounting only. This one will be used for General Ledger and as default value of Subledger accounting if dedicated user accounting account on user is not defined. -SALARIES_ACCOUNTING_ACCOUNT_CHARGE=Accounting account by default for wage payments -CREATE_NEW_SALARY_WITHOUT_AUTO_PAYMENT=By default, leave empty the option "Automatically create a total payment" when creating a Salary -Salary=Salary -Salaries=Salaries -NewSalary=New salary -NewSalaryPayment=New salary card -AddSalaryPayment=Add salary payment -SalaryPayment=Salary payment -SalariesPayments=Salaries payments -SalariesPaymentsOf=Salaries payments of %s -ShowSalaryPayment=Show salary payment -THM=Average hourly rate -TJM=Average daily rate -CurrentSalary=Current salary -THMDescription=This value may be used to calculate the cost of time consumed on a project entered by users if module project is used -TJMDescription=This value is currently for information only and is not used for any calculation -LastSalaries=Latest %s salaries -AllSalaries=All salaries -SalariesStatistics=Salary statistics -SalariesAndPayments=Salaries and payments -ConfirmDeleteSalaryPayment=Do you want to delete this salary payment ? diff --git a/htdocs/langs/ar_IQ/sendings.lang b/htdocs/langs/ar_IQ/sendings.lang index b94891d79c5..47082ac4ba4 100644 --- a/htdocs/langs/ar_IQ/sendings.lang +++ b/htdocs/langs/ar_IQ/sendings.lang @@ -1,76 +1,2 @@ # Dolibarr language file - Source file is en_US - sendings -RefSending=Ref. shipment -Sending=Shipment -Sendings=Shipments -AllSendings=All Shipments -Shipment=Shipment -Shipments=Shipments -ShowSending=Show Shipments -Receivings=Delivery Receipts -SendingsArea=Shipments area -ListOfSendings=List of shipments -SendingMethod=Shipping method -LastSendings=Latest %s shipments -StatisticsOfSendings=Statistics for shipments -NbOfSendings=Number of shipments -NumberOfShipmentsByMonth=Number of shipments by month -SendingCard=Shipment card -NewSending=New shipment -CreateShipment=Create shipment -QtyShipped=Qty shipped -QtyShippedShort=Qty ship. -QtyPreparedOrShipped=Qty prepared or shipped -QtyToShip=Qty to ship -QtyToReceive=Qty to receive -QtyReceived=Qty received -QtyInOtherShipments=Qty in other shipments -KeepToShip=Remain to ship -KeepToShipShort=Remain -OtherSendingsForSameOrder=Other shipments for this order -SendingsAndReceivingForSameOrder=Shipments and receipts for this order -SendingsToValidate=Shipments to validate -StatusSendingCanceled=Canceled -StatusSendingCanceledShort=Canceled -StatusSendingDraft=Draft -StatusSendingValidated=Validated (products to ship or already shipped) -StatusSendingProcessed=Processed -StatusSendingDraftShort=Draft -StatusSendingValidatedShort=Validated -StatusSendingProcessedShort=Processed -SendingSheet=Shipment sheet -ConfirmDeleteSending=Are you sure you want to delete this shipment? -ConfirmValidateSending=Are you sure you want to validate this shipment with reference %s? -ConfirmCancelSending=Are you sure you want to cancel this shipment? -DocumentModelMerou=Merou A5 model -WarningNoQtyLeftToSend=Warning, no products waiting to be shipped. -StatsOnShipmentsOnlyValidated=Statistics are only for validated shipments. Date used is the date of validation of shipment (planned delivery date is not always known) -DateDeliveryPlanned=Planned date of delivery -RefDeliveryReceipt=Ref delivery receipt -StatusReceipt=Status delivery receipt -DateReceived=Date delivery received -ClassifyReception=Classify reception -SendShippingByEMail=Send shipment by email -SendShippingRef=Submission of shipment %s -ActionsOnShipping=Events on shipment -LinkToTrackYourPackage=Link to track your package ShipmentCreationIsDoneFromOrder=For the moment, creation of a new shipment is done from the order card. -ShipmentLine=Shipment line -ProductQtyInCustomersOrdersRunning=Product quantity from open sales orders -ProductQtyInSuppliersOrdersRunning=Product quantity from open purchase orders -ProductQtyInShipmentAlreadySent=Product quantity from open sales order already sent -ProductQtyInSuppliersShipmentAlreadyRecevied=Product quantity from open purchase orders already received -NoProductToShipFoundIntoStock=No product to ship found in warehouse %s. Correct stock or go back to choose another warehouse. -WeightVolShort=Weight/Vol. -ValidateOrderFirstBeforeShipment=You must first validate the order before being able to make shipments. - -# Sending methods -# ModelDocument -DocumentModelTyphon=More complete document model for delivery receipts (logo...) -DocumentModelStorm=More complete document model for delivery receipts and extrafields compatibility (logo...) -Error_EXPEDITION_ADDON_NUMBER_NotDefined=Constant EXPEDITION_ADDON_NUMBER not defined -SumOfProductVolumes=Sum of product volumes -SumOfProductWeights=Sum of product weights - -# warehouse details -DetailWarehouseNumber= Warehouse details -DetailWarehouseFormat= W:%s (Qty: %d) diff --git a/htdocs/langs/ar_IQ/sms.lang b/htdocs/langs/ar_IQ/sms.lang deleted file mode 100644 index 055085eb16a..00000000000 --- a/htdocs/langs/ar_IQ/sms.lang +++ /dev/null @@ -1,51 +0,0 @@ -# Dolibarr language file - Source file is en_US - sms -Sms=Sms -SmsSetup=SMS setup -SmsDesc=This page allows you to define global options on SMS features -SmsCard=SMS Card -AllSms=All SMS campaigns -SmsTargets=Targets -SmsRecipients=Targets -SmsRecipient=Target -SmsTitle=Description -SmsFrom=Sender -SmsTo=Target -SmsTopic=Topic of SMS -SmsText=Message -SmsMessage=SMS Message -ShowSms=Show SMS -ListOfSms=List SMS campaigns -NewSms=New SMS campaign -EditSms=Edit SMS -ResetSms=New sending -DeleteSms=Delete SMS campaign -DeleteASms=Remove a SMS campaign -PreviewSms=Previuw SMS -PrepareSms=Prepare SMS -CreateSms=Create SMS -SmsResult=Result of SMS sending -TestSms=Test SMS -ValidSms=Validate SMS -ApproveSms=Approve SMS -SmsStatusDraft=Draft -SmsStatusValidated=Validated -SmsStatusApproved=Approved -SmsStatusSent=Sent -SmsStatusSentPartialy=Sent partially -SmsStatusSentCompletely=Sent completely -SmsStatusError=Error -SmsStatusNotSent=Not sent -SmsSuccessfulySent=SMS correctly sent (from %s to %s) -ErrorSmsRecipientIsEmpty=Number of target is empty -WarningNoSmsAdded=No new phone number to add to target list -ConfirmValidSms=Do you confirm validation of this campaign? -NbOfUniqueSms=No. of unique phone numbers -NbOfSms=No. of phone numbers -ThisIsATestMessage=This is a test message -SendSms=Send SMS -SmsInfoCharRemain=No. of remaining characters -SmsInfoNumero= (international format i.e.: +33899701761) -DelayBeforeSending=Delay before sending (minutes) -SmsNoPossibleSenderFound=No sender available. Check setup of your SMS provider. -SmsNoPossibleRecipientFound=No target available. Check setup of your SMS provider. -DisableStopIfSupported=Disable STOP message (if supported) diff --git a/htdocs/langs/ar_IQ/stocks.lang b/htdocs/langs/ar_IQ/stocks.lang index c1f0abc43a8..a95d0f1b7cd 100644 --- a/htdocs/langs/ar_IQ/stocks.lang +++ b/htdocs/langs/ar_IQ/stocks.lang @@ -1,263 +1,4 @@ # Dolibarr language file - Source file is en_US - stocks -WarehouseCard=Warehouse card -Warehouse=Warehouse -Warehouses=Warehouses -ParentWarehouse=Parent warehouse -NewWarehouse=New warehouse / Stock Location -WarehouseEdit=Modify warehouse -MenuNewWarehouse=New warehouse -WarehouseSource=Source warehouse -WarehouseSourceNotDefined=No warehouse defined, -AddWarehouse=Create warehouse -AddOne=Add one -DefaultWarehouse=Default warehouse -WarehouseTarget=Target warehouse ValidateSending=Delete sending CancelSending=Cancel sending DeleteSending=Delete sending -Stock=Stock -Stocks=Stocks -MissingStocks=Missing stocks -StockAtDate=Stocks at date -StockAtDateInPast=Date in the past -StockAtDateInFuture=Date in the future -StocksByLotSerial=Stocks by lot/serial -LotSerial=Lots/Serials -LotSerialList=List of lot/serials -Movements=Movements -ErrorWarehouseRefRequired=Warehouse reference name is required -ListOfWarehouses=List of warehouses -ListOfStockMovements=List of stock movements -ListOfInventories=List of inventories -MovementId=Movement ID -StockMovementForId=Movement ID %d -ListMouvementStockProject=List of stock movements associated to project -StocksArea=Warehouses area -AllWarehouses=All warehouses -IncludeEmptyDesiredStock=Include also negative stock with undefined desired stock -IncludeAlsoDraftOrders=Include also draft orders -Location=Location -LocationSummary=Short name of location -NumberOfDifferentProducts=Number of unique products -NumberOfProducts=Total number of products -LastMovement=Latest movement -LastMovements=Latest movements -Units=Units -Unit=Unit -StockCorrection=Stock correction -CorrectStock=Correct stock -StockTransfer=Stock transfer -TransferStock=Transfer stock -MassStockTransferShort=Mass stock transfer -StockMovement=Stock movement -StockMovements=Stock movements -NumberOfUnit=Number of units -UnitPurchaseValue=Unit purchase price -StockTooLow=Stock too low -StockLowerThanLimit=Stock lower than alert limit (%s) -EnhancedValue=Value -EnhancedValueOfWarehouses=Warehouses value -UserWarehouseAutoCreate=Create a user warehouse automatically when creating a user -AllowAddLimitStockByWarehouse=Manage also value for minimum and desired stock per pairing (product-warehouse) in addition to the value for minimum and desired stock per product -RuleForWarehouse=Rule for warehouses -WarehouseAskWarehouseOnThirparty=Set a warehouse on Third-parties -WarehouseAskWarehouseDuringPropal=Set a warehouse on Commercial proposals -WarehouseAskWarehouseDuringOrder=Set a warehouse on Sale orders -UserDefaultWarehouse=Set a warehouse on Users -MainDefaultWarehouse=Default warehouse -MainDefaultWarehouseUser=Use a default warehouse for each user -MainDefaultWarehouseUserDesc=By activating this option, during creation of a product, the warehouse assigned to the product will be defined on this one. If no warehouse is defined on the user, the default warehouse is defined. -IndependantSubProductStock=Product stock and subproduct stock are independent -QtyDispatched=Quantity dispatched -QtyDispatchedShort=Qty dispatched -QtyToDispatchShort=Qty to dispatch -OrderDispatch=Item receipts -RuleForStockManagementDecrease=Choose Rule for automatic stock decrease (manual decrease is always possible, even if an automatic decrease rule is activated) -RuleForStockManagementIncrease=Choose Rule for automatic stock increase (manual increase is always possible, even if an automatic increase rule is activated) -DeStockOnBill=Decrease real stocks on validation of customer invoice/credit note -DeStockOnValidateOrder=Decrease real stocks on validation of sales order -DeStockOnShipment=Decrease real stocks on shipping validation -DeStockOnShipmentOnClosing=Decrease real stocks when shipping is set to closed -ReStockOnBill=Increase real stocks on validation of vendor invoice/credit note -ReStockOnValidateOrder=Increase real stocks on purchase order approval -ReStockOnDispatchOrder=Increase real stocks on manual dispatching into warehouse, after purchase order receipt of goods -StockOnReception=Increase real stocks on validation of reception -StockOnReceptionOnClosing=Increase real stocks when reception is set to closed -OrderStatusNotReadyToDispatch=Order has not yet or no more a status that allows dispatching of products in stock warehouses. -StockDiffPhysicTeoric=Explanation for difference between physical and virtual stock -NoPredefinedProductToDispatch=No predefined products for this object. So no dispatching in stock is required. -DispatchVerb=Dispatch -StockLimitShort=Limit for alert -StockLimit=Stock limit for alert -StockLimitDesc=(empty) means no warning.
    0 can be used to trigger a warning as soon as the stock is empty. -PhysicalStock=Physical Stock -RealStock=Real Stock -RealStockDesc=Physical/real stock is the stock currently in the warehouses. -RealStockWillAutomaticallyWhen=The real stock will be modified according to this rule (as defined in the Stock module): -VirtualStock=Virtual stock -VirtualStockAtDate=Virtual stock at date -VirtualStockAtDateDesc=Virtual stock once all the pending orders that are planned to be processed before the chosen date will be finished -VirtualStockDesc=Virtual stock is the calculated stock available once all open/pending actions (that affect stocks) are closed (purchase orders received, sales orders shipped, manufacturing orders produced, etc) -AtDate=At date -IdWarehouse=Id warehouse -DescWareHouse=Description warehouse -LieuWareHouse=Localisation warehouse -WarehousesAndProducts=Warehouses and products -WarehousesAndProductsBatchDetail=Warehouses and products (with detail per lot/serial) -AverageUnitPricePMPShort=Weighted average price -AverageUnitPricePMPDesc=The input average unit price we had to expense to get 1 unit of product into our stock. -SellPriceMin=Selling Unit Price -EstimatedStockValueSellShort=Value for sell -EstimatedStockValueSell=Value for sell -EstimatedStockValueShort=Input stock value -EstimatedStockValue=Input stock value -DeleteAWarehouse=Delete a warehouse -ConfirmDeleteWarehouse=Are you sure you want to delete the warehouse %s? -PersonalStock=Personal stock %s -ThisWarehouseIsPersonalStock=This warehouse represents personal stock of %s %s -SelectWarehouseForStockDecrease=Choose warehouse to use for stock decrease -SelectWarehouseForStockIncrease=Choose warehouse to use for stock increase -NoStockAction=No stock action -DesiredStock=Desired Stock -DesiredStockDesc=This stock amount will be the value used to fill the stock by replenishment feature. -StockToBuy=To order -Replenishment=Replenishment -ReplenishmentOrders=Replenishment orders -VirtualDiffersFromPhysical=According to increase/decrease stock options, physical stock and virtual stock (physical stock + open orders) may differ -UseRealStockByDefault=Use real stock, instead of virtual stock, for replenishment feature -ReplenishmentCalculation=Amount to order will be (desired quantity - real stock) instead of (desired quantity - virtual stock) -UseVirtualStock=Use virtual stock -UsePhysicalStock=Use physical stock -CurentSelectionMode=Current selection mode -CurentlyUsingVirtualStock=Virtual stock -CurentlyUsingPhysicalStock=Physical stock -RuleForStockReplenishment=Rule for stocks replenishment -SelectProductWithNotNullQty=Select at least one product with a qty not null and a vendor -AlertOnly= Alerts only -IncludeProductWithUndefinedAlerts = Include also negative stock for products with no desired quantity defined, to restore them to 0 -WarehouseForStockDecrease=The warehouse %s will be used for stock decrease -WarehouseForStockIncrease=The warehouse %s will be used for stock increase -ForThisWarehouse=For this warehouse -ReplenishmentStatusDesc=This is a list of all products with a stock lower than desired stock (or lower than alert value if checkbox "alert only" is checked). Using the checkbox, you can create purchase orders to fill the difference. -ReplenishmentStatusDescPerWarehouse=If you want a replenishment based on desired quantity defined per warehouse, you must add a filter on the warehouse. -ReplenishmentOrdersDesc=This is a list of all open purchase orders including predefined products. Only open orders with predefined products, so orders that may affect stocks, are visible here. -Replenishments=Replenishments -NbOfProductBeforePeriod=Quantity of product %s in stock before selected period (< %s) -NbOfProductAfterPeriod=Quantity of product %s in stock after selected period (> %s) -MassMovement=Mass movement -SelectProductInAndOutWareHouse=Select a source warehouse and a target warehouse, a product and a quantity then click "%s". Once this is done for all required movements, click on "%s". -RecordMovement=Record transfer -ReceivingForSameOrder=Receipts for this order -StockMovementRecorded=Stock movements recorded -RuleForStockAvailability=Rules on stock requirements -StockMustBeEnoughForInvoice=Stock level must be enough to add product/service to invoice (check is done on current real stock when adding a line into invoice whatever the rule for automatic stock change) -StockMustBeEnoughForOrder=Stock level must be enough to add product/service to order (check is done on current real stock when adding a line into order whatever the rule for automatic stock change) -StockMustBeEnoughForShipment= Stock level must be enough to add product/service to shipment (check is done on current real stock when adding a line into shipment whatever the rule for automatic stock change) -MovementLabel=Label of movement -TypeMovement=Direction of movement -DateMovement=Date of movement -InventoryCode=Movement or inventory code -IsInPackage=Contained into package -WarehouseAllowNegativeTransfer=Stock can be negative -qtyToTranferIsNotEnough=You don't have enough stock from your source warehouse and your setup does not allow negative stocks. -qtyToTranferLotIsNotEnough=You don't have enough stock, for this lot number, from your source warehouse and your setup does not allow negative stocks (Qty for product '%s' with lot '%s' is %s in warehouse '%s'). -ShowWarehouse=Show warehouse -MovementCorrectStock=Stock correction for product %s -MovementTransferStock=Stock transfer of product %s into another warehouse -InventoryCodeShort=Inv./Mov. code -NoPendingReceptionOnSupplierOrder=No pending reception due to open purchase order -ThisSerialAlreadyExistWithDifferentDate=This lot/serial number (%s) already exists but with different eatby or sellby date (found %s but you enter %s). -OpenAnyMovement=Open (all movement) -OpenInternal=Open (only internal movement) -UseDispatchStatus=Use a dispatch status (approve/refuse) for product lines on purchase order reception -OptionMULTIPRICESIsOn=Option "several prices per segment" is on. It means a product has several selling price so value for sell can't be calculated -ProductStockWarehouseCreated=Stock limit for alert and desired optimal stock correctly created -ProductStockWarehouseUpdated=Stock limit for alert and desired optimal stock correctly updated -ProductStockWarehouseDeleted=Stock limit for alert and desired optimal stock correctly deleted -AddNewProductStockWarehouse=Set new limit for alert and desired optimal stock -AddStockLocationLine=Decrease quantity then click to add another warehouse for this product -InventoryDate=Inventory date -NewInventory=New inventory -inventorySetup = Inventory Setup -inventoryCreatePermission=Create new inventory -inventoryReadPermission=View inventories -inventoryWritePermission=Update inventories -inventoryValidatePermission=Validate inventory -inventoryDeletePermission=Delete inventory -inventoryTitle=Inventory -inventoryListTitle=Inventories -inventoryListEmpty=No inventory in progress -inventoryCreateDelete=Create/Delete inventory -inventoryCreate=Create new -inventoryEdit=Edit -inventoryValidate=Validated -inventoryDraft=Running -inventorySelectWarehouse=Warehouse choice -inventoryConfirmCreate=Create -inventoryOfWarehouse=Inventory for warehouse: %s -inventoryErrorQtyAdd=Error: one quantity is less than zero -inventoryMvtStock=By inventory -inventoryWarningProductAlreadyExists=This product is already into list -SelectCategory=Category filter -SelectFournisseur=Vendor filter -inventoryOnDate=Inventory -INVENTORY_USE_INVENTORY_DATE_FOR_DATE_OF_MVT=Stock movements will have the date of inventory (instead of the date of inventory validation) -inventoryChangePMPPermission=Allow to change PMP value for a product -ColumnNewPMP=New unit PMP -OnlyProdsInStock=Do not add product without stock -TheoricalQty=Theorique qty -TheoricalValue=Theorique qty -LastPA=Last BP -CurrentPA=Curent BP -RecordedQty=Recorded Qty -RealQty=Real Qty -RealValue=Real Value -RegulatedQty=Regulated Qty -AddInventoryProduct=Add product to inventory -AddProduct=Add -ApplyPMP=Apply PMP -FlushInventory=Flush inventory -ConfirmFlushInventory=Do you confirm this action? -InventoryFlushed=Inventory flushed -ExitEditMode=Exit edition -inventoryDeleteLine=Delete line -RegulateStock=Regulate Stock -ListInventory=List -StockSupportServices=Stock management supports Services -StockSupportServicesDesc=By default, you can stock only products of type "product". You may also stock a product of type "service" if both module Services and this option are enabled. -ReceiveProducts=Receive items -StockIncreaseAfterCorrectTransfer=Increase by correction/transfer -StockDecreaseAfterCorrectTransfer=Decrease by correction/transfer -StockIncrease=Stock increase -StockDecrease=Stock decrease -InventoryForASpecificWarehouse=Inventory for a specific warehouse -InventoryForASpecificProduct=Inventory for a specific product -StockIsRequiredToChooseWhichLotToUse=Stock is required to choose which lot to use -ForceTo=Force to -AlwaysShowFullArbo=Display full tree of warehouse on popup of warehouse links (Warning: This may decrease dramatically performances) -StockAtDatePastDesc=You can view here the stock (real stock) at a given date in the past -StockAtDateFutureDesc=You can view here the stock (virtual stock) at a given date in the future -CurrentStock=Current stock -InventoryRealQtyHelp=Set value to 0 to reset qty
    Keep field empty, or remove line, to keep unchanged -UpdateByScaning=Fill real qty by scaning -UpdateByScaningProductBarcode=Update by scan (product barcode) -UpdateByScaningLot=Update by scan (lot|serial barcode) -DisableStockChangeOfSubProduct=Deactivate the stock change for all the subproducts of this Kit during this movement. -ImportFromCSV=Import CSV list of movement -ChooseFileToImport=Upload file then click on the %s icon to select file as source import file... -SelectAStockMovementFileToImport=select a stock movement file to import -InfoTemplateImport=Uploaded file needs to have this format (* are mandatory fields):
    Source Warehouse* | Target Warehouse* | Product* | Quantity* | Lot/serial number
    CSV character separator must be "%s" -LabelOfInventoryMovemement=Inventory %s -ReOpen=Reopen -ConfirmFinish=Do you confirm the closing of the inventory ? This will generate all stock movements to update your stock to the real qty you entered into the inventory. -ObjectNotFound=%s not found -MakeMovementsAndClose=Generate movements and close -AutofillWithExpected=Fill real quantity with expected quantity -ShowAllBatchByDefault=By default, show batch details on product "stock" tab -CollapseBatchDetailHelp=You can set batch detail default display in stocks module configuration -FieldCannotBeNegative=Field "%s" cannot be negative -ErrorWrongBarcodemode=Unknown Barcode mode -ProductDoesNotExist=Product does not exist -ErrorSameBatchNumber=Same batch number found in inventory list -ProductBatchDoesNotExist=Product with batch/serial does not exist -ProductBarcodeDoesNotExist=Product with barcode does not exist diff --git a/htdocs/langs/ar_IQ/stripe.lang b/htdocs/langs/ar_IQ/stripe.lang deleted file mode 100644 index a536ffd81e7..00000000000 --- a/htdocs/langs/ar_IQ/stripe.lang +++ /dev/null @@ -1,71 +0,0 @@ -# Dolibarr language file - Source file is en_US - stripe -StripeSetup=Stripe module setup -StripeDesc=Offer customers a Stripe online payment page for payments with credit/cebit cards via Stripe. This can be used to allow your customers to make ad-hoc payments or for payments related to a particular Dolibarr object (invoice, order, ...) -StripeOrCBDoPayment=Pay with credit card or Stripe -FollowingUrlAreAvailableToMakePayments=Following URLs are available to offer a page to a customer to make a payment on Dolibarr objects -PaymentForm=Payment form -WelcomeOnPaymentPage=Welcome to our online payment service -ThisScreenAllowsYouToPay=This screen allow you to make an online payment to %s. -ThisIsInformationOnPayment=This is information on payment to do -ToComplete=To complete -YourEMail=Email to receive payment confirmation -STRIPE_PAYONLINE_SENDEMAIL=Email notification after a payment attempt (success or fail) -Creditor=Creditor -PaymentCode=Payment code -StripeDoPayment=Pay with Stripe -YouWillBeRedirectedOnStripe=You will be redirected on secured Stripe page to input you credit card information -Continue=Next -ToOfferALinkForOnlinePayment=URL for %s payment -ToOfferALinkForOnlinePaymentOnOrder=URL to offer a %s online payment page for a sales order -ToOfferALinkForOnlinePaymentOnInvoice=URL to offer a %s online payment page for a customer invoice -ToOfferALinkForOnlinePaymentOnContractLine=URL to offer a %s online payment page for a contract line -ToOfferALinkForOnlinePaymentOnFreeAmount=URL to offer a %s online payment page of any amount with no existing object -ToOfferALinkForOnlinePaymentOnMemberSubscription=URL to offer a %s online payment page for a member subscription -ToOfferALinkForOnlinePaymentOnDonation=URL to offer a %s online payment page for payment of a donation -YouCanAddTagOnUrl=You can also add url parameter &tag=value to any of those URL (mandatory only for payment not linked to an object) to add your own payment comment tag.
    For the URL of payments with no existing object, you may also add the parameter &noidempotency=1 so the same link with same tag can be used several times (some payment mode may limit the payment to 1 for each different link without this parameter) -SetupStripeToHavePaymentCreatedAutomatically=Setup your Stripe with url %s to have payment created automatically when validated by Stripe. -AccountParameter=Account parameters -UsageParameter=Usage parameters -InformationToFindParameters=Help to find your %s account information -STRIPE_CGI_URL_V2=Url of Stripe CGI module for payment -CSSUrlForPaymentForm=CSS style sheet url for payment form -NewStripePaymentReceived=New Stripe payment received -NewStripePaymentFailed=New Stripe payment tried but failed -FailedToChargeCard=Failed to charge card -STRIPE_TEST_SECRET_KEY=Secret test key -STRIPE_TEST_PUBLISHABLE_KEY=Publishable test key -STRIPE_TEST_WEBHOOK_KEY=Webhook test key -STRIPE_LIVE_SECRET_KEY=Secret live key -STRIPE_LIVE_PUBLISHABLE_KEY=Publishable live key -STRIPE_LIVE_WEBHOOK_KEY=Webhook live key -ONLINE_PAYMENT_WAREHOUSE=Stock to use for stock decrease when online payment is done
    (TODO When option to decrease stock is done on an action on invoice and the online payment generate itself the invoice ?) -StripeLiveEnabled=Stripe live enabled (otherwise test/sandbox mode) -StripeImportPayment=Import Stripe payments -ExampleOfTestCreditCard=Example of credit card for test: %s => valid, %s => error CVC, %s => expired, %s => charge fails -StripeGateways=Stripe gateways -OAUTH_STRIPE_TEST_ID=Stripe Connect Client ID (ca_...) -OAUTH_STRIPE_LIVE_ID=Stripe Connect Client ID (ca_...) -BankAccountForBankTransfer=Bank account for fund payouts -StripeAccount=Stripe account -StripeChargeList=List of Stripe charges -StripeTransactionList=List of Stripe transactions -StripeCustomerId=Stripe customer id -StripePaymentModes=Stripe payment modes -LocalID=Local ID -StripeID=Stripe ID -NameOnCard=Name on card -CardNumber=Card Number -ExpiryDate=Expiry Date -CVN=CVN -DeleteACard=Delete Card -ConfirmDeleteCard=Are you sure you want to delete this Credit or Debit card? -CreateCustomerOnStripe=Create customer on Stripe -CreateCardOnStripe=Create card on Stripe -ShowInStripe=Show in Stripe -StripeUserAccountForActions=User account to use for email notification of some Stripe events (Stripe payouts) -StripePayoutList=List of Stripe payouts -ToOfferALinkForTestWebhook=Link to setup Stripe WebHook to call the IPN (test mode) -ToOfferALinkForLiveWebhook=Link to setup Stripe WebHook to call the IPN (live mode) -PaymentWillBeRecordedForNextPeriod=Payment will be recorded for the next period. -ClickHereToTryAgain=Click here to try again... -CreationOfPaymentModeMustBeDoneFromStripeInterface=Due to Strong Customer Authentication rules, creation of a card must be done from Stripe backoffice. You can click here to switch on Stripe customer record: %s diff --git a/htdocs/langs/ar_IQ/supplier_proposal.lang b/htdocs/langs/ar_IQ/supplier_proposal.lang deleted file mode 100644 index a68319fb2df..00000000000 --- a/htdocs/langs/ar_IQ/supplier_proposal.lang +++ /dev/null @@ -1,58 +0,0 @@ -# Dolibarr language file - Source file is en_US - supplier_proposal -SupplierProposal=Vendor commercial proposals -supplier_proposalDESC=Manage price requests to suppliers -SupplierProposalNew=New price request -CommRequest=Price request -CommRequests=Price requests -SearchRequest=Find a request -DraftRequests=Draft requests -SupplierProposalsDraft=Draft vendor proposals -LastModifiedRequests=Latest %s modified price requests -RequestsOpened=Open price requests -SupplierProposalArea=Vendor proposals area -SupplierProposalShort=Vendor proposal -SupplierProposals=Vendor proposals -SupplierProposalsShort=Vendor proposals -AskPrice=Price request -NewAskPrice=New price request -ShowSupplierProposal=Show price request -AddSupplierProposal=Create a price request -SupplierProposalRefFourn=Vendor ref -SupplierProposalDate=Delivery date -SupplierProposalRefFournNotice=Before closing to "Accepted", think to grasp suppliers references. -ConfirmValidateAsk=Are you sure you want to validate this price request under name %s? -DeleteAsk=Delete request -ValidateAsk=Validate request -SupplierProposalStatusDraft=Draft (needs to be validated) -SupplierProposalStatusValidated=Validated (request is open) -SupplierProposalStatusClosed=Closed -SupplierProposalStatusSigned=Accepted -SupplierProposalStatusNotSigned=Refused -SupplierProposalStatusDraftShort=Draft -SupplierProposalStatusValidatedShort=Validated -SupplierProposalStatusClosedShort=Closed -SupplierProposalStatusSignedShort=Accepted -SupplierProposalStatusNotSignedShort=Refused -CopyAskFrom=Create a price request by copying an existing request -CreateEmptyAsk=Create blank request -ConfirmCloneAsk=Are you sure you want to clone the price request %s? -ConfirmReOpenAsk=Are you sure you want to open back the price request %s? -SendAskByMail=Send price request by mail -SendAskRef=Sending the price request %s -SupplierProposalCard=Request card -ConfirmDeleteAsk=Are you sure you want to delete this price request %s? -ActionsOnSupplierProposal=Events on price request -DocModelAuroreDescription=A complete request model (logo...) -CommercialAsk=Price request -DefaultModelSupplierProposalCreate=Default model creation -DefaultModelSupplierProposalToBill=Default template when closing a price request (accepted) -DefaultModelSupplierProposalClosed=Default template when closing a price request (refused) -ListOfSupplierProposals=List of vendor proposal requests -ListSupplierProposalsAssociatedProject=List of vendor proposals associated with project -SupplierProposalsToClose=Vendor proposals to close -SupplierProposalsToProcess=Vendor proposals to process -LastSupplierProposals=Latest %s price requests -AllPriceRequests=All requests -TypeContact_supplier_proposal_external_SHIPPING=Vendor contact for delivery -TypeContact_supplier_proposal_external_BILLING=Vendor contact for billing -TypeContact_supplier_proposal_external_SERVICE=Representative following-up proposal diff --git a/htdocs/langs/ar_IQ/suppliers.lang b/htdocs/langs/ar_IQ/suppliers.lang deleted file mode 100644 index ca9ee174d29..00000000000 --- a/htdocs/langs/ar_IQ/suppliers.lang +++ /dev/null @@ -1,49 +0,0 @@ -# Dolibarr language file - Source file is en_US - vendors -Suppliers=Vendors -SuppliersInvoice=Vendor invoice -SupplierInvoices=Vendor invoices -ShowSupplierInvoice=Show Vendor Invoice -NewSupplier=New vendor -History=History -ListOfSuppliers=List of vendors -ShowSupplier=Show vendor -OrderDate=Order date -BuyingPriceMin=Best buying price -BuyingPriceMinShort=Best buying price -TotalBuyingPriceMinShort=Total of subproducts buying prices -TotalSellingPriceMinShort=Total of subproducts selling prices -SomeSubProductHaveNoPrices=Some sub-products have no price defined -AddSupplierPrice=Add buying price -ChangeSupplierPrice=Change buying price -SupplierPrices=Vendor prices -ReferenceSupplierIsAlreadyAssociatedWithAProduct=This vendor reference is already associated with a product: %s -NoRecordedSuppliers=No vendor recorded -SupplierPayment=Vendor payment -SuppliersArea=Vendor area -RefSupplierShort=Ref. vendor -Availability=Availability -ExportDataset_fournisseur_1=Vendor invoices and invoice details -ExportDataset_fournisseur_2=Vendor invoices and payments -ExportDataset_fournisseur_3=Purchase orders and order details -ApproveThisOrder=Approve this order -ConfirmApproveThisOrder=Are you sure you want to approve order %s? -DenyingThisOrder=Deny this order -ConfirmDenyingThisOrder=Are you sure you want to deny this order %s? -ConfirmCancelThisOrder=Are you sure you want to cancel this order %s? -AddSupplierOrder=Create Purchase Order -AddSupplierInvoice=Create vendor invoice -ListOfSupplierProductForSupplier=List of products and prices for vendor %s -SentToSuppliers=Sent to vendors -ListOfSupplierOrders=List of purchase orders -MenuOrdersSupplierToBill=Purchase orders to invoice -NbDaysToDelivery=Delivery delay (days) -DescNbDaysToDelivery=The longest delivery delay of the products from this order -SupplierReputation=Vendor reputation -ReferenceReputation=Reference reputation -DoNotOrderThisProductToThisSupplier=Do not order -NotTheGoodQualitySupplier=Low quality -ReputationForThisProduct=Reputation -BuyerName=Buyer name -AllProductServicePrices=All product / service prices -AllProductReferencesOfSupplier=All references of vendor -BuyingPriceNumShort=Vendor prices diff --git a/htdocs/langs/ar_IQ/ticket.lang b/htdocs/langs/ar_IQ/ticket.lang deleted file mode 100644 index 5615415ef28..00000000000 --- a/htdocs/langs/ar_IQ/ticket.lang +++ /dev/null @@ -1,321 +0,0 @@ -# en_US lang file for module ticket -# Copyright (C) 2013 Jean-François FERRY -# -# 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 . - -# -# Generic -# - -Module56000Name=Tickets -Module56000Desc=Ticket system for issue or request management - -Permission56001=See tickets -Permission56002=Modify tickets -Permission56003=Delete tickets -Permission56004=Manage tickets -Permission56005=See tickets of all third parties (not effective for external users, always be limited to the third party they depend on) - -TicketDictType=Ticket - Types -TicketDictCategory=Ticket - Groupes -TicketDictSeverity=Ticket - Severities -TicketDictResolution=Ticket - Resolution - -TicketTypeShortCOM=Commercial question -TicketTypeShortHELP=Request for functionnal help -TicketTypeShortISSUE=Issue or bug -TicketTypeShortPROBLEM=Problem -TicketTypeShortREQUEST=Change or enhancement request -TicketTypeShortPROJET=Project -TicketTypeShortOTHER=Other - -TicketSeverityShortLOW=Low -TicketSeverityShortNORMAL=Normal -TicketSeverityShortHIGH=High -TicketSeverityShortBLOCKING=Critical, Blocking - -ErrorBadEmailAddress=Field '%s' incorrect -MenuTicketMyAssign=My tickets -MenuTicketMyAssignNonClosed=My open tickets -MenuListNonClosed=Open tickets - -TypeContact_ticket_internal_CONTRIBUTOR=Contributor -TypeContact_ticket_internal_SUPPORTTEC=Assigned user -TypeContact_ticket_external_SUPPORTCLI=Customer contact / incident tracking -TypeContact_ticket_external_CONTRIBUTOR=External contributor - -OriginEmail=Reporter Email -Notify_TICKET_SENTBYMAIL=Send ticket message by email - -# Status -Read=Read -Assigned=Assigned -InProgress=In progress -NeedMoreInformation=Waiting for reporter feedback -NeedMoreInformationShort=Waiting for feedback -Answered=Answered -Waiting=Waiting -SolvedClosed=Solved -Deleted=Deleted - -# Dict -Type=Type -Severity=Severity -TicketGroupIsPublic=Group is public -TicketGroupIsPublicDesc=If a ticket group is public, it will be visible in the form when creating a ticket from the public interface - -# Email templates -MailToSendTicketMessage=To send email from ticket message - -# -# Admin page -# -TicketSetup=Ticket module setup -TicketSettings=Settings -TicketSetupPage= -TicketPublicAccess=A public interface requiring no identification is available at the following url -TicketSetupDictionaries=The type of ticket, severity and analytic codes are configurable from dictionaries -TicketParamModule=Module variable setup -TicketParamMail=Email setup -TicketEmailNotificationFrom=Notification email from -TicketEmailNotificationFromHelp=Used into ticket message answer by example -TicketEmailNotificationTo=Notifications email to -TicketEmailNotificationToHelp=Send email notifications to this address. -TicketNewEmailBodyLabel=Text message sent after creating a ticket -TicketNewEmailBodyHelp=The text specified here will be inserted into the email confirming the creation of a new ticket from the public interface. Information on the consultation of the ticket are automatically added. -TicketParamPublicInterface=Public interface setup -TicketsEmailMustExist=Require an existing email address to create a ticket -TicketsEmailMustExistHelp=In the public interface, the email address should already be filled in the database to create a new ticket. -PublicInterface=Public interface -TicketUrlPublicInterfaceLabelAdmin=Alternative URL for public interface -TicketUrlPublicInterfaceHelpAdmin=It is possible to define an alias to the web server and thus make available the public interface with another URL (the server must act as a proxy on this new URL) -TicketPublicInterfaceTextHomeLabelAdmin=Welcome text of the public interface -TicketPublicInterfaceTextHome=You can create a support ticket or view existing from its identifier tracking ticket. -TicketPublicInterfaceTextHomeHelpAdmin=The text defined here will appear on the home page of the public interface. -TicketPublicInterfaceTopicLabelAdmin=Interface title -TicketPublicInterfaceTopicHelp=This text will appear as the title of the public interface. -TicketPublicInterfaceTextHelpMessageLabelAdmin=Help text to the message entry -TicketPublicInterfaceTextHelpMessageHelpAdmin=This text will appear above the message input area of the user. -ExtraFieldsTicket=Extra attributes -TicketCkEditorEmailNotActivated=HTML editor is not activated. Please put FCKEDITOR_ENABLE_MAIL content to 1 to get it. -TicketsDisableEmail=Do not send emails for ticket creation or message recording -TicketsDisableEmailHelp=By default, emails are sent when new tickets or messages created. Enable this option to disable *all* email notifications -TicketsLogEnableEmail=Enable log by email -TicketsLogEnableEmailHelp=At each change, an email will be sent **to each contact** associated with the ticket. -TicketParams=Params -TicketsShowModuleLogo=Display the logo of the module in the public interface -TicketsShowModuleLogoHelp=Enable this option to hide the logo module in the pages of the public interface -TicketsShowCompanyLogo=Display the logo of the company in the public interface -TicketsShowCompanyLogoHelp=Enable this option to hide the logo of the main company in the pages of the public interface -TicketsEmailAlsoSendToMainAddress=Also send a notification to the main email address -TicketsEmailAlsoSendToMainAddressHelp=Enable this option to also send an email to the address defined into setup "%s" (see tab "%s") -TicketsLimitViewAssignedOnly=Restrict the display to tickets assigned to the current user (not effective for external users, always be limited to the third party they depend on) -TicketsLimitViewAssignedOnlyHelp=Only tickets assigned to the current user will be visible. Does not apply to a user with tickets management rights. -TicketsActivatePublicInterface=Activate public interface -TicketsActivatePublicInterfaceHelp=Public interface allow any visitors to create tickets. -TicketsAutoAssignTicket=Automatically assign the user who created the ticket -TicketsAutoAssignTicketHelp=When creating a ticket, the user can be automatically assigned to the ticket. -TicketNumberingModules=Tickets numbering module -TicketsModelModule=Document templates for tickets -TicketNotifyTiersAtCreation=Notify third party at creation -TicketsDisableCustomerEmail=Always disable emails when a ticket is created from public interface -TicketsPublicNotificationNewMessage=Send email(s) when a new message/comment is added to a ticket -TicketsPublicNotificationNewMessageHelp=Send email(s) when a new message is added from public interface (to assigned user or the notifications email to (update) and/or the notifications email to) -TicketPublicNotificationNewMessageDefaultEmail=Notifications email to (update) -TicketPublicNotificationNewMessageDefaultEmailHelp=Send an email to this address for each new message notifications if the ticket doesn't have a user assigned to it or if the user doesn't have any known email. -# -# Index & list page -# -TicketsIndex=Tickets area -TicketList=List of tickets -TicketAssignedToMeInfos=This page display ticket list created by or assigned to current user -NoTicketsFound=No ticket found -NoUnreadTicketsFound=No unread ticket found -TicketViewAllTickets=View all tickets -TicketViewNonClosedOnly=View only open tickets -TicketStatByStatus=Tickets by status -OrderByDateAsc=Sort by ascending date -OrderByDateDesc=Sort by descending date -ShowAsConversation=Show as conversation list -MessageListViewType=Show as table list - -# -# Ticket card -# -Ticket=Ticket -TicketCard=Ticket card -CreateTicket=Create ticket -EditTicket=Edit ticket -TicketsManagement=Tickets Management -CreatedBy=Created by -NewTicket=New Ticket -SubjectAnswerToTicket=Ticket answer -TicketTypeRequest=Request type -TicketCategory=Ticket categorization -SeeTicket=See ticket -TicketMarkedAsRead=Ticket has been marked as read -TicketReadOn=Read on -TicketCloseOn=Closing date -MarkAsRead=Mark ticket as read -TicketHistory=Ticket history -AssignUser=Assign to user -TicketAssigned=Ticket is now assigned -TicketChangeType=Change type -TicketChangeCategory=Change analytic code -TicketChangeSeverity=Change severity -TicketAddMessage=Add a message -AddMessage=Add a message -MessageSuccessfullyAdded=Ticket added -TicketMessageSuccessfullyAdded=Message successfully added -TicketMessagesList=Message list -NoMsgForThisTicket=No message for this ticket -Properties=Classification -LatestNewTickets=Latest %s newest tickets (not read) -TicketSeverity=Severity -ShowTicket=See ticket -RelatedTickets=Related tickets -TicketAddIntervention=Create intervention -CloseTicket=Close|Solve ticket -AbandonTicket=Abandon ticket -CloseATicket=Close|Solve a ticket -ConfirmCloseAticket=Confirm ticket closing -ConfirmAbandonTicket=Do you confirm the closing of the ticket to status 'Abandonned' -ConfirmDeleteTicket=Please confirm ticket deleting -TicketDeletedSuccess=Ticket deleted with success -TicketMarkedAsClosed=Ticket marked as closed -TicketDurationAuto=Calculated duration -TicketDurationAutoInfos=Duration calculated automatically from intervention related -TicketUpdated=Ticket updated -SendMessageByEmail=Send message by email -TicketNewMessage=New message -ErrorMailRecipientIsEmptyForSendTicketMessage=Recipient is empty. No email send -TicketGoIntoContactTab=Please go into "Contacts" tab to select them -TicketMessageMailIntro=Introduction -TicketMessageMailIntroHelp=This text is added only at the beginning of the email and will not be saved. -TicketMessageMailIntroLabelAdmin=Introduction to the message when sending email -TicketMessageMailIntroText=Hello,
    A new response was sent on a ticket that you contact. Here is the message:
    -TicketMessageMailIntroHelpAdmin=This text will be inserted before the text of the response to a ticket. -TicketMessageMailSignature=Signature -TicketMessageMailSignatureHelp=This text is added only at the end of the email and will not be saved. -TicketMessageMailSignatureText=

    Sincerely,

    --

    -TicketMessageMailSignatureLabelAdmin=Signature of response email -TicketMessageMailSignatureHelpAdmin=This text will be inserted after the response message. -TicketMessageHelp=Only this text will be saved in the message list on ticket card. -TicketMessageSubstitutionReplacedByGenericValues=Substitutions variables are replaced by generic values. -TimeElapsedSince=Time elapsed since -TicketTimeToRead=Time elapsed before read -TicketTimeElapsedBeforeSince=Time elapsed before / since -TicketContacts=Contacts ticket -TicketDocumentsLinked=Documents linked to ticket -ConfirmReOpenTicket=Confirm reopen this ticket ? -TicketMessageMailIntroAutoNewPublicMessage=A new message was posted on the ticket with the subject %s: -TicketAssignedToYou=Ticket assigned -TicketAssignedEmailBody=You have been assigned the ticket #%s by %s -MarkMessageAsPrivate=Mark message as private -TicketMessagePrivateHelp=This message will not display to external users -TicketEmailOriginIssuer=Issuer at origin of the tickets -InitialMessage=Initial Message -LinkToAContract=Link to a contract -TicketPleaseSelectAContract=Select a contract -UnableToCreateInterIfNoSocid=Can not create an intervention when no third party is defined -TicketMailExchanges=Mail exchanges -TicketInitialMessageModified=Initial message modified -TicketMessageSuccesfullyUpdated=Message successfully updated -TicketChangeStatus=Change status -TicketConfirmChangeStatus=Confirm the status change: %s ? -TicketLogStatusChanged=Status changed: %s to %s -TicketNotNotifyTiersAtCreate=Not notify company at create -Unread=Unread -TicketNotCreatedFromPublicInterface=Not available. Ticket was not created from public interface. -ErrorTicketRefRequired=Ticket reference name is required - -# -# Logs -# -TicketLogMesgReadBy=Ticket %s read by %s -NoLogForThisTicket=No log for this ticket yet -TicketLogAssignedTo=Ticket %s assigned to %s -TicketLogPropertyChanged=Ticket %s modified: classification from %s to %s -TicketLogClosedBy=Ticket %s closed by %s -TicketLogReopen=Ticket %s re-open - -# -# Public pages -# -TicketSystem=Ticket system -ShowListTicketWithTrackId=Display ticket list from track ID -ShowTicketWithTrackId=Display ticket from track ID -TicketPublicDesc=You can create a support ticket or check from an existing ID. -YourTicketSuccessfullySaved=Ticket has been successfully saved! -MesgInfosPublicTicketCreatedWithTrackId=A new ticket has been created with ID %s and Ref %s. -PleaseRememberThisId=Please keep the tracking number that we might ask you later. -TicketNewEmailSubject=Ticket creation confirmation - Ref %s (public ticket ID %s) -TicketNewEmailSubjectCustomer=New support ticket -TicketNewEmailBody=This is an automatic email to confirm you have registered a new ticket. -TicketNewEmailBodyCustomer=This is an automatic email to confirm a new ticket has just been created into your account. -TicketNewEmailBodyInfosTicket=Information for monitoring the ticket -TicketNewEmailBodyInfosTrackId=Ticket tracking number: %s -TicketNewEmailBodyInfosTrackUrl=You can view the progress of the ticket by clicking the link above. -TicketNewEmailBodyInfosTrackUrlCustomer=You can view the progress of the ticket in the specific interface by clicking the following link -TicketEmailPleaseDoNotReplyToThisEmail=Please do not reply directly to this email! Use the link to reply into the interface. -TicketPublicInfoCreateTicket=This form allows you to record a support ticket in our management system. -TicketPublicPleaseBeAccuratelyDescribe=Please accurately describe the problem. Provide the most information possible to allow us to correctly identify your request. -TicketPublicMsgViewLogIn=Please enter ticket tracking ID -TicketTrackId=Public Tracking ID -OneOfTicketTrackId=One of your tracking ID -ErrorTicketNotFound=Ticket with tracking ID %s not found! -Subject=Subject -ViewTicket=View ticket -ViewMyTicketList=View my ticket list -ErrorEmailMustExistToCreateTicket=Error: email address not found in our database -TicketNewEmailSubjectAdmin=New ticket created - Ref %s (public ticket ID %s) -TicketNewEmailBodyAdmin=

    Ticket has just been created with ID #%s, see information:

    -SeeThisTicketIntomanagementInterface=See ticket in management interface -TicketPublicInterfaceForbidden=The public interface for the tickets was not enabled -ErrorEmailOrTrackingInvalid=Bad value for tracking ID or email -OldUser=Old user -NewUser=New user -NumberOfTicketsByMonth=Number of tickets per month -NbOfTickets=Number of tickets -# notifications -TicketNotificationEmailSubject=Ticket %s updated -TicketNotificationEmailBody=This is an automatic message to notify you that ticket %s has just been updated -TicketNotificationRecipient=Notification recipient -TicketNotificationLogMessage=Log message -TicketNotificationEmailBodyInfosTrackUrlinternal=View ticket into interface -TicketNotificationNumberEmailSent=Notification email sent: %s - -ActionsOnTicket=Events on ticket - -# -# Boxes -# -BoxLastTicket=Latest created tickets -BoxLastTicketDescription=Latest %s created tickets -BoxLastTicketContent= -BoxLastTicketNoRecordedTickets=No recent unread tickets -BoxLastModifiedTicket=Latest modified tickets -BoxLastModifiedTicketDescription=Latest %s modified tickets -BoxLastModifiedTicketContent= -BoxLastModifiedTicketNoRecordedTickets=No recent modified tickets -BoxTicketType=Distribution of open tickets by type -BoxTicketSeverity=Number of open tickets by severity -BoxNoTicketSeverity=No tickets opened -BoxTicketLastXDays=Number of new tickets by days the last %s days -BoxTicketLastXDayswidget = Number of new tickets by days the last X days -BoxNoTicketLastXDays=No new tickets the last %s days -BoxNumberOfTicketByDay=Number of new tickets by day -BoxNewTicketVSClose=Number of today's new tickets versus today's closed tickets -TicketCreatedToday=Ticket created today -TicketClosedToday=Ticket closed today diff --git a/htdocs/langs/ar_IQ/trips.lang b/htdocs/langs/ar_IQ/trips.lang deleted file mode 100644 index c9a6c792077..00000000000 --- a/htdocs/langs/ar_IQ/trips.lang +++ /dev/null @@ -1,150 +0,0 @@ -# Dolibarr language file - Source file is en_US - trips -ShowExpenseReport=Show expense report -Trips=Expense reports -TripsAndExpenses=Expenses reports -TripsAndExpensesStatistics=Expense reports statistics -TripCard=Expense report card -AddTrip=Create expense report -ListOfTrips=List of expense reports -ListOfFees=List of fees -TypeFees=Types of fees -ShowTrip=Show expense report -NewTrip=New expense report -LastExpenseReports=Latest %s expense reports -AllExpenseReports=All expense reports -CompanyVisited=Company/organization visited -FeesKilometersOrAmout=Amount or kilometers -DeleteTrip=Delete expense report -ConfirmDeleteTrip=Are you sure you want to delete this expense report? -ListTripsAndExpenses=List of expense reports -ListToApprove=Waiting for approval -ExpensesArea=Expense reports area -ClassifyRefunded=Classify 'Refunded' -ExpenseReportWaitingForApproval=A new expense report has been submitted for approval -ExpenseReportWaitingForApprovalMessage=A new expense report has been submitted and is waiting for approval.
    - User: %s
    - Period: %s
    Click here to validate: %s -ExpenseReportWaitingForReApproval=An expense report has been submitted for re-approval -ExpenseReportWaitingForReApprovalMessage=An expense report has been submitted and is waiting for re-approval.
    The %s, you refused to approve the expense report for this reason: %s.
    A new version has been proposed and waiting for your approval.
    - User: %s
    - Period: %s
    Click here to validate: %s -ExpenseReportApproved=An expense report was approved -ExpenseReportApprovedMessage=The expense report %s was approved.
    - User: %s
    - Approved by: %s
    Click here to show the expense report: %s -ExpenseReportRefused=An expense report was refused -ExpenseReportRefusedMessage=The expense report %s was refused.
    - User: %s
    - Refused by: %s
    - Motive for refusal: %s
    Click here to show the expense report: %s -ExpenseReportCanceled=An expense report was canceled -ExpenseReportCanceledMessage=The expense report %s was canceled.
    - User: %s
    - Canceled by: %s
    - Motive for cancellation: %s
    Click here to show the expense report: %s -ExpenseReportPaid=An expense report was paid -ExpenseReportPaidMessage=The expense report %s was paid.
    - User: %s
    - Paid by: %s
    Click here to show the expense report: %s -TripId=Id expense report -AnyOtherInThisListCanValidate=Person to be informed for validating the request. -TripSociete=Information company -TripNDF=Informations expense report -PDFStandardExpenseReports=Standard template to generate a PDF document for expense report -ExpenseReportLine=Expense report line -TF_OTHER=Other -TF_TRIP=Transportation -TF_LUNCH=Lunch -TF_METRO=Metro -TF_TRAIN=Train -TF_BUS=Bus -TF_CAR=Car -TF_PEAGE=Toll -TF_ESSENCE=Fuel -TF_HOTEL=Hotel -TF_TAXI=Taxi -EX_KME=Mileage costs -EX_FUE=Fuel CV -EX_HOT=Hotel -EX_PAR=Parking CV -EX_TOL=Toll CV -EX_TAX=Various Taxes -EX_IND=Indemnity transportation subscription -EX_SUM=Maintenance supply -EX_SUO=Office supplies -EX_CAR=Car rental -EX_DOC=Documentation -EX_CUR=Customers receiving -EX_OTR=Other receiving -EX_POS=Postage -EX_CAM=CV maintenance and repair -EX_EMM=Employees meal -EX_GUM=Guests meal -EX_BRE=Breakfast -EX_FUE_VP=Fuel PV -EX_TOL_VP=Toll PV -EX_PAR_VP=Parking PV -EX_CAM_VP=PV maintenance and repair -DefaultCategoryCar=Default transportation mode -DefaultRangeNumber=Default range number -UploadANewFileNow=Upload a new document now -Error_EXPENSEREPORT_ADDON_NotDefined=Error, the rule for expense report numbering ref was not defined into setup of module 'Expense Report' -ErrorDoubleDeclaration=You have declared another expense report into a similar date range. -AucuneLigne=There is no expense report declared yet -ModePaiement=Payment mode -VALIDATOR=User responsible for approval -VALIDOR=Approved by -AUTHOR=Recorded by -AUTHORPAIEMENT=Paid by -REFUSEUR=Denied by -CANCEL_USER=Deleted by -MOTIF_REFUS=Reason -MOTIF_CANCEL=Reason -DATE_REFUS=Deny date -DATE_SAVE=Validation date -DATE_CANCEL=Cancelation date -DATE_PAIEMENT=Payment date -ExpenseReportRef=Ref. expense report -ValidateAndSubmit=Validate and submit for approval -ValidatedWaitingApproval=Validated (waiting for approval) -NOT_AUTHOR=You are not the author of this expense report. Operation cancelled. -ConfirmRefuseTrip=Are you sure you want to deny this expense report? -ValideTrip=Approve expense report -ConfirmValideTrip=Are you sure you want to approve this expense report? -PaidTrip=Pay an expense report -ConfirmPaidTrip=Are you sure you want to change status of this expense report to "Paid"? -ConfirmCancelTrip=Are you sure you want to cancel this expense report? -BrouillonnerTrip=Move back expense report to status "Draft" -ConfirmBrouillonnerTrip=Are you sure you want to move this expense report to status "Draft"? -SaveTrip=Validate expense report -ConfirmSaveTrip=Are you sure you want to validate this expense report? -NoTripsToExportCSV=No expense report to export for this period. -ExpenseReportPayment=Expense report payment -ExpenseReportsToApprove=Expense reports to approve -ExpenseReportsToPay=Expense reports to pay -ConfirmCloneExpenseReport=Are you sure you want to clone this expense report ? -ExpenseReportsIk=Configuration of mileage charges -ExpenseReportsRules=Expense report rules -ExpenseReportIkDesc=You can modify the calculation of kilometers expense by category and range who they are previously defined. d is the distance in kilometers -ExpenseReportRulesDesc=You can create or update any rules of calculation. This part will be used when user will create a new expense report -expenseReportOffset=Offset -expenseReportCoef=Coefficient -expenseReportTotalForFive=Example with d = 5 -expenseReportRangeFromTo=from %d to %d -expenseReportRangeMoreThan=more than %d -expenseReportCoefUndefined=(value not defined) -expenseReportCatDisabled=Category disabled - see the c_exp_tax_cat dictionary -expenseReportRangeDisabled=Range disabled - see the c_exp_tax_range dictionay -expenseReportPrintExample=offset + (d x coef) = %s -ExpenseReportApplyTo=Apply to -ExpenseReportDomain=Domain to apply -ExpenseReportLimitOn=Limit on -ExpenseReportDateStart=Date start -ExpenseReportDateEnd=Date end -ExpenseReportLimitAmount=Limite amount -ExpenseReportRestrictive=Restrictive -AllExpenseReport=All type of expense report -OnExpense=Expense line -ExpenseReportRuleSave=Expense report rule saved -ExpenseReportRuleErrorOnSave=Error: %s -RangeNum=Range %d -ExpenseReportConstraintViolationError=Constraint violation id [%s]: %s is superior to %s %s -byEX_DAY=by day (limitation to %s) -byEX_MON=by month (limitation to %s) -byEX_YEA=by year (limitation to %s) -byEX_EXP=by line (limitation to %s) -ExpenseReportConstraintViolationWarning=Constraint violation id [%s]: %s is superior to %s %s -nolimitbyEX_DAY=by day (no limitation) -nolimitbyEX_MON=by month (no limitation) -nolimitbyEX_YEA=by year (no limitation) -nolimitbyEX_EXP=by line (no limitation) -CarCategory=Vehicle category -ExpenseRangeOffset=Offset amount: %s -RangeIk=Mileage range -AttachTheNewLineToTheDocument=Attach the line to an uploaded document diff --git a/htdocs/langs/ar_IQ/users.lang b/htdocs/langs/ar_IQ/users.lang index 6aeaf128838..fd9215f98df 100644 --- a/htdocs/langs/ar_IQ/users.lang +++ b/htdocs/langs/ar_IQ/users.lang @@ -1,126 +1,3 @@ # Dolibarr language file - Source file is en_US - users -HRMArea=HRM area -UserCard=User card -GroupCard=Group card -Permission=Permission -Permissions=Permissions -EditPassword=Edit password -SendNewPassword=Regenerate and send password -SendNewPasswordLink=Send link to reset password -ReinitPassword=Regenerate password -PasswordChangedTo=Password changed to: %s -SubjectNewPassword=Your new password for %s -GroupRights=Group permissions -UserRights=User permissions -Credentials=Credentials -UserGUISetup=User Display Setup -DisableUser=Disable -DisableAUser=Disable a user -DeleteUser=Delete -DeleteAUser=Delete a user -EnableAUser=Enable a user -DeleteGroup=Delete -DeleteAGroup=Delete a group -ConfirmDisableUser=Are you sure you want to disable user %s? -ConfirmDeleteUser=Are you sure you want to delete user %s? -ConfirmDeleteGroup=Are you sure you want to delete group %s? -ConfirmEnableUser=Are you sure you want to enable user %s? -ConfirmReinitPassword=Are you sure you want to generate a new password for user %s? -ConfirmSendNewPassword=Are you sure you want to generate and send new password for user %s? -NewUser=New user -CreateUser=Create user -LoginNotDefined=Login is not defined. -NameNotDefined=Name is not defined. -ListOfUsers=List of users -SuperAdministrator=Super Administrator -SuperAdministratorDesc=Global administrator -AdministratorDesc=Administrator -DefaultRights=Default Permissions -DefaultRightsDesc=Define here the default permissions that are automatically granted to a new user (to modify permissions for existing users, go to the user card). -DolibarrUsers=Dolibarr users -LastName=Last name -FirstName=First name -ListOfGroups=List of groups -NewGroup=New group -CreateGroup=Create group -RemoveFromGroup=Remove from group -PasswordChangedAndSentTo=Password changed and sent to %s. -PasswordChangeRequest=Request to change password for %s -PasswordChangeRequestSent=Request to change password for %s sent to %s. -IfLoginExistPasswordRequestSent=If this login is a valid account, an email to reset password has been sent. -IfEmailExistPasswordRequestSent=If this email is a valid account, an email to reset password has been sent. -ConfirmPasswordReset=Confirm password reset -MenuUsersAndGroups=Users & Groups -LastGroupsCreated=Latest %s groups created -LastUsersCreated=Latest %s users created -ShowGroup=Show group -ShowUser=Show user -NonAffectedUsers=Non assigned users -UserModified=User modified successfully -PhotoFile=Photo file -ListOfUsersInGroup=List of users in this group -ListOfGroupsForUser=List of groups for this user -LinkToCompanyContact=Link to third party / contact -LinkedToDolibarrMember=Link to member LinkedToDolibarrUser=Link to Dolibarr user LinkedToDolibarrThirdParty=Link to Dolibarr third party -CreateDolibarrLogin=Create a user -CreateDolibarrThirdParty=Create a third party -LoginAccountDisableInDolibarr=Account disabled in Dolibarr. -UsePersonalValue=Use personal value -InternalUser=Internal user -ExportDataset_user_1=Users and their properties -DomainUser=Domain user %s -Reactivate=Reactivate -CreateInternalUserDesc=This form allows you to create an internal user in your company/organization. To create an external user (customer, vendor etc. ..), use the button 'Create Dolibarr User' from that third-party's contact card. -InternalExternalDesc=An internal user is a user that is part of your company/organization, or is a partner user outside of your organization that may need to see more data than data related to his company (the permission system will define what he can or can't see or do).
    An external user is a customer, vendor or other that must view ONLY data related to himself (Creating an external user for a third-party can be done from the contact record of the third-party).

    In both cases, you must grant permissions on the features that the user need. -PermissionInheritedFromAGroup=Permission granted because inherited from one of a user's group. -Inherited=Inherited -UserWillBe=Created user will be -UserWillBeInternalUser=Created user will be an internal user (because not linked to a particular third party) -UserWillBeExternalUser=Created user will be an external user (because linked to a particular third party) -IdPhoneCaller=Id phone caller -NewUserCreated=User %s created -NewUserPassword=Password change for %s -NewPasswordValidated=Your new password have been validated and must be used now to login. -EventUserModified=User %s modified -UserDisabled=User %s disabled -UserEnabled=User %s activated -UserDeleted=User %s removed -NewGroupCreated=Group %s created -GroupModified=Group %s modified -GroupDeleted=Group %s removed -ConfirmCreateContact=Are you sure you want to create a Dolibarr account for this contact? -ConfirmCreateLogin=Are you sure you want to create a Dolibarr account for this member? -ConfirmCreateThirdParty=Are you sure you want to create a third party for this member? -LoginToCreate=Login to create -NameToCreate=Name of third party to create -YourRole=Your roles -YourQuotaOfUsersIsReached=Your quota of active users is reached ! -NbOfUsers=Number of users -NbOfPermissions=Number of permissions -DontDowngradeSuperAdmin=Only a superadmin can downgrade a superadmin -HierarchicalResponsible=Supervisor -HierarchicView=Hierarchical view -UseTypeFieldToChange=Use field Type to change -OpenIDURL=OpenID URL -LoginUsingOpenID=Use OpenID to login -WeeklyHours=Hours worked (per week) -ExpectedWorkedHours=Expected hours worked per week -ColorUser=Color of the user -DisabledInMonoUserMode=Disabled in maintenance mode -UserAccountancyCode=User accounting code -UserLogoff=User logout -UserLogged=User logged -DateOfEmployment=Employment date -DateEmployment=Employment -DateEmploymentstart=Employment Start Date -DateEmploymentEnd=Employment End Date -RangeOfLoginValidity=Access validity date range -CantDisableYourself=You can't disable your own user record -ForceUserExpenseValidator=Force expense report validator -ForceUserHolidayValidator=Force leave request validator -ValidatorIsSupervisorByDefault=By default, the validator is the supervisor of the user. Keep empty to keep this behaviour. -UserPersonalEmail=Personal email -UserPersonalMobile=Personal mobile phone -WarningNotLangOfInterface=Warning, this is the main language the user speak, not the language of the interface he choosed to see. To change the interface language visible by this user, go on tab %s diff --git a/htdocs/langs/ar_IQ/website.lang b/htdocs/langs/ar_IQ/website.lang deleted file mode 100644 index dc2ec2c0b3d..00000000000 --- a/htdocs/langs/ar_IQ/website.lang +++ /dev/null @@ -1,147 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -Shortname=Code -WebsiteSetupDesc=Create here the websites you wish to use. Then go into menu Websites to edit them. -DeleteWebsite=Delete website -ConfirmDeleteWebsite=Are you sure you want to delete this web site? All its pages and content will also be removed. The files uploaded (like into the medias directory, the ECM module, ...) will remain. -WEBSITE_TYPE_CONTAINER=Type of page/container -WEBSITE_PAGE_EXAMPLE=Web page to use as example -WEBSITE_PAGENAME=Page name/alias -WEBSITE_ALIASALT=Alternative page names/aliases -WEBSITE_ALIASALTDesc=Use here list of other name/aliases so the page can also be accessed using this other names/aliases (for example the old name after renaming the alias to keep backlink on old link/name working). Syntax is:
    alternativename1, alternativename2, ... -WEBSITE_CSS_URL=URL of external CSS file -WEBSITE_CSS_INLINE=CSS file content (common to all pages) -WEBSITE_JS_INLINE=Javascript file content (common to all pages) -WEBSITE_HTML_HEADER=Addition at bottom of HTML Header (common to all pages) -WEBSITE_ROBOT=Robot file (robots.txt) -WEBSITE_HTACCESS=Website .htaccess file -WEBSITE_MANIFEST_JSON=Website manifest.json file -WEBSITE_README=README.md file -WEBSITE_KEYWORDSDesc=Use a comma to separate values -EnterHereLicenseInformation=Enter here meta data or license information to fille a README.md file. if you distribute your website as a template, the file will be included into the temptate package. -HtmlHeaderPage=HTML header (specific to this page only) -PageNameAliasHelp=Name or alias of the page.
    This alias is also used to forge a SEO URL when website is ran from a Virtual host of a Web server (like Apacke, Nginx, ...). Use the button "%s" to edit this alias. -EditTheWebSiteForACommonHeader=Note: If you want to define a personalized header for all pages, edit the header on the site level instead of on the page/container. -MediaFiles=Media library -EditCss=Edit website properties -EditMenu=Edit menu -EditMedias=Edit medias -EditPageMeta=Edit page/container properties -EditInLine=Edit inline -AddWebsite=Add website -Webpage=Web page/container -AddPage=Add page/container -PageContainer=Page -PreviewOfSiteNotYetAvailable=The preview of your website %s is not yet available. You must first 'Import a full website template' or just 'Add a page/container'. -RequestedPageHasNoContentYet=Requested page with id %s has no content yet, or cache file .tpl.php was removed. Edit content of the page to solve this. -SiteDeleted=Web site '%s' deleted -PageContent=Page/Contenair -PageDeleted=Page/Contenair '%s' of website %s deleted -PageAdded=Page/Contenair '%s' added -ViewSiteInNewTab=View site in new tab -ViewPageInNewTab=View page in new tab -SetAsHomePage=Set as Home page -RealURL=Real URL -ViewWebsiteInProduction=View web site using home URLs -SetHereVirtualHost=Use with Apache/NGinx/...
    Create on your web server (Apache, Nginx, ...) a dedicated Virtual Host with PHP enabled and a Root directory on
    %s -ExampleToUseInApacheVirtualHostConfig=Example to use in Apache virtual host setup: -YouCanAlsoTestWithPHPS=Use with PHP embedded server
    On develop environment, you may prefer to test the site with the PHP embedded web server (PHP 5.5 required) by running
    php -S 0.0.0.0:8080 -t %s -YouCanAlsoDeployToAnotherWHP=Run your web site with another Dolibarr Hosting provider
    If you don't have a web server like Apache or NGinx available on internet, you can export and import your web site onto another Dolibarr instance provided by another Dolibarr hosting provider that provide full integration with the Website module. You can find a list of some Dolibarr hosting providers on https://saas.dolibarr.org -CheckVirtualHostPerms=Check also that the virtual host user (for example www-data) has %s permissions on files into
    %s -ReadPerm=Read -WritePerm=Write -TestDeployOnWeb=Test/deploy on web -PreviewSiteServedByWebServer=Preview %s in a new tab.

    The %s will be served by an external web server (like Apache, Nginx, IIS). You must install and setup this server before to point to directory:
    %s
    URL served by external server:
    %s -PreviewSiteServedByDolibarr=Preview %s in a new tab.

    The %s will be served by Dolibarr server so it does not need any extra web server (like Apache, Nginx, IIS) to be installed.
    The inconvenient is that the URLs of pages are not user friendly and start with the path of your Dolibarr.
    URL served by Dolibarr:
    %s

    To use your own external web server to serve this web site, create a virtual host on your web server that points on directory
    %s
    then enter the name of this virtual server in the properties of this website and click on the link "Test/Deploy on the web". -VirtualHostUrlNotDefined=URL of the virtual host served by external web server not defined -NoPageYet=No pages yet -YouCanCreatePageOrImportTemplate=You can create a new page or import a full website template -SyntaxHelp=Help on specific syntax tips -YouCanEditHtmlSourceckeditor=You can edit HTML source code using the "Source" button in editor. -YouCanEditHtmlSource=
    You can include PHP code into this source using tags <?php ?>. The following global variables are available: $conf, $db, $mysoc, $user, $website, $websitepage, $weblangs, $pagelangs.

    You can also include content of another Page/Container with the following syntax:
    <?php includeContainer('alias_of_container_to_include'); ?>

    You can make a redirect to another Page/Container with the following syntax (Note: do not output any content before a redirect):
    <?php redirectToContainer('alias_of_container_to_redirect_to'); ?>

    To add a link to another page, use the syntax:
    <a href="alias_of_page_to_link_to.php">mylink<a>

    To include a link to download a file stored into the documents directory, use the document.php wrapper:
    Example, for a file into documents/ecm (need to be logged), syntax is:
    <a href="/document.php?modulepart=ecm&file=[relative_dir/]filename.ext">
    For a file into documents/medias (open directory for public access), syntax is:
    <a href="/document.php?modulepart=medias&file=[relative_dir/]filename.ext">
    For a file shared with a share link (open access using the sharing hash key of file), syntax is:
    <a href="/document.php?hashp=publicsharekeyoffile">

    To include an image stored into the documents directory, use the viewimage.php wrapper:
    Example, for an image into documents/medias (open directory for public access), syntax is:
    <img src="/viewimage.php?modulepart=medias&file=[relative_dir/]filename.ext">
    -#YouCanEditHtmlSource2=
    To include a image shared publicaly, use the viewimage.php wrapper:
    Example with a shared key 123456789, syntax is:
    <img src="/viewimage.php?hashp=12345679012...">
    -YouCanEditHtmlSource2=For an image shared with a share link (open access using the sharing hash key of file), syntax is:
    <img src="/viewimage.php?hashp=12345679012...">
    -YouCanEditHtmlSourceMore=
    More examples of HTML or dynamic code available on the wiki documentation
    . -ClonePage=Clone page/container -CloneSite=Clone site -SiteAdded=Website added -ConfirmClonePage=Please enter code/alias of new page and if it is a translation of the cloned page. -PageIsANewTranslation=The new page is a translation of the current page ? -LanguageMustNotBeSameThanClonedPage=You clone a page as a translation. The language of the new page must be different than language of source page. -ParentPageId=Parent page ID -WebsiteId=Website ID -CreateByFetchingExternalPage=Create page/container by fetching page from external URL... -OrEnterPageInfoManually=Or create page from scratch or from a page template... -FetchAndCreate=Fetch and Create -ExportSite=Export website -ImportSite=Import website template -IDOfPage=Id of page -Banner=Banner -BlogPost=Blog post -WebsiteAccount=Website account -WebsiteAccounts=Website accounts -AddWebsiteAccount=Create web site account -BackToListForThirdParty=Back to list for the third-party -DisableSiteFirst=Disable website first -MyContainerTitle=My web site title -AnotherContainer=This is how to include content of another page/container (you may have an error here if you enable dynamic code because the embedded subcontainer may not exists) -SorryWebsiteIsCurrentlyOffLine=Sorry, this website is currently off line. Please comme back later... -WEBSITE_USE_WEBSITE_ACCOUNTS=Enable the web site account table -WEBSITE_USE_WEBSITE_ACCOUNTSTooltip=Enable the table to store web site accounts (login/pass) for each website / third party -YouMustDefineTheHomePage=You must first define the default Home page -OnlyEditionOfSourceForGrabbedContentFuture=Warning: Creating a web page by importing an external web page is reserved for experienced users. Depending on the complexity of source page, the result of importation may differ from the original. Also if the source page uses common CSS styles or conflicting javascript, it may break the look or features of the Website editor when working on this page. This method is a quicker way to create a page but it is recommended to create your new page from scratch or from a suggested page template.
    Note also that the inline editor may not works correclty when used on a grabbed external page. -OnlyEditionOfSourceForGrabbedContent=Only edition of HTML source is possible when content was grabbed from an external site -GrabImagesInto=Grab also images found into css and page. -ImagesShouldBeSavedInto=Images should be saved into directory -WebsiteRootOfImages=Root directory for website images -SubdirOfPage=Sub-directory dedicated to page -AliasPageAlreadyExists=Alias page %s already exists -CorporateHomePage=Corporate Home page -EmptyPage=Empty page -ExternalURLMustStartWithHttp=External URL must start with http:// or https:// -ZipOfWebsitePackageToImport=Upload the Zip file of the website template package -ZipOfWebsitePackageToLoad=or Choose an available embedded website template package -ShowSubcontainers=Show dynamic content -InternalURLOfPage=Internal URL of page -ThisPageIsTranslationOf=This page/container is a translation of -ThisPageHasTranslationPages=This page/container has translation -NoWebSiteCreateOneFirst=No website has been created yet. Create one first. -GoTo=Go to -DynamicPHPCodeContainsAForbiddenInstruction=You add dynamic PHP code that contains the PHP instruction '%s' that is forbidden by default as dynamic content (see hidden options WEBSITE_PHP_ALLOW_xxx to increase list of allowed commands). -NotAllowedToAddDynamicContent=You don't have permission to add or edit PHP dynamic content in websites. Ask permission or just keep code into php tags unmodified. -ReplaceWebsiteContent=Search or Replace website content -DeleteAlsoJs=Delete also all javascript files specific to this website? -DeleteAlsoMedias=Delete also all medias files specific to this website? -MyWebsitePages=My website pages -SearchReplaceInto=Search | Replace into -ReplaceString=New string -CSSContentTooltipHelp=Enter here CSS content. To avoid any conflict with the CSS of the application, be sure to prepend all declaration with the .bodywebsite class. For example:

    #mycssselector, input.myclass:hover { ... }
    must be
    .bodywebsite #mycssselector, .bodywebsite input.myclass:hover { ... }

    Note: If you have a large file without this prefix, you can use 'lessc' to convert it to append the .bodywebsite prefix everywhere. -LinkAndScriptsHereAreNotLoadedInEditor=Warning: This content is output only when site is accessed from a server. It is not used in Edit mode so if you need to load javascript files also in edit mode, just add your tag 'script src=...' into the page. -Dynamiccontent=Sample of a page with dynamic content -ImportSite=Import website template -EditInLineOnOff=Mode 'Edit inline' is %s -ShowSubContainersOnOff=Mode to execute 'dynamic content' is %s -GlobalCSSorJS=Global CSS/JS/Header file of web site -BackToHomePage=Back to home page... -TranslationLinks=Translation links -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
    (ref=%s, type=%s, status=%s) -UseTextBetween5And70Chars=For good SEO practices, use a text between 5 and 70 characters -MainLanguage=Main language -OtherLanguages=Other languages -UseManifest=Provide a manifest.json file -PublicAuthorAlias=Public author alias -AvailableLanguagesAreDefinedIntoWebsiteProperties=Available languages are defined into website properties -ReplacementDoneInXPages=Replacement done in %s pages or containers -RSSFeed=RSS Feed -RSSFeedDesc=You can get a RSS feed of latest articles with type 'blogpost' using this URL -PagesRegenerated=%s page(s)/container(s) regenerated -RegenerateWebsiteContent=Regenerate web site cache files -AllowedInFrames=Allowed in Frames -DefineListOfAltLanguagesInWebsiteProperties=Define list of all available languages into web site properties. -GenerateSitemaps=Generate website sitemap file -ConfirmGenerateSitemaps=If you confirm, you will erase the existing sitemap file... -ConfirmSitemapsCreation=Confirm sitemap generation -SitemapGenerated=Sitemap file %s generated -ImportFavicon=Favicon -ErrorFaviconType=Favicon must be png -ErrorFaviconSize=Favicon must be sized 16x16, 32x32 or 64x64 -FaviconTooltip=Upload an image which needs to be a png (16x16, 32x32 or 64x64) diff --git a/htdocs/langs/ar_IQ/withdrawals.lang b/htdocs/langs/ar_IQ/withdrawals.lang deleted file mode 100644 index a3773a427a1..00000000000 --- a/htdocs/langs/ar_IQ/withdrawals.lang +++ /dev/null @@ -1,152 +0,0 @@ -# Dolibarr language file - Source file is en_US - withdrawals -CustomersStandingOrdersArea=Payments by Direct debit orders -SuppliersStandingOrdersArea=Payments by Credit transfer -StandingOrdersPayment=Direct debit payment orders -StandingOrderPayment=Direct debit payment order -NewStandingOrder=New direct debit order -NewPaymentByBankTransfer=New payment by credit transfer -StandingOrderToProcess=To process -PaymentByBankTransferReceipts=Credit transfer orders -PaymentByBankTransferLines=Credit transfer order lines -WithdrawalsReceipts=Direct debit orders -WithdrawalReceipt=Direct debit order -BankTransferReceipts=Credit transfer orders -BankTransferReceipt=Credit transfer order -LatestBankTransferReceipts=Latest %s credit transfer orders -LastWithdrawalReceipts=Latest %s direct debit files -WithdrawalsLine=Direct debit order line -CreditTransferLine=Credit transfer line -WithdrawalsLines=Direct debit order lines -CreditTransferLines=Credit transfer lines -RequestStandingOrderToTreat=Requests for direct debit payment order to process -RequestStandingOrderTreated=Requests for direct debit payment order processed -RequestPaymentsByBankTransferToTreat=Requests for credit transfer to process -RequestPaymentsByBankTransferTreated=Requests for credit transfer processed -NotPossibleForThisStatusOfWithdrawReceiptORLine=Not yet possible. Withdraw status must be set to 'credited' before declaring reject on specific lines. -NbOfInvoiceToWithdraw=No. of qualified customer invoices with waiting direct debit order -NbOfInvoiceToWithdrawWithInfo=No. of customer invoice with direct debit payment orders having defined bank account information -NbOfInvoiceToPayByBankTransfer=No. of qualified supplier invoices waiting for a payment by credit transfer -SupplierInvoiceWaitingWithdraw=Vendor invoice waiting for payment by credit transfer -InvoiceWaitingWithdraw=Invoice waiting for direct debit -InvoiceWaitingPaymentByBankTransfer=Invoice waiting for credit transfer -AmountToWithdraw=Amount to withdraw -NoInvoiceToWithdraw=No invoice open for '%s' is waiting. Go on tab '%s' on invoice card to make a request. -NoSupplierInvoiceToWithdraw=No supplier invoice with open 'Direct credit requests' is waiting. Go on tab '%s' on invoice card to make a request. -ResponsibleUser=User Responsible -WithdrawalsSetup=Direct debit payment setup -CreditTransferSetup=Credit transfer setup -WithdrawStatistics=Direct debit payment statistics -CreditTransferStatistics=Credit transfer statistics -Rejects=Rejects -LastWithdrawalReceipt=Latest %s direct debit receipts -MakeWithdrawRequest=Make a direct debit payment request -MakeBankTransferOrder=Make a credit transfer request -WithdrawRequestsDone=%s direct debit payment requests recorded -BankTransferRequestsDone=%s credit transfer requests recorded -ThirdPartyBankCode=Third-party bank code -NoInvoiceCouldBeWithdrawed=No invoice debited successfully. Check that invoices are on companies with a valid IBAN and that IBAN has a UMR (Unique Mandate Reference) with mode %s. -WithdrawalCantBeCreditedTwice=This withdrawal receipt is already marked as credited; this can't be done twice, as this would potentially create duplicate payments and bank entries. -ClassCredited=Classify credited -ClassCreditedConfirm=Are you sure you want to classify this withdrawal receipt as credited on your bank account? -TransData=Transmission date -TransMetod=Transmission method -Send=Send -Lines=Lines -StandingOrderReject=Issue a rejection -WithdrawsRefused=Direct debit refused -WithdrawalRefused=Withdrawal refused -CreditTransfersRefused=Credit transfers refused -WithdrawalRefusedConfirm=Are you sure you want to enter a withdrawal rejection for society -RefusedData=Date of rejection -RefusedReason=Reason for rejection -RefusedInvoicing=Billing the rejection -NoInvoiceRefused=Do not charge the rejection -InvoiceRefused=Invoice refused (Charge the rejection to customer) -StatusDebitCredit=Status debit/credit -StatusWaiting=Waiting -StatusTrans=Sent -StatusDebited=Debited -StatusCredited=Credited -StatusPaid=Paid -StatusRefused=Refused -StatusMotif0=Unspecified -StatusMotif1=Insufficient funds -StatusMotif2=Request contested -StatusMotif3=No direct debit payment order -StatusMotif4=Sales Order -StatusMotif5=RIB unusable -StatusMotif6=Account without balance -StatusMotif7=Judicial Decision -StatusMotif8=Other reason -CreateForSepaFRST=Create direct debit file (SEPA FRST) -CreateForSepaRCUR=Create direct debit file (SEPA RCUR) -CreateAll=Create direct debit file (all) -CreateFileForPaymentByBankTransfer=Create file for credit transfer -CreateSepaFileForPaymentByBankTransfer=Create credit transfer file (SEPA) -CreateGuichet=Only office -CreateBanque=Only bank -OrderWaiting=Waiting for treatment -NotifyTransmision=Record file transmission of order -NotifyCredit=Record credit of order -NumeroNationalEmetter=National Transmitter Number -WithBankUsingRIB=For bank accounts using RIB -WithBankUsingBANBIC=For bank accounts using IBAN/BIC/SWIFT -BankToReceiveWithdraw=Receiving Bank Account -BankToPayCreditTransfer=Bank Account used as source of payments -CreditDate=Credit on -WithdrawalFileNotCapable=Unable to generate withdrawal receipt file for your country %s (Your country is not supported) -ShowWithdraw=Show Direct Debit Order -IfInvoiceNeedOnWithdrawPaymentWontBeClosed=However, if invoice has at least one direct debit payment order not yet processed, it won't be set as paid to allow prior withdrawal management. -DoStandingOrdersBeforePayments=This tab allows you to request a direct debit payment order. Once done, go into menu Bank->Payment by direct debit to generate and manage the direct debit order. When direct debit order is closed, payment on invoices will be automatically recorded, and invoices closed if remainder to pay is null. -DoCreditTransferBeforePayments=This tab allows you to request a credit transfer order. Once done, go into menu Bank->Payment by credit transfer to generate and manage the credit transfer order. When credit transfer order is closed, payment on invoices will be automatically recorded, and invoices closed if remainder to pay is null. -WithdrawalFile=Debit order file -CreditTransferFile=Credit transfer file -SetToStatusSent=Set to status "File Sent" -ThisWillAlsoAddPaymentOnInvoice=This will also record payments on invoices and will classify them as "Paid" if remain to pay is null -StatisticsByLineStatus=Statistics by status of lines -RUM=UMR -DateRUM=Mandate signature date -RUMLong=Unique Mandate Reference -RUMWillBeGenerated=If empty, a UMR (Unique Mandate Reference) will be generated once the bank account information is saved. -WithdrawMode=Direct debit mode (FRST or RECUR) -WithdrawRequestAmount=Amount of Direct debit request: -BankTransferAmount=Amount of Credit Transfer request: -WithdrawRequestErrorNilAmount=Unable to create direct debit request for empty amount. -SepaMandate=SEPA Direct Debit Mandate -SepaMandateShort=SEPA Mandate -PleaseReturnMandate=Please return this mandate form by email to %s or by mail to -SEPALegalText=By signing this mandate form, you authorize (A) %s to send instructions to your bank to debit your account and (B) your bank to debit your account in accordance with the instructions from %s. As part of your rights, you are entitled to a refund from your bank under the terms and conditions of your agreement with your bank. A refund must be claimed within 8 weeks starting from the date on which your account was debited. Your rights regarding the above mandate are explained in a statement that you can obtain from your bank. -CreditorIdentifier=Creditor Identifier -CreditorName=Creditor Name -SEPAFillForm=(B) Please complete all the fields marked * -SEPAFormYourName=Your name -SEPAFormYourBAN=Your Bank Account Name (IBAN) -SEPAFormYourBIC=Your Bank Identifier Code (BIC) -SEPAFrstOrRecur=Type of payment -ModeRECUR=Recurring payment -ModeFRST=One-off payment -PleaseCheckOne=Please check one only -CreditTransferOrderCreated=Credit transfer order %s created -DirectDebitOrderCreated=Direct debit order %s created -AmountRequested=Amount requested -SEPARCUR=SEPA CUR -SEPAFRST=SEPA FRST -ExecutionDate=Execution date -CreateForSepa=Create direct debit file -ICS=Creditor Identifier - ICS -END_TO_END="EndToEndId" SEPA XML tag - Unique id assigned per transaction -USTRD="Unstructured" SEPA XML tag -ADDDAYS=Add days to Execution Date -NoDefaultIBANFound=No default IBAN found for this third party -### Notifications -InfoCreditSubject=Payment of direct debit payment order %s by the bank -InfoCreditMessage=The direct debit payment order %s has been paid by the bank
    Data of payment: %s -InfoTransSubject=Transmission of direct debit payment order %s to bank -InfoTransMessage=The direct debit payment order %s has been sent to bank by %s %s.

    -InfoTransData=Amount: %s
    Method: %s
    Date: %s -InfoRejectSubject=Direct debit payment order refused -InfoRejectMessage=Hello,

    the direct debit payment order of invoice %s related to the company %s, with an amount of %s has been refused by the bank.

    --
    %s -ModeWarning=Option for real mode was not set, we stop after this simulation -ErrorCompanyHasDuplicateDefaultBAN=Company with id %s has more than one default bank account. No way to know wich one to use. -ErrorICSmissing=Missing ICS in Bank account %s -TotalAmountOfdirectDebitOrderDiffersFromSumOfLines=Total amount of direct debit order differs from sum of lines diff --git a/htdocs/langs/ar_IQ/workflow.lang b/htdocs/langs/ar_IQ/workflow.lang deleted file mode 100644 index adfe7f69609..00000000000 --- a/htdocs/langs/ar_IQ/workflow.lang +++ /dev/null @@ -1,26 +0,0 @@ -# Dolibarr language file - Source file is en_US - workflow -WorkflowSetup=Workflow module setup -WorkflowDesc=This module provides some automatic actions. By default, the workflow is open (you can do things in the order you want) but here you can activate some automatic actions. -ThereIsNoWorkflowToModify=There is no workflow modifications available with the activated modules. -# Autocreate -descWORKFLOW_PROPAL_AUTOCREATE_ORDER=Automatically create a sales order after a commercial proposal is signed (the new order will have same amount as the proposal) -descWORKFLOW_PROPAL_AUTOCREATE_INVOICE=Automatically create a customer invoice after a commercial proposal is signed (the new invoice will have same amount as the proposal) -descWORKFLOW_CONTRACT_AUTOCREATE_INVOICE=Automatically create a customer invoice after a contract is validated -descWORKFLOW_ORDER_AUTOCREATE_INVOICE=Automatically create a customer invoice after a sales order is closed (the new invoice will have same amount as the order) -# Autoclassify customer proposal or order -descWORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL=Classify linked source proposal as billed when sales order is set to billed (and if the amount of the order is the same as the total amount of the signed linked proposal) -descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classify linked source proposal as billed when customer invoice is validated (and if the amount of the invoice is the same as the total amount of the signed linked proposal) -descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source sales order as billed when customer invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order) -descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source sales order as billed when customer invoice is set to paid (and if the amount of the invoice is the same as the total amount of the linked order) -descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source sales order as shipped when a shipment is validated (and if the quantity shipped by all shipments is the same as in the order to update) -descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED=Classify linked source sales order as shipped when a shipment is closed (and if the quantity shipped by all shipments is the same as in the order to update) -# Autoclassify purchase order -descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source vendor proposal as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked proposal) -descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source purchase order as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order) -descWORKFLOW_BILL_ON_RECEPTION=Classify receptions to "billed" when a linked supplier order is validated -# Autoclose intervention -descWORKFLOW_TICKET_CLOSE_INTERVENTION=Close all interventions linked to the ticket when a ticket is closed -AutomaticCreation=Automatic creation -AutomaticClassification=Automatic classification -# Autoclassify shipment -descWORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE=Classify linked source shipment as closed when customer invoice is validated diff --git a/htdocs/langs/ar_IQ/zapier.lang b/htdocs/langs/ar_IQ/zapier.lang deleted file mode 100644 index b4cc4ccba4a..00000000000 --- a/htdocs/langs/ar_IQ/zapier.lang +++ /dev/null @@ -1,21 +0,0 @@ -# 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 . - -ModuleZapierForDolibarrName = Zapier for Dolibarr -ModuleZapierForDolibarrDesc = Zapier for Dolibarr module -ZapierForDolibarrSetup=Setup of Zapier for Dolibarr -ZapierDescription=Interface with Zapier -ZapierAbout=About the module Zapier -ZapierSetupPage=There is no need for a setup on Dolibarr side to use Zapier. However, you must generate and publish a package on zapier to be able to use Zapier with Dolibarr. See documentation on this wiki page. diff --git a/htdocs/langs/ar_SA/mrp.lang b/htdocs/langs/ar_SA/mrp.lang index 97c6e6378bb..fe2c1a87769 100644 --- a/htdocs/langs/ar_SA/mrp.lang +++ b/htdocs/langs/ar_SA/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=أوامر التصنيع NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/az_AZ/mrp.lang b/htdocs/langs/az_AZ/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/az_AZ/mrp.lang +++ b/htdocs/langs/az_AZ/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/bg_BG/mrp.lang b/htdocs/langs/bg_BG/mrp.lang index 0c39bca3291..933315a64d4 100644 --- a/htdocs/langs/bg_BG/mrp.lang +++ b/htdocs/langs/bg_BG/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Стойност 0,95 означава сре DeleteBillOfMaterials=Изтриване на списък с материали DeleteMo=Изтриване на поръчка за производство ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Поръчки за производство NewMO=Нова поръчка за производство QtyToProduce=Кол. за производство diff --git a/htdocs/langs/bn_BD/mrp.lang b/htdocs/langs/bn_BD/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/bn_BD/mrp.lang +++ b/htdocs/langs/bn_BD/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/bn_IN/mrp.lang b/htdocs/langs/bn_IN/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/bn_IN/mrp.lang +++ b/htdocs/langs/bn_IN/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/bs_BA/mrp.lang b/htdocs/langs/bs_BA/mrp.lang index 16ab0c8ac49..999a6ec67b8 100644 --- a/htdocs/langs/bs_BA/mrp.lang +++ b/htdocs/langs/bs_BA/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/cs_CZ/mrp.lang b/htdocs/langs/cs_CZ/mrp.lang index 948205b3887..13d519a79b7 100644 --- a/htdocs/langs/cs_CZ/mrp.lang +++ b/htdocs/langs/cs_CZ/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Hodnota 0,95 znamená průměrně ztrátu vyr DeleteBillOfMaterials=Odstranit kusovník DeleteMo=Smazat výrobní zakázku ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Výrobní zakázky NewMO=Nová výrobní objednávka QtyToProduce=Množství k výrobě diff --git a/htdocs/langs/de_AT/admin.lang b/htdocs/langs/de_AT/admin.lang index 4d4d8fa6c0e..47bcbdba9a3 100644 --- a/htdocs/langs/de_AT/admin.lang +++ b/htdocs/langs/de_AT/admin.lang @@ -44,7 +44,6 @@ DetailPosition=Nummer sortieren, um die Menüposition zu definieren NotConfigured=Modul / Anwendung nicht konfiguriert OtherOptions=Andere Optionen OtherSetup=Andere Einstellungen -ClientTZ=Client-Zeitzone (Benutzer) ClientHour=Client-Zeit (Benutzer) DaylingSavingTime=Sommerzeit Language_en_US_es_MX_etc=Sprache (de_AT, en_UK, ...) diff --git a/htdocs/langs/de_DE/mrp.lang b/htdocs/langs/de_DE/mrp.lang index 0c90379fd43..323bbe74d59 100644 --- a/htdocs/langs/de_DE/mrp.lang +++ b/htdocs/langs/de_DE/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Ein Wert von 0,95 bedeutet im Durchschnitt 5% DeleteBillOfMaterials=Stückliste löschen DeleteMo=Fertigungsauftrag löschen ConfirmDeleteBillOfMaterials=Möchten Sie diese Stückliste wirklich löschen? -ConfirmDeleteMo=Möchten Sie diese Stückliste wirklich löschen? +ConfirmDeleteMo=Möchten Sie diese Fertigungsauftrag wirklich löschen? MenuMRP=Fertigungsaufträge NewMO=Neuer Fertigungsauftrag QtyToProduce=Produktionsmenge diff --git a/htdocs/langs/el_GR/mrp.lang b/htdocs/langs/el_GR/mrp.lang index 3d622d1de8b..f70ffcd3117 100644 --- a/htdocs/langs/el_GR/mrp.lang +++ b/htdocs/langs/el_GR/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Η τιμή 0,95 σημαίνει κατά μ DeleteBillOfMaterials=Διαγραφή λογαριασμού υλικών DeleteMo=Διαγραφή Παραγγελίας Παραγωγής ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Παραγγελίες Παραγωγής NewMO=Νέα Παραγγελία Παραγωγής QtyToProduce=Ποσότητα για παραγωγή diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 771f0a83e7b..c20e0a339f6 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -37,8 +37,8 @@ OtherInfo=Other information DeleteCptCategory=Remove accounting account from group ConfirmDeleteCptCategory=Are you sure you want to remove this accounting account from the accounting account group? JournalizationInLedgerStatus=Status of journalization -AlreadyInGeneralLedger=Already transferred in accounting journals and ledger -NotYetInGeneralLedger=Not yet transferred in accouting journals and ledger +AlreadyInGeneralLedger=Already transferred to accounting journals and ledger +NotYetInGeneralLedger=Not yet transferred to accouting journals and ledger GroupIsEmptyCheckSetup=Group is empty, check setup of the personalized accounting group DetailByAccount=Show detail by account AccountWithNonZeroValues=Accounts with non-zero values @@ -298,7 +298,7 @@ NoNewRecordSaved=No more record to journalize ListOfProductsWithoutAccountingAccount=List of products not bound to any accounting account ChangeBinding=Change the binding Accounted=Accounted in ledger -NotYetAccounted=Not yet accounted in the ledger +NotYetAccounted=Not yet transferred to accounting ShowTutorial=Show Tutorial NotReconciled=Not reconciled WarningRecordWithoutSubledgerAreExcluded=Warning, all operations without subledger account defined are filtered and excluded from this view @@ -329,8 +329,8 @@ ACCOUNTING_DISABLE_BINDING_ON_PURCHASES=Disable binding & transfer in accountanc ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS=Disable binding & transfer in accountancy on expense reports (expense reports will not be taken into account in accounting) ## Export -NotifiedExportDate=Notified export date (modification of the entries will not be possible) -NotifiedValidationDate=Validation of the entries (modification or deletion of the entries will not be possible) +NotifiedExportDate=Flag exported lines as exported (modification of the lines will not be possible) +NotifiedValidationDate=Validate the exported entries (modification or deletion of the lines will not be possible) ConfirmExportFile=Confirmation of the generation of the accounting export file ? ExportDraftJournal=Export draft journal Modelcsv=Model of export @@ -343,7 +343,7 @@ Modelcsv_ciel=Export for Sage50, Ciel Compta or Compta Evo. (Format XIMPORT) Modelcsv_quadratus=Export for Quadratus QuadraCompta Modelcsv_ebp=Export for EBP Modelcsv_cogilog=Export for Cogilog -Modelcsv_agiris=Export for Agiris +Modelcsv_agiris=Export for Agiris Isacompta Modelcsv_LDCompta=Export for LD Compta (v9) (Test) Modelcsv_LDCompta10=Export for LD Compta (v10 & higher) Modelcsv_openconcerto=Export for OpenConcerto (Test) @@ -351,9 +351,10 @@ Modelcsv_configurable=Export CSV Configurable Modelcsv_FEC=Export FEC Modelcsv_FEC2=Export FEC (With dates generation writing / document reversed) Modelcsv_Sage50_Swiss=Export for Sage 50 Switzerland -Modelcsv_winfic=Export Winfic - eWinfic - WinSis Compta +Modelcsv_winfic=Export for Winfic - eWinfic - WinSis Compta Modelcsv_Gestinumv3=Export for Gestinum (v3) -Modelcsv_Gestinumv5Export for Gestinum (v5) +Modelcsv_Gestinumv5=Export for Gestinum (v5) +Modelcsv_charlemagne=Export for Aplim Charlemagne ChartofaccountsId=Chart of accounts Id ## Tools - Init accounting account on product / service diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 6d99e754368..7ffbe0328c1 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -75,7 +75,7 @@ Dictionary=Dictionaries ErrorReservedTypeSystemSystemAuto=Value 'system' and 'systemauto' for type is reserved. You can use 'user' as value to add your own record ErrorCodeCantContainZero=Code can't contain value 0 DisableJavascript=Disable JavaScript and Ajax functions -DisableJavascriptNote=Note: For test or debug purpose. For optimization for blind person or text browsers, you may prefer to use the setup on the profile of user +DisableJavascriptNote=Note: For test or debug purpose only. For optimization for blind person or text browsers, you may prefer to use the setup on the profile of user UseSearchToSelectCompanyTooltip=Also if you have a large number of third parties (> 100 000), you can increase speed by setting constant COMPANY_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. UseSearchToSelectContactTooltip=Also if you have a large number of third parties (> 100 000), you can increase speed by setting constant CONTACT_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. DelaiedFullListToSelectCompany=Wait until a key is pressed before loading content of Third Parties combo list.
    This may increase performance if you have a large number of third parties, but it is less convenient. @@ -133,7 +133,6 @@ IdModule=Module ID IdPermissions=Permissions ID LanguageBrowserParameter=Parameter %s LocalisationDolibarrParameters=Localization parameters -ClientTZ=Client Time Zone (user) ClientHour=Client time (user) OSTZ=Server OS Time Zone PHPTZ=PHP server Time Zone @@ -161,7 +160,7 @@ Purge=Purge PurgeAreaDesc=This page allows you to delete all files generated or stored by Dolibarr (temporary files or all files in %s directory). Using this feature is not normally necessary. It is provided as a workaround for users whose Dolibarr is hosted by a provider that does not offer permissions to delete files generated by the web server. PurgeDeleteLogFile=Delete log files, including %s defined for Syslog module (no risk of losing data) PurgeDeleteTemporaryFiles=Delete all log and temporary files (no risk of losing data). Parameter can be 'tempfilesold', 'logfiles' or both 'tempfilesold+logfiles'. Note: Deletion of temporary files is done only if the temp directory was created more than 24 hours ago. -PurgeDeleteTemporaryFilesShort=Delete log and temporary files +PurgeDeleteTemporaryFilesShort=Delete log and temporary files (no risk of losing data) PurgeDeleteAllFilesInDocumentsDir=Delete all files in directory: %s.
    This will delete all generated documents related to elements (third parties, invoices etc...), files uploaded into the ECM module, database backup dumps and temporary files. PurgeRunNow=Purge now PurgeNothingToDelete=No directory or files to delete. @@ -280,6 +279,7 @@ SpaceX=Space X SpaceY=Space Y FontSize=Font size Content=Content +ContentForLines=Content to display for each product or service (from variable __LINES__ of Content) NoticePeriod=Notice period NewByMonth=New by month Emails=Emails @@ -375,8 +375,8 @@ UMask=UMask parameter for new files on Unix/Linux/BSD/Mac file system. UMaskExplanation=This parameter allow you to define permissions set by default on files created by Dolibarr on server (during upload for example).
    It must be the octal value (for example, 0666 means read and write for everyone).
    This parameter is useless on a Windows server. SeeWikiForAllTeam=Take a look at the Wiki page for a list of contributors and their organization UseACacheDelay= Delay for caching export response in seconds (0 or empty for no cache) -DisableLinkToHelpCenter=Hide link "Need help or support" on login page -DisableLinkToHelp=Hide link to online help "%s" +DisableLinkToHelpCenter=Hide the link "Need help or support" on the login page +DisableLinkToHelp=Hide the link to the online help "%s" AddCRIfTooLong=There is no automatic text wrapping, text that is too long will not display on documents. Please add carriage returns in the text area if needed. ConfirmPurge=Are you sure you want to execute this purge?
    This will permanently delete all your data files with no way to restore them (ECM files, attached files...). MinLength=Minimum length @@ -500,7 +500,8 @@ WarningPHPMailB=- Some Email Service Providers (like Yahoo) do not allow you to WarningPHPMailC=- Using the SMTP server of your own Email Service Provider to send emails is also interesting so all emails sent from application will also be saved into your "Sent" directory of your mailbox. WarningPHPMailD=Also, it is therefore recommended to change the sending method of e-mails to the value "SMTP". If you really want to keep the default "PHP" method to send emails, just ignore this warning, or remove it by setting the MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP constant to 1 in Home - Setup - Other. WarningPHPMail2=If your email SMTP provider need to restrict email client to some IP addresses (very rare), this is the IP address of the mail user agent (MUA) for your ERP CRM application: %s. -WarningPHPMailSPF=If the domain name in your sender email address is protected by a SPF record (ask you domain name registar), you must add the following IPs in the SPF record of the DNS of your domain: %s. +WarningPHPMailSPF=If the domain name in your sender email address is protected by a SPF record (ask your domain name registar), you must add the following IPs in the SPF record of the DNS of your domain: %s. +ActualMailSPFRecordFound=Actual SPF record found : %s ClickToShowDescription=Click to show description DependsOn=This module needs the module(s) RequiredBy=This module is required by module(s) @@ -517,6 +518,9 @@ Field=Field ProductDocumentTemplates=Document templates to generate product document FreeLegalTextOnExpenseReports=Free legal text on expense reports WatermarkOnDraftExpenseReports=Watermark on draft expense reports +ProjectIsRequiredOnExpenseReports=The project is mandatory for entering an expense report +PrefillExpenseReportDatesWithCurrentMonth=Pre-fill start and end dates of new expense report with start and end dates of the current month +ForceExpenseReportsLineAmountsIncludingTaxesOnly=Force the entry of expense report amounts always in amount with taxes AttachMainDocByDefault=Set this to 1 if you want to attach main document to email by default (if applicable) FilesAttachedToEmail=Attach file SendEmailsReminders=Send agenda reminders by emails @@ -606,7 +610,7 @@ Module400Desc=Management of projects, leads/opportunities and/or tasks. You can Module410Name=Webcalendar Module410Desc=Webcalendar integration Module500Name=Taxes & Special Expenses -Module500Desc=Management of other expenses (sale taxes, social or fiscal taxes, dividends, ...) +Module500Desc=Management of other expenses (sales taxes, social or fiscal taxes, dividends, ...) Module510Name=Salaries Module510Desc=Record and track employee payments Module520Name=Loans @@ -898,6 +902,11 @@ Permission1002=Create/modify warehouses Permission1003=Delete warehouses Permission1004=Read stock movements Permission1005=Create/modify stock movements +Permission1011=View inventories +Permission1012=Create new inventory +Permission1014=Validate inventory +Permission1015=Allow to change PMP value for a product +Permission1016=Delete inventory Permission1101=Read delivery receipts Permission1102=Create/modify delivery receipts Permission1104=Validate delivery receipts @@ -953,6 +962,14 @@ Permission4001=See employees Permission4002=Create employees Permission4003=Delete employees Permission4004=Export employees +Permission4010=Read skill/job/position +Permission4011=Create/modify skill/job/position +Permission4012=Delete skill/job/position +Permission4020=Read evaluation +Permission4021=Create/modify evaluation +Permission4022=Validate evaluation +Permission4023=Delete evaluation +Permission4030=See comparison menu Permission10001=Read website content Permission10002=Create/modify website content (html and javascript content) Permission10003=Create/modify website content (dynamic php code). Dangerous, must be reserved to restricted developers. @@ -1035,7 +1052,7 @@ DictionaryFees=Expense report - Types of expense report lines DictionarySendingMethods=Shipping methods DictionaryStaff=Number of Employees DictionaryAvailability=Delivery delay -DictionaryOrderMethods=Ordering methods +DictionaryOrderMethods=Order methods DictionarySource=Origin of proposals/orders DictionaryAccountancyCategory=Personalized groups for reports DictionaryAccountancysystem=Models for chart of accounts @@ -1168,7 +1185,8 @@ DoNotSuggestPaymentMode=Do not suggest NoActiveBankAccountDefined=No active bank account defined OwnerOfBankAccount=Owner of bank account %s BankModuleNotActive=Bank accounts module not enabled -ShowBugTrackLink=Define the link "%s" (empty to not display this link, 'github' for the link to the Dolibarr project or define directly an url 'https://...') +ShowBugTrackLink=Show the link "%s" +ShowBugTrackLinkDesc=Keep empty to not display this link, use value 'github' for the link to the Dolibarr project or define directly an url 'https://...' Alerts=Alerts DelaysOfToleranceBeforeWarning=Delay before displaying a warning alert for: DelaysOfToleranceDesc=Set the delay before an alert icon %s is shown onscreen for the late element. @@ -1218,7 +1236,7 @@ SystemAreaForAdminOnly=This area is available to administrator users only. Dolib CompanyFundationDesc=Edit the information of your company/organization. Click on "%s" button at the bottom of the page when done. AccountantDesc=If you have an external accountant/bookkeeper, you can edit here its information. AccountantFileNumber=Accountant code -DisplayDesc=Parameters affecting the look and behaviour of the application can be modified here. +DisplayDesc=Parameters affecting the look and presentation of the application can be modified here. AvailableModules=Available app/modules ToActivateModule=To activate modules, go on setup Area (Home->Setup->Modules). SessionTimeOut=Time out for session @@ -1270,7 +1288,7 @@ SimpleNumRefNoDateModelDesc=Returns the reference number in the format %s-nnnn w ShowProfIdInAddress=Show professional ID with addresses ShowVATIntaInAddress=Hide intra-Community VAT number TranslationUncomplete=Partial translation -MAIN_DISABLE_METEO=Disable meteorological view +MAIN_DISABLE_METEO=Disable weather thumb MeteoStdMod=Standard mode MeteoStdModEnabled=Standard mode enabled MeteoPercentageMod=Percentage mode @@ -1341,6 +1359,7 @@ BrowserIsKO=You are using the %s web browser. This browser is known to be a bad PHPModuleLoaded=PHP component %s is loaded PreloadOPCode=Preloaded OPCode is used AddRefInList=Display Customer/Vendor ref. info list (select list or combobox) and most of hyperlink.
    Third Parties will appear with a name format of "CC12345 - SC45678 - The Big Company corp." instead of "The Big Company corp". +AddVatInList=Display Customer/Vendor VAT number. info list (select list or combobox). AddAdressInList=Display Customer/Vendor adress info list (select list or combobox)
    Third Parties will appear with a name format of "The Big Company corp. - 21 jump street 123456 Big town - USA" instead of "The Big Company corp". AddEmailPhoneTownInContactList=Display Contact email (or phones if not defined) and town info list (select list or combobox)
    Contacts will appear with a name format of "Dupond Durand - dupond.durand@email.com - Paris" or "Dupond Durand - 06 07 59 65 66 - Paris" instead of "Dupond Durand". AskForPreferredShippingMethod=Ask for preferred shipping method for Third Parties. @@ -1472,10 +1491,10 @@ LDAPSynchronizeMembersTypes=Organization of foundation's members types in LDAP LDAPPrimaryServer=Primary server LDAPSecondaryServer=Secondary server LDAPServerPort=Server port -LDAPServerPortExample=Default port: 389 +LDAPServerPortExample=Standard or StartTLS: 389, LDAPs: 636 LDAPServerProtocolVersion=Protocol version LDAPServerUseTLS=Use TLS -LDAPServerUseTLSExample=Your LDAP server use TLS +LDAPServerUseTLSExample=Your LDAP server use StartTLS LDAPServerDn=Server DN LDAPAdminDn=Administrator DN LDAPAdminDnExample=Complete DN (ex: cn=admin,dc=example,dc=com or cn=Administrator,cn=Users,dc=example,dc=com for active directory) @@ -1625,12 +1644,11 @@ ProductSetup=Products module setup ServiceSetup=Services module setup ProductServiceSetup=Products and Services modules setup NumberOfProductShowInSelect=Maximum number of products to show in combo select lists (0=no limit) -ViewProductDescInFormAbility=Display product descriptions in forms (otherwise shown in a tooltip popup) -DoNotAddProductDescAtAddLines=Do not add product description (from product card) on submit add lines on forms +ViewProductDescInFormAbility=Display product descriptions in lines of items (otherwise show description in a tooltip popup) OnProductSelectAddProductDesc=How to use the description of the products when adding a product as a line of a document AutoFillFormFieldBeforeSubmit=Auto fill the description input field with the description of product -DoNotAutofillButAutoConcat=Do not autofill the input field with description of product. Description of the product will be concatenated to the entered description automatically. -DoNotUseDescriptionOfProdut=Description of the product will never be included into the description of lines of documents +DoNotAutofillButAutoConcat=Do not autofill the input field with description of product. Description of the product will be concatenated to the entered description automatically. +DoNotUseDescriptionOfProdut=Description of the product will never be included into the description of lines of documents MergePropalProductCard=Activate in product/service Attached Files tab an option to merge product PDF document to proposal PDF azur if product/service is in the proposal ViewProductDescInThirdpartyLanguageAbility=Display products descriptions in forms in the language of the third party (otherwise in the language of the user) UseSearchToSelectProductTooltip=Also if you have a large number of products (> 100 000), you can increase speed by setting constant PRODUCT_DONOTSEARCH_ANYWHERE to 1 in Setup->Other. Search will then be limited to start of string. @@ -1690,6 +1708,8 @@ MailingDelay=Seconds to wait after sending next message NotificationSetup=Email Notification module setup NotificationEMailFrom=Sender email (From) for emails sent by the Notifications module FixedEmailTarget=Recipient +NotificationDisableConfirmMessageFix=Disable notification info in confirm message for fix notification +NotificationDisableConfirmMessageUser=Disable notification info in confirm message for user notification ##### Sendings ##### SendingsSetup=Shipping module setup SendingsReceiptModel=Sending receipt model @@ -1705,8 +1725,10 @@ FreeLegalTextOnDeliveryReceipts=Free text on delivery receipts ##### FCKeditor ##### AdvancedEditor=Advanced editor ActivateFCKeditor=Activate advanced editor for: -FCKeditorForCompany=WYSIWIG creation/edition of elements description and note (except products/services) -FCKeditorForProduct=WYSIWIG creation/edition of products/services description and note +FCKeditorForNotePublic=WYSIWIG creation/edition of the field public notes of elements +FCKeditorForNotePrivate=WYSIWIG creation/edition of the field private notes of elements +FCKeditorForCompany=WYSIWIG creation/edition of the field description of elements (except products/services) +FCKeditorForProduct=WYSIWIG creation/edition of the field description of products/services FCKeditorForProductDetails=WYSIWIG creation/edition of products details lines for all entities (proposals, orders, invoices, etc...). Warning: Using this option for this case is seriously not recommended as it can create problems with special characters and page formatting when building PDF files. FCKeditorForMailing= WYSIWIG creation/edition for mass eMailings (Tools->eMailing) FCKeditorForUserSignature=WYSIWIG creation/edition of user signature @@ -1915,11 +1937,11 @@ UnicodeCurrency=Enter here between braces, list of byte number that represent th ColorFormat=The RGB color is in HEX format, eg: FF0000 PictoHelp=Icon name in dolibarr format ('image.png' if into the current theme directory, 'image.png@nom_du_module' if into the directory /img/ of a module) PositionIntoComboList=Position of line into combo lists -SellTaxRate=Sale tax rate +SellTaxRate=Sales tax rate RecuperableOnly=Yes for VAT "Not Perceived but Recoverable" dedicated for some state in France. Keep value to "No" in all other cases. UrlTrackingDesc=If the provider or transport service offers a page or web site to check the status of your shipments, you may enter it here. You can use the key {TRACKID} in the URL parameters so the system will replace it with the tracking number the user entered into the shipment card. OpportunityPercent=When you create a lead, you will define an estimated amount of project/lead. According to status of the lead, this amount may be multiplied by this rate to evaluate a total amount all your leads may generate. Value is a percentage (between 0 and 100). -TemplateForElement=This template record is dedicated to which element +TemplateForElement=This mail template is related to what type of object? An email template is available only when using the "Send Email" button from the related object. TypeOfTemplate=Type of template TemplateIsVisibleByOwnerOnly=Template is visible to owner only VisibleEverywhere=Visible everywhere @@ -1994,7 +2016,8 @@ MAIN_PDF_MARGIN_RIGHT=Right margin on PDF MAIN_PDF_MARGIN_TOP=Top margin on PDF MAIN_PDF_MARGIN_BOTTOM=Bottom margin on PDF MAIN_DOCUMENTS_LOGO_HEIGHT=Height for logo on PDF -MAIN_GENERATE_PROPOSALS_WITH_PICTURE=Add picture on proposal line +MAIN_GENERATE_PROPOSALS_WITH_PICTURE=Add column for picture on proposal lines +MAIN_DOCUMENTS_WITH_PICTURE_WIDTH=Width of the column if a picture is added on lines MAIN_PDF_NO_SENDER_FRAME=Hide borders on sender address frame MAIN_PDF_NO_RECIPENT_FRAME=Hide borders on recipent address frame MAIN_PDF_HIDE_CUSTOMER_CODE=Hide customer code @@ -2118,6 +2141,7 @@ EMailsWillHaveMessageID=Emails will have a tag 'References' matching this syntax PDF_SHOW_PROJECT=Show project on document ShowProjectLabel=Project Label PDF_USE_ALSO_LANGUAGE_CODE=If you want to have some texts in your PDF duplicated in 2 different languages in the same generated PDF, you must set here this second language so generated PDF will contains 2 different languages in same page, the one chosen when generating PDF and this one (only few PDF templates support this). Keep empty for 1 language per PDF. +PDF_USE_A=Gererate PDF documents with format PDF/A instead of defaut format PDF FafaIconSocialNetworksDesc=Enter here the code of a FontAwesome icon. If you don't know what is FontAwesome, you can use the generic value fa-address-book. RssNote=Note: Each RSS feed definition provides a widget that you must enable to have it available in dashboard JumpToBoxes=Jump to Setup -> Widgets @@ -2149,7 +2173,7 @@ NoWritableFilesFoundIntoRootDir=No writable files or directories of the common p RecommendedValueIs=Recommended: %s Recommended=Recommended NotRecommended=Not recommended -ARestrictedPath=A restricted path +ARestrictedPath=Some restricted path CheckForModuleUpdate=Check for external modules updates CheckForModuleUpdateHelp=This action will connect to editors of external modules to check if a new version is available. ModuleUpdateAvailable=An update is available @@ -2164,6 +2188,24 @@ YouShouldSetThisToOff=You should set this to 0 or off InstallAndUpgradeLockedBy=Install and upgrades are locked by the file %s OldImplementation=Old implementation PDF_SHOW_LINK_TO_ONLINE_PAYMENT=If some online payment modules are enabled (Paypal, Stripe, ...), add a link on the PDF to make the online payment +DashboardDisableGlobal=Disable globally all the thumbs of open objects +BoxstatsDisableGlobal=Disable totally box statistics +DashboardDisableBlocks=Thumbs of open objects (to process or late) on main dashboard +DashboardDisableBlockAgenda=Disable the thumb for agenda +DashboardDisableBlockProject=Disable the thumb for projects +DashboardDisableBlockCustomer=Disable the thumb for customers +DashboardDisableBlockSupplier=Disable the thumb for suppliers +DashboardDisableBlockContract=Disable the thumb for contracts +DashboardDisableBlockTicket=Disable the thumb for tickets +DashboardDisableBlockBank=Disable the thumb for banks +DashboardDisableBlockAdherent=Disable the thumb for memberships +DashboardDisableBlockExpenseReport=Disable the thumb for expense reports +DashboardDisableBlockHoliday=Disable the thumb for leaves EnabledCondition=Condition to have field enabled (if not enabled, visibility will always be off) IfYouUseASecondTaxYouMustSetYouUseTheMainTax=If you want to use a second tax, you must enable also the first sale tax IfYouUseAThirdTaxYouMustSetYouUseTheMainTax=If you want to use a third tax, you must enable also the first sale tax +LanguageAndPresentation=Language and presentation +SkinAndColors=Skin and colors +IfYouUseASecondTaxYouMustSetYouUseTheMainTax=If you want to use a second tax, you must enable also the first sales tax +IfYouUseAThirdTaxYouMustSetYouUseTheMainTax=If you want to use a third tax, you must enable also the first sales tax +PDF_USE_1A=Generate PDF with PDF/A-1b format diff --git a/htdocs/langs/en_US/agenda.lang b/htdocs/langs/en_US/agenda.lang index cbe238ad2a4..bc9c7dab537 100644 --- a/htdocs/langs/en_US/agenda.lang +++ b/htdocs/langs/en_US/agenda.lang @@ -64,6 +64,7 @@ ShipmentClassifyClosedInDolibarr=Shipment %s classified billed ShipmentUnClassifyCloseddInDolibarr=Shipment %s classified re-open ShipmentBackToDraftInDolibarr=Shipment %s go back to draft status ShipmentDeletedInDolibarr=Shipment %s deleted +ShipmentCanceledInDolibarr=Shipment %s canceled ReceptionValidatedInDolibarr=Reception %s validated OrderCreatedInDolibarr=Order %s created OrderValidatedInDolibarr=Order %s validated diff --git a/htdocs/langs/en_US/banks.lang b/htdocs/langs/en_US/banks.lang index a0b7942d446..6c770163f29 100644 --- a/htdocs/langs/en_US/banks.lang +++ b/htdocs/langs/en_US/banks.lang @@ -182,3 +182,4 @@ BankColorizeMovementName2=Background color for credit movement IfYouDontReconcileDisableProperty=If you don't make the bank reconciliations on some bank accounts, disable the property "%s" on them to remove this warning. NoBankAccountDefined=No bank account defined NoRecordFoundIBankcAccount=No record found in bank account. Commonly, this occurs when a record has been deleted manually from the list of transaction in the bank account (for example during a reconciliation of the bank account). Another reason is that the payment was recorded when the module "%s" was disabled. +AlreadyOneBankAccount=Already one bank account defined diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index e475a815ac9..3aaa5465ca0 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -192,6 +192,7 @@ ConfirmClassifyPaidPartiallyReasonDiscount=Remaining unpaid (%s %s) is a ConfirmClassifyPaidPartiallyReasonDiscountNoVat=Remaining unpaid (%s %s) is a discount granted because payment was made before term. I accept to lose the VAT on this discount. ConfirmClassifyPaidPartiallyReasonDiscountVat=Remaining unpaid (%s %s) is a discount granted because payment was made before term. I recover the VAT on this discount without a credit note. ConfirmClassifyPaidPartiallyReasonBadCustomer=Bad customer +ConfirmClassifyPaidPartiallyReasonBankCharge=Deduction by bank (intermediary bank fees) ConfirmClassifyPaidPartiallyReasonProductReturned=Products partially returned ConfirmClassifyPaidPartiallyReasonOther=Amount abandoned for other reason ConfirmClassifyPaidPartiallyReasonDiscountNoVatDesc=This choice is possible if your invoice has been provided with suitable comments. (Example «Only the tax corresponding to the price that has been actually paid gives rights to deduction») @@ -199,6 +200,7 @@ ConfirmClassifyPaidPartiallyReasonDiscountVatDesc=In some countries, this choice ConfirmClassifyPaidPartiallyReasonAvoirDesc=Use this choice if all other does not suit ConfirmClassifyPaidPartiallyReasonBadCustomerDesc=A bad customer is a customer that refuses to pay his debt. ConfirmClassifyPaidPartiallyReasonProductReturnedDesc=This choice is used when payment is not complete because some of products were returned +ConfirmClassifyPaidPartiallyReasonBankChargeDesc=The unpaid amount is intermediary bank fees, deducted directly from the correct amount paid by the Customer. ConfirmClassifyPaidPartiallyReasonOtherDesc=Use this choice if all others are not suitable, for example in following situation:
    - payment not complete because some products were shipped back
    - amount claimed too important because a discount was forgotten
    In all cases, amount over-claimed must be corrected in accountancy system by creating a credit note. ConfirmClassifyAbandonReasonOther=Other ConfirmClassifyAbandonReasonOtherDesc=This choice will be used in all other cases. For example because you plan to create a replacing invoice. @@ -239,16 +241,19 @@ RemainderToTake=Remaining amount to take RemainderToTakeMulticurrency=Remaining amount to take, original currency RemainderToPayBack=Remaining amount to refund RemainderToPayBackMulticurrency=Remaining amount to refund, original currency +NegativeIfExcessRefunded=negative if excess refunded Rest=Pending AmountExpected=Amount claimed ExcessReceived=Excess received ExcessReceivedMulticurrency=Excess received, original currency +NegativeIfExcessReceived=negative if excess received ExcessPaid=Excess paid ExcessPaidMulticurrency=Excess paid, original currency EscompteOffered=Discount offered (payment before term) EscompteOfferedShort=Discount SendBillRef=Submission of invoice %s SendReminderBillRef=Submission of invoice %s (reminder) +SendPaymentReceipt=Submission of payment receipt %s NoDraftBills=No draft invoices NoOtherDraftBills=No other draft invoices NoDraftInvoices=No draft invoices @@ -265,6 +270,7 @@ DateInvoice=Invoice date DatePointOfTax=Point of tax NoInvoice=No invoice NoOpenInvoice=No open invoice +NbOfOpenInvoices=Number of open invoices ClassifyBill=Classify invoice SupplierBillsToPay=Unpaid vendor invoices CustomerBillsUnpaid=Unpaid customer invoices diff --git a/htdocs/langs/en_US/bookmarks.lang b/htdocs/langs/en_US/bookmarks.lang index 87466cadcfa..d2378963a21 100644 --- a/htdocs/langs/en_US/bookmarks.lang +++ b/htdocs/langs/en_US/bookmarks.lang @@ -19,3 +19,4 @@ UseAnExternalHttpLinkOrRelativeDolibarrLink=Use an external/absolute link (https ChooseIfANewWindowMustBeOpenedOnClickOnBookmark=Choose if the linked page should open in the current tab or a new tab BookmarksManagement=Bookmarks management BookmarksMenuShortCut=Ctrl + shift + m +NoBookmarks=No bookmarks defined diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index 52dc71d140c..22d5afed2fc 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -130,3 +130,6 @@ ShowPriceHT = Display the column with the price excluding tax (on screen) ShowPriceHTOnReceipt = Display the column with the price excluding tax (on the receipt) CustomerDisplay=Customer display SplitSale=Split sale +PrintWithoutDetailsButton=Add "Print without details" button +PrintWithoutDetailsLabelDefault=Line label by default on printing without details +PrintWithoutDetails=Print without details diff --git a/htdocs/langs/en_US/categories.lang b/htdocs/langs/en_US/categories.lang index 29e08f66541..cf0de898bdb 100644 --- a/htdocs/langs/en_US/categories.lang +++ b/htdocs/langs/en_US/categories.lang @@ -96,4 +96,5 @@ ChooseCategory=Choose category StocksCategoriesArea=Warehouse Categories ActionCommCategoriesArea=Event Categories WebsitePagesCategoriesArea=Page-Container Categories +KnowledgemanagementsCategoriesArea=KM article Categories UseOrOperatorForCategories=Use 'OR' operator for categories diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index b52ab6131be..616619adb92 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -80,7 +80,7 @@ Web=Web Poste= Position DefaultLang=Default language VATIsUsed=Sales tax used -VATIsUsedWhenSelling=This defines if this third party includes a sale tax or not when it makes an invoice to its own customers +VATIsUsedWhenSelling=This defines if this third party includes a sales tax or not when it makes an invoice to its own customers VATIsNotUsed=Sales tax is not used CopyAddressFromSoc=Copy address from third-party details ThirdpartyNotCustomerNotSupplierSoNoRef=Third party neither customer nor vendor, no available referring objects @@ -271,6 +271,12 @@ ProfId3RU=Prof Id 3 (KPP) ProfId4RU=Prof Id 4 (OKPO) ProfId5RU=- ProfId6RU=- +ProfId1UA=Prof Id 1 (EDRPOU) +ProfId2UA=Prof Id 2 (DRFO) +ProfId3UA=Prof Id 3 (INN) +ProfId4UA=Prof Id 4 (Certificate) +ProfId5UA=Prof Id 5 (RNOKPP) +ProfId6UA=Prof Id 6 (TRDPAU) ProfId1DZ=RC ProfId2DZ=Art. ProfId3DZ=NIF diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index 8329346c163..ace3e518003 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -188,25 +188,25 @@ LT1ReportByCustomers=Report tax 2 by third party LT2ReportByCustomers=Report tax 3 by third party LT1ReportByCustomersES=Report by third party RE LT2ReportByCustomersES=Report by third party IRPF -VATReport=Sale tax report -VATReportByPeriods=Sale tax report by period -VATReportByMonth=Sale tax report by month -VATReportByRates=Sale tax report by rates -VATReportByThirdParties=Sale tax report by third parties -VATReportByCustomers=Sale tax report by customer +VATReport=Sales tax report +VATReportByPeriods=Sales tax report by period +VATReportByMonth=Sales tax report by month +VATReportByRates=Sales tax report by rate +VATReportByThirdParties=Sales tax report by third party +VATReportByCustomers=Sales tax report by customer VATReportByCustomersInInputOutputMode=Report by the customer VAT collected and paid -VATReportByQuartersInInputOutputMode=Report by Sale tax rate of the tax collected and paid +VATReportByQuartersInInputOutputMode=Report by Sales tax rate of the tax collected and paid VATReportShowByRateDetails=Show details of this rate LT1ReportByQuarters=Report tax 2 by rate LT2ReportByQuarters=Report tax 3 by rate LT1ReportByQuartersES=Report by RE rate LT2ReportByQuartersES=Report by IRPF rate -SeeVATReportInInputOutputMode=See report %sVAT encasement%s for a standard calculation -SeeVATReportInDueDebtMode=See report %sVAT on flow%s for a calculation with an option on the flow -RulesVATInServices=- For services, the report includes the VAT regulations actually received or issued on the basis of the date of payment. -RulesVATInProducts=- For material assets, the report includes the VAT received or issued on the basis of the date of payment. -RulesVATDueServices=- For services, the report includes VAT invoices due, paid or not, based on the invoice date. -RulesVATDueProducts=- For material assets, the report includes the VAT invoices, based on the invoice date. +SeeVATReportInInputOutputMode=See report %sVAT collection%s for a standard calculation +SeeVATReportInDueDebtMode=See report %sVAT on debit%s for a calculation with an option on the invoicing +RulesVATInServices=- For services, the report includes the VAT of payments actually received or paid on the basis of the date of payment. +RulesVATInProducts=- For material assets, the report includes the VAT on the basis of the date of payment. +RulesVATDueServices=- For services, the report includes VAT of due invoices, paid or not, based on the invoice date. +RulesVATDueProducts=- For material assets, the report includes the VAT of due invoices, based on the invoice date. OptionVatInfoModuleComptabilite=Note: For material assets, it should use the date of delivery to be more fair. ThisIsAnEstimatedValue=This is a preview, based on business events and not from the final ledger table, so final results may differ from this preview values PercentOfInvoice=%%/invoice @@ -286,9 +286,12 @@ ReportPurchaseTurnover=Purchase turnover invoiced ReportPurchaseTurnoverCollected=Purchase turnover collected IncludeVarpaysInResults = Include various payments in reports IncludeLoansInResults = Include loans in reports -InvoiceLate30Days = Invoices late > 30 days -InvoiceLate15Days = Invoices late > 15 days -InvoiceLateMinus15Days = Invoices late -InvoiceNotLate = To be collected < 15 days -InvoiceNotLate15Days = To be collected in 15 days -InvoiceNotLate30Days = To be collected in 30 days +InvoiceLate30Days = Invoices late (> 30 days) +InvoiceLate15Days = Invoices late (15 to 30 days) +InvoiceLateMinus15Days = Invoices late (< 15 days) +InvoiceNotLate = To be collected (< 15 days) +InvoiceNotLate15Days = To be collected (15 to 30 days) +InvoiceNotLate30Days = To be collected (> 30 days) +InvoiceToPay=To pay (< 15 days) +InvoiceToPay15Days=To pay (15 to 30 days) +InvoiceToPay30Days=To pay (> 30 days) \ No newline at end of file diff --git a/htdocs/langs/en_US/ecm.lang b/htdocs/langs/en_US/ecm.lang index bc18bed4a29..494a6c55164 100644 --- a/htdocs/langs/en_US/ecm.lang +++ b/htdocs/langs/en_US/ecm.lang @@ -45,3 +45,5 @@ GenerateImgWebp=Duplicate all images with another version with .webp format ConfirmGenerateImgWebp=If you confirm, you will generate an image in .webp format for all images currently into this folder (subfolders are not included)... ConfirmImgWebpCreation=Confirm all images duplication SucessConvertImgWebp=Images successfully duplicated +ECMDirName=Dir name +ECMParentDirectory=Parent directory diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 89a3ec36af5..efe5e069b60 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -83,7 +83,7 @@ ErrorCantSaveADoneUserWithZeroPercentage=Can't save an action with "status not s ErrorRefAlreadyExists=Ref used for creation already exists. ErrorPleaseTypeBankTransactionReportName=Please enter the bank statement name where the entry has to be reported (Format YYYYMM or YYYYMMDD) ErrorRecordHasChildren=Failed to delete record since it has some child records. -ErrorRecordHasAtLeastOneChildOfType=Object has at least one child of type %s +ErrorRecordHasAtLeastOneChildOfType=Object %s has at least one child of type %s ErrorRecordIsUsedCantDelete=Can't delete record. It is already used or included into another object. ErrorModuleRequireJavascript=Javascript must not be disabled to have this feature working. To enable/disable Javascript, go to menu Home->Setup->Display. ErrorPasswordsMustMatch=Both typed passwords must match each other @@ -270,6 +270,7 @@ ErrorActionCommBadType=Selected event type (id: %n, code: %s) do not exist in Ev CheckVersionFail=Version check fail ErrorWrongFileName=Name of the file cannot have __SOMETHING__ in it ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please modify. +ErrorIsNotADraft=%s is not a draft # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. @@ -307,10 +308,10 @@ WarningPaypalPaymentNotCompatibleWithStrict=The value 'Strict' makes the online # Validate RequireValidValue = Value not valid -RequireAtLeastXString = Requires at least % character(s) -RequireXStringMax = Requires % character(s) max -RequireAtLeastXDigits = Requires at least % digit(s) -RequireXDigitsMax = Requires % digit(s) max +RequireAtLeastXString = Requires at least %s character(s) +RequireXStringMax = Requires %s character(s) max +RequireAtLeastXDigits = Requires at least %s digit(s) +RequireXDigitsMax = Requires %s digit(s) max RequireValidEmail = Email address is not valid RequireMaxLength = Length must be less than %s chars RequireMinLength = Length must be more than %s char(s) diff --git a/htdocs/langs/en_US/eventorganization.lang b/htdocs/langs/en_US/eventorganization.lang index 4cb7307f0c2..88415022bde 100644 --- a/htdocs/langs/en_US/eventorganization.lang +++ b/htdocs/langs/en_US/eventorganization.lang @@ -19,7 +19,7 @@ # ModuleEventOrganizationName = Event Organization EventOrganizationDescription = Event Organization through Module Project -EventOrganizationDescriptionLong= Manage the organization of an event (conferences, attendees, speakers, with public suggestion, vote or registration pages) +EventOrganizationDescriptionLong= Manage the organization of an event (show, conferences, attendees or speakers, with public pages for suggestion, vote or registration) # # Menu # @@ -32,14 +32,9 @@ PaymentEvent=Payment of event # Admin page # NewRegistration=Registration -<<<<<<< HEAD -EventOrganizationSetup = Event Organization setup -Settings = Settings -======= EventOrganizationSetup=Event Organization setup EventOrganization=Event organization Settings=Settings ->>>>>>> branch '14.0' of git@github.com:Dolibarr/dolibarr.git EventOrganizationSetupPage = Event Organization setup page EVENTORGANIZATION_TASK_LABEL = Label of tasks to create automatically when project is validated EVENTORGANIZATION_TASK_LABELTooltip = When you validate an organized event, some tasks can be automatically created in the project

    For example:
    Send Call for Conference
    Send Call for Booth
    Receive call for conferences
    Receive call for Booth
    Open subscriptions to events for attendees
    Send remind of event to speakers
    Send remind of event to Booth hoster
    Send remind of event to attendees @@ -47,8 +42,8 @@ EVENTORGANIZATION_CATEG_THIRDPARTY_CONF = Category to add to third-parties autom EVENTORGANIZATION_CATEG_THIRDPARTY_BOOTH = Category to add to third-parties automatically created when they suggests a booth EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_CONF = Template of email to send after receiving a suggestion of a conference. EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH = Template of email to send after receiving a suggestion of a booth. -EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_BOOTH = Template of email to send after a subscription to a booth has been paid. -EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT = Template of email to send after a subscription to an event has been paid. +EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_BOOTH = Template of email to send after a registration to a booth has been paid. +EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT = Template of email to send after a registration to an event has been paid. EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER = Template of email of massaction to attendes EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES = Template of email of massaction to speakers EVENTORGANIZATION_FILTERATTENDEES_CAT = Filter thirdpartie's select list in attendees creation card/form with category @@ -62,7 +57,7 @@ ManageOrganizeEvent = Manage the organization of an event ConferenceOrBooth = Conference Or Booth ConferenceOrBoothTab = Conference Or Booth AmountPaid = Amount paid -DateOfRegistration = Date of subscription +DateOfRegistration = Date of registration ConferenceOrBoothAttendee = Conference Or Booth Attendee # @@ -72,18 +67,18 @@ YourOrganizationEventConfRequestWasReceived = Your request for conference was re YourOrganizationEventBoothRequestWasReceived = Your request for booth was received EventOrganizationEmailAskConf = Request for conference EventOrganizationEmailAskBooth = Request for booth -EventOrganizationEmailSubsBooth = Subscription for booth -EventOrganizationEmailSubsEvent = Subscription for an event +EventOrganizationEmailBoothPayment = Payment of your booth +EventOrganizationEmailRegistrationPayment = Registration for an event EventOrganizationMassEmailAttendees = Communication to attendees EventOrganizationMassEmailSpeakers = Communication to speakers # # Event # -AllowUnknownPeopleSuggestConf=Allow unknown people to suggest conferences -AllowUnknownPeopleSuggestConfHelp=Allow unknown people to suggest conferences -AllowUnknownPeopleSuggestBooth=Allow unknown people to suggest booth -AllowUnknownPeopleSuggestBoothHelp=Allow unknown people to suggest booth +AllowUnknownPeopleSuggestConf=Allow people to suggest conferences +AllowUnknownPeopleSuggestConfHelp=Allow unknown people to suggest a conference they want to do +AllowUnknownPeopleSuggestBooth=Allow people to apply for a booth +AllowUnknownPeopleSuggestBoothHelp=Allow unknown people to apply for a booth PriceOfRegistration=Price of registration PriceOfRegistrationHelp=Price to pay to register or participate in the event PriceOfBooth=Subscription price to stand a booth @@ -111,9 +106,9 @@ EvntOrgCancelled = Cancelled # SuggestForm = Suggestion page SuggestOrVoteForConfOrBooth = Page for suggestion or vote -EvntOrgRegistrationHelpMessage = Here, you can vote for a conference or booth or suggest a new one for the event -EvntOrgRegistrationConfHelpMessage = Here, you can suggest a new conference for the project -EvntOrgRegistrationBoothHelpMessage = Here, you can suggest a new booth for the project +EvntOrgRegistrationHelpMessage = Here, you can vote for a conference or suggest a new one for the event. You can also apply to have a booth during the event. +EvntOrgRegistrationConfHelpMessage = Here, you can suggest a new conference to animate during the event. +EvntOrgRegistrationBoothHelpMessage = Here, you can apply to have a booth during the event. ListOfSuggestedConferences = List of suggested conferences ListOfSuggestedBooths = List of suggested booths ListOfConferencesOrBooths=List of conferences or booths of event project @@ -130,10 +125,22 @@ BoothLocationFee = Booth location for the event : '%s' occurring from %s to %s EventType = Event type LabelOfBooth=Booth label LabelOfconference=Conference label -ConferenceIsNotConfirmed=Subcription not available, conference is not confirmed yet +ConferenceIsNotConfirmed=Registration not available, conference is not confirmed yet DateMustBeBeforeThan=%s must be before %s DateMustBeAfterThan=%s must be after %s +NewSubscription=Registration +OrganizationEventConfRequestWasReceived=Your suggestion for a conference has been received +OrganizationEventBoothRequestWasReceived=Your request for a booth has been received +OrganizationEventPaymentOfBoothWasReceived=Your payment for your booth has been recorded +OrganizationEventPaymentOfRegistrationWasReceived=Your payment for your event registration has been recorded +OrganizationEventBulkMailToAttendees=This is a remind about your participation in the event as an attendee +OrganizationEventBulkMailToSpeakers=This is a reminder on your participation in the event as a speaker +OrganizationEventLinkToThirdParty=Link to third party (customer, supplier or partner) + +NewSuggestionOfBooth=Application for a booth +NewSuggestionOfConference=Application for a conference + # # Vote page # @@ -145,17 +152,15 @@ VoteOk = Your vote has been accepted. AlreadyVoted = You have already voted for this event. VoteError = An error has occurred during the vote, please try again. -# -# SubscriptionOk page -# -SubscriptionOk = Your subscription to this conference has been validated -# -# Subscription validation mail -# -ConfAttendeeSubscriptionConfirmation = Confirmation of your subscription to a conference -# -# Payment page -# +SubscriptionOk = Your registration has been validated +ConfAttendeeSubscriptionConfirmation = Confirmation of your subscription to an event Attendee = Attendee PaymentConferenceAttendee = Conference attendee payment PaymentBoothLocation = Booth location payment +DeleteConferenceOrBoothAttendee=Remove attendee +RegistrationAndPaymentWereAlreadyRecorder=A registration and a payment were already recorded for the email %s +EmailAttendee=Attendee email +EmailCompanyForInvoice=Company email (for invoice, if different of attendee email) +ErrorSeveralCompaniesWithEmailContactUs=Several companies with this email has been found so we can't validate automaticaly your registration. Please contact us at %s for a manual validation +ErrorSeveralCompaniesWithNameContactUs=Several companies with this name has been found so we can't validate automaticaly your registration. Please contact us at %s for a manual validation +NoPublicActionsAllowedForThisEvent=No public actions are open to public for this event \ No newline at end of file diff --git a/htdocs/langs/en_US/hrm.lang b/htdocs/langs/en_US/hrm.lang index da098e10bdb..8724bb805a6 100644 --- a/htdocs/langs/en_US/hrm.lang +++ b/htdocs/langs/en_US/hrm.lang @@ -1,4 +1,6 @@ # Dolibarr language file - en_US - hrm + + # Admin HRM_EMAIL_EXTERNAL_SERVICE=Email to prevent HRM external service Establishments=Establishments @@ -17,3 +19,63 @@ Employees=Employees Employee=Employee NewEmployee=New employee ListOfEmployees=List of employees +HrmSetup=HRM module setup +HRM_MAXRANK=Maximum rank for a skill +HRM_DEFAULT_SKILL_DESCRIPTION=Default description of ranks when skill is created +deplacement=Shift +DateEval=Evaluation date +JobCard=Job card +Job=Job +Jobs=Jobs +NewSkill=New Skill +SkillType=Skill type +Skilldets=List of ranks for this skill +Skilldet=Skill level +rank=Rank +ErrNoSkillSelected=No skill selected +ErrSkillAlreadyAdded=This skill is already in the list +SkillHasNoLines=This skill has no lines +skill=Skill +Skills=Skills +SkillCard=Skill card +EmployeeSkillsUpdated=Employee skills have been updated (see "Skills" tab of employee card) +Eval=Evaluation +Evals=Evaluations +NewEval=New evaluation +ValidateEvaluation=Validate evaluation +ConfirmValidateEvaluation=Are you sure you want to validate this evaluation with reference %s? +EvaluationCard=Evaluation card +RequiredRank=Required rank for this job +EmployeeRank=Employee rank for this skill +Position=Position +Positions=Positions +PositionCard=Position card +EmployeesInThisPosition=Employees in this position +group1ToCompare=Usergroup to analyze +group2ToCompare=Second usergroup for comparison +OrJobToCompare=Compare to job skills requirements +difference=Difference +CompetenceAcquiredByOneOrMore=Competence acquired by one or more users but not requested by the second comparator +MaxlevelGreaterThan=Max level greater than the one requested +MaxLevelEqualTo=Max level equal to that demand +MaxLevelLowerThan=Max level lower than that demand +MaxlevelGreaterThanShort=Employee level greater than the one requested +MaxLevelEqualToShort=Employee level equals to that demand +MaxLevelLowerThanShort=Employee level lower than that demand +SkillNotAcquired=Skill not acquired by all users and requested by the second comparator +legend=Legend +TypeSkill=Skill type +AddSkill=Add skills to job +RequiredSkills=Required skills for this job +UserRank=User Rank +SkillList=Skill list +SaveRank=Save rank +knowHow=Know how +HowToBe=How to be +knowledge=Knowledge +AbandonmentComment=Abandonment comment +DateLastEval=Date last evaluation +NoEval=No evaluation done for this employee +HowManyUserWithThisMaxNote=Number of users with this rank +HighestRank=Highest rank +SkillComparison=Skill comparison diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang index e3b6bed94c8..91811ebf667 100644 --- a/htdocs/langs/en_US/languages.lang +++ b/htdocs/langs/en_US/languages.lang @@ -1,11 +1,13 @@ # Dolibarr language file - Source file is en_US - languages Language_am_ET=Ethiopian Language_ar_AR=Arabic +Language_ar_DZ=Arabic (Algeria) Language_ar_EG=Arabic (Egypt) Language_ar_MA=Arabic (Moroco) Language_ar_SA=Arabic Language_ar_TN=Arabic (Tunisia) Language_ar_IQ=Arabic (Iraq) +Language_as_IN=Assamese Language_az_AZ=Azerbaijani Language_bn_BD=Bengali Language_bn_IN=Bengali (India) @@ -72,6 +74,7 @@ Language_it_IT=Italian Language_it_CH=Italian (Switzerland) Language_ja_JP=Japanese Language_ka_GE=Georgian +Language_kk_KZ=Kazakh Language_km_KH=Khmer Language_kn_IN=Kannada Language_ko_KR=Korean @@ -92,6 +95,7 @@ Language_ro_MD=Romanian (Moldavia) Language_ro_RO=Romanian Language_ru_RU=Russian Language_ru_UA=Russian (Ukraine) +Language_tg_TJ=Tajik Language_tr_TR=Turkish Language_sl_SI=Slovenian Language_sv_SV=Swedish diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 033f86b63aa..22fe0696363 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -60,6 +60,7 @@ EMailTestSubstitutionReplacedByGenericValues=When using test mode, substitutions MailingAddFile=Attach this file NoAttachedFiles=No attached files BadEMail=Bad value for Email +EMailNotDefined=Email not defined ConfirmCloneEMailing=Are you sure you want to clone this emailing? CloneContent=Clone message CloneReceivers=Cloner recipients diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 1756176cc4d..492a20bae77 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -804,6 +804,7 @@ LinkToSupplierInvoice=Link to vendor invoice LinkToContract=Link to contract LinkToIntervention=Link to intervention LinkToTicket=Link to ticket +LinkToMo=Link to Mo CreateDraft=Create draft SetToDraft=Back to draft ClickToEdit=Click to edit @@ -1153,4 +1154,8 @@ ConfirmMassLeaveApprovalQuestion=Are you sure you want to approve the %s selecte ConfirmMassLeaveApproval=Mass leave approval confirmation RecordAproved=Record approved RecordsApproved=%s Record(s) approved -Properties=Properties \ No newline at end of file +Properties=Properties +hasBeenValidated=%s has been validated +ClientTZ=Client Time Zone (user) +NotClosedYet=Not yet closed +ClearSignature=Signature reset \ No newline at end of file diff --git a/htdocs/langs/en_US/margins.lang b/htdocs/langs/en_US/margins.lang index ad5406409b4..a91b139ec7b 100644 --- a/htdocs/langs/en_US/margins.lang +++ b/htdocs/langs/en_US/margins.lang @@ -22,7 +22,7 @@ ProductService=Product or Service AllProducts=All products and services ChooseProduct/Service=Choose product or service ForceBuyingPriceIfNull=Force buying/cost price to selling price if not defined -ForceBuyingPriceIfNullDetails=If buying/cost price not provided when we add a new line, and this option is "ON", the margin will be 0 on the new line (buying/cost price = selling price). If this option is "OFF" (recommended), margin will be equal to the value suggested by default (and may be 100% if no default value can be found). +ForceBuyingPriceIfNullDetails=If buying/cost price not provided when we add a new line, and this option is "ON", the margin will be 0%% on the new line (buying/cost price = selling price). If this option is "OFF" (recommended), margin will be equal to the value suggested by default (and may be 100%% if no default value can be found). MARGIN_METHODE_FOR_DISCOUNT=Margin method for global discounts UseDiscountAsProduct=As a product UseDiscountAsService=As a service diff --git a/htdocs/langs/en_US/members.lang b/htdocs/langs/en_US/members.lang index 5b81bbd69b0..9605e7a8df7 100644 --- a/htdocs/langs/en_US/members.lang +++ b/htdocs/langs/en_US/members.lang @@ -206,7 +206,7 @@ VATToUseForSubscriptions=VAT rate to use for contributionss NoVatOnSubscription=No VAT for contributions ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS=Product used for contribution line into invoice: %s NameOrCompany=Name or company -SubscriptionRecorded=Subscription recorded +SubscriptionRecorded=Contribution recorded NoEmailSentToMember=No email sent to member EmailSentToMember=Email sent to member at %s SendReminderForExpiredSubscriptionTitle=Send reminder by email for expired contributions diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 5d6b51d5fe4..e479438769d 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -98,7 +98,7 @@ MenusDefDescTooltip=The menus provided by your module/application are defined in DictionariesDefDescTooltip=The dictionaries provided by your module/application are defined into the array $this->dictionaries into the module descriptor file. You can edit manually this file or use the embedded editor.

    Note: Once defined (and module re-activated), dictionaries are also visible into the setup area to administrator users on %s. PermissionsDefDescTooltip=The permissions provided by your module/application are defined into the array $this->rights into the module descriptor file. You can edit manually this file or use the embedded editor.

    Note: Once defined (and module re-activated), permissions are visible into the default permissions setup %s. HooksDefDesc=Define in the module_parts['hooks'] property, in the module descriptor, the context of hooks you want to manage (list of contexts can be found by a search on 'initHooks(' in core code).
    Edit the hook file to add code of your hooked functions (hookable functions can be found by a search on 'executeHooks' in core code). -TriggerDefDesc=Define in the trigger file the code you want to execute for each business event executed. +TriggerDefDesc=Define in the trigger file the code that you want to execute when a business event external to your module is executed (events recorded by other modules). SeeIDsInUse=See IDs in use in your installation SeeReservedIDsRangeHere=See range of reserved IDs ToolkitForDevelopers=Toolkit for Dolibarr developers diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index 0b779d55fbd..3f1aac53340 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -32,7 +32,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce @@ -74,6 +74,7 @@ NoStockChangeOnServices=No stock change on services ProductQtyToConsumeByMO=Product quantity still to consume by open MO ProductQtyToProduceByMO=Product quantity still to produce by open MO AddNewConsumeLines=Add new line to consume +AddNewProduceLines=Add new line to produce ProductsToConsume=Products to consume ProductsToProduce=Products to produce UnitCost=Unit cost @@ -103,4 +104,6 @@ HumanMachine=Human / Machine WorkstationArea=Workstation area Machines=Machines THMEstimatedHelp=This rate makes it possible to define a forecast cost of the item -MOAndLines=Manufacturing Orders and lines \ No newline at end of file +BOM=Bill Of Materials +CollapseBOMHelp=You can define the default display of the details of the nomenclature in the configuration of the BOM module +MOAndLines=Manufacturing Orders and lines diff --git a/htdocs/langs/en_US/opensurvey.lang b/htdocs/langs/en_US/opensurvey.lang index 7d26151fa16..9fafacaf8bf 100644 --- a/htdocs/langs/en_US/opensurvey.lang +++ b/htdocs/langs/en_US/opensurvey.lang @@ -48,6 +48,8 @@ AddEndHour=Add end hour votes=vote(s) NoCommentYet=No comments have been posted for this poll yet CanComment=Voters can comment in the poll +YourVoteIsPrivate=This poll is private, nobody can see your vote. +YourVoteIsPublic=This poll is public, anybody with the link can see your vote. CanSeeOthersVote=Voters can see other people's vote SelectDayDesc=For each selected day, you can choose, or not, meeting hours in the following format:
    - empty,
    - "8h", "8H" or "8:00" to give a meeting's start hour,
    - "8-11", "8h-11h", "8H-11H" or "8:00-11:00" to give a meeting's start and end hour,
    - "8h15-11h15", "8H15-11H15" or "8:15-11:15" for the same thing but with minutes. BackToCurrentMonth=Back to current month diff --git a/htdocs/langs/en_US/orders.lang b/htdocs/langs/en_US/orders.lang index aad0010b4af..11220633d61 100644 --- a/htdocs/langs/en_US/orders.lang +++ b/htdocs/langs/en_US/orders.lang @@ -124,6 +124,8 @@ SupplierOrderReceivedInDolibarr=Purchase Order %s received %s SupplierOrderSubmitedInDolibarr=Purchase Order %s submitted SupplierOrderClassifiedBilled=Purchase Order %s set billed OtherOrders=Other orders +SupplierOrderValidatedAndApproved=Supplier order is validated and approved : %s +SupplierOrderValidated=Supplier order is validated : %s ##### Types de contacts ##### TypeContact_commande_internal_SALESREPFOLL=Representative following-up sales order TypeContact_commande_internal_SHIPPING=Representative following-up shipping diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index ea280968ef4..9bc68dc3678 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -35,6 +35,9 @@ OnlyOneFieldForXAxisIsPossible=Only 1 field is currently possible as X-Axis. Onl AtLeastOneMeasureIsRequired=At least 1 field for measure is required AtLeastOneXAxisIsRequired=At least 1 field for X-Axis is required LatestBlogPosts=Latest Blog Posts +notiftouser=To users +notiftofixedemail=To fixed mail +notiftouserandtofixedemail=To user and fixed mail Notify_ORDER_VALIDATE=Sales order validated Notify_ORDER_SENTBYMAIL=Sales order sent by mail Notify_ORDER_SUPPLIER_SENTBYMAIL=Purchase order sent by email diff --git a/htdocs/langs/en_US/partnership.lang b/htdocs/langs/en_US/partnership.lang index f5b9ebcde24..0eb73c17920 100644 --- a/htdocs/langs/en_US/partnership.lang +++ b/htdocs/langs/en_US/partnership.lang @@ -58,6 +58,7 @@ ManagePartnership=Manage partnership BacklinkNotFoundOnPartnerWebsite=Backlink not found on partner website ConfirmClosePartnershipAsk=Are you sure you want to cancel this partnership? PartnershipType=Partnership type +PartnershipRefApproved=Partnership %s approved # # Template Mail diff --git a/htdocs/langs/en_US/printing.lang b/htdocs/langs/en_US/printing.lang index 16494583550..bd9094f213d 100644 --- a/htdocs/langs/en_US/printing.lang +++ b/htdocs/langs/en_US/printing.lang @@ -1,10 +1,10 @@ # Dolibarr language file - Source file is en_US - printing -Module64000Name=Direct Printing -Module64000Desc=Enable Direct Printing System -PrintingSetup=Setup of Direct Printing System -PrintingDesc=This module adds a Print button to various modules to allow documents to be printed directly to a printer without needing to open the document in another application. -MenuDirectPrinting=Direct Printing jobs -DirectPrint=Direct print +Module64000Name=One click Printing +Module64000Desc=Enable One click Printing System +PrintingSetup=Setup of One click Printing System +PrintingDesc=This module adds a Print button to various modules to allow documents to be printed directly to a printer with no need to open the document into another application. +MenuDirectPrinting=One click Printing jobs +DirectPrint=One click Print PrintingDriverDesc=Configuration variables for printing driver. ListDrivers=List of drivers PrintTestDesc=List of Printers. diff --git a/htdocs/langs/en_US/productbatch.lang b/htdocs/langs/en_US/productbatch.lang index 763af20c6b4..71e44e8f281 100644 --- a/htdocs/langs/en_US/productbatch.lang +++ b/htdocs/langs/en_US/productbatch.lang @@ -37,7 +37,8 @@ ManufacturingDate=Manufacturing date DestructionDate=Destruction date FirstUseDate=First use date QCFrequency=Quality control frequency (in days) - +ShowAllLots=Show all lots +HideLots=Hide lots #Traceability - qc status OutOfOrder=Out of order InWorkingOrder=In working order diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index ae199f4136b..205a28980a8 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -75,6 +75,7 @@ SellingPriceTTC=Selling price (inc. tax) SellingMinPriceTTC=Minimum Selling price (inc. tax) CostPriceDescription=This price field (excl. tax) can be used to capture the average amount this product costs to your company. It may be any price you calculate yourself, for example, from the average buying price plus average production and distribution cost. CostPriceUsage=This value could be used for margin calculation. +ManufacturingPrice=Manufacturing price SoldAmount=Sold amount PurchasedAmount=Purchased amount NewPrice=New price @@ -315,7 +316,7 @@ LastUpdated=Latest update CorrectlyUpdated=Correctly updated PropalMergePdfProductActualFile=Files use to add into PDF Azur are/is PropalMergePdfProductChooseFile=Select PDF files -IncludingProductWithTag=Include products/services with tag +IncludingProductWithTag=Including products/services with the tag DefaultPriceRealPriceMayDependOnCustomer=Default price, real price may depend on customer WarningSelectOneDocument=Please select at least one document DefaultUnitToShow=Unit @@ -397,7 +398,13 @@ ActionAvailableOnVariantProductOnly=Action only available on the variant of prod ProductsPricePerCustomer=Product prices per customers ProductSupplierExtraFields=Additional Attributes (Supplier Prices) DeleteLinkedProduct=Delete the child product linked to the combination +AmountUsedToUpdateWAP=Amount to use to update the Weighted Average Price PMPValue=Weighted average price PMPValueShort=WAP +mandatoryperiod=Mandatory periods +mandatoryPeriodNeedTobeSet=Attention periods not entered and mandatory +mandatoryPeriodNeedTobeSetMsgValidate=A service requires a start and end period +mandatoryHelper=Message to the user on the need to enter a start date and an end date on a service when creating / validating an invoice, commercial proposal, sales order.
    This action is not blocking in the process of confirmation DefaultBOM=Default BOM -DefaultBOMDesc=The default BOM recommended to use to manufacture this product. This field can be set only if nature of product is '%s'. \ No newline at end of file +DefaultBOMDesc=The default BOM recommended to use to manufacture this product. This field can be set only if nature of product is '%s'. +Rank=Rank diff --git a/htdocs/langs/en_US/projects.lang b/htdocs/langs/en_US/projects.lang index 6709a1de200..0b713a2197b 100644 --- a/htdocs/langs/en_US/projects.lang +++ b/htdocs/langs/en_US/projects.lang @@ -282,3 +282,5 @@ UsageOrganizeEvent=Usage: Event Organization PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE=Classify project as closed when all its tasks are completed (100%% progress) PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Note: existing projects with all tasks at 100 %% progress won't be affected: you will have to close them manually. This option only affects open projects. SelectLinesOfTimeSpentToInvoice=Select lines of time spent that are unbilled, then bulk action "Generate Invoice" to bill them +ProjectTasksWithoutTimeSpent=Project tasks without time spent +FormForNewLeadDesc=Thanks to fill the following form to contact us. You can also send us an email directly to %s. \ No newline at end of file diff --git a/htdocs/langs/en_US/propal.lang b/htdocs/langs/en_US/propal.lang index edbc08236d3..ed07831fcba 100644 --- a/htdocs/langs/en_US/propal.lang +++ b/htdocs/langs/en_US/propal.lang @@ -89,4 +89,11 @@ IdProposal=Proposal ID IdProduct=Product ID PrParentLine=Proposal Parent Line LineBuyPriceHT=Buy Price Amount net of tax for line - +SignPropal=Accept proposal +RefusePropal=Refuse proposal +Sign=Sign +PropalAlreadySigned=Proposal already accepted +PropalAlreadyRefused=Proposal already refused +PropalSigned=Proposal accepted +PropalRefused=Proposal refused +ConfirmRefusePropal=Are you sure you want to refuse this commercial proposal? diff --git a/htdocs/langs/en_US/receptions.lang b/htdocs/langs/en_US/receptions.lang index 4ee0555c396..46b2d689609 100644 --- a/htdocs/langs/en_US/receptions.lang +++ b/htdocs/langs/en_US/receptions.lang @@ -45,3 +45,4 @@ ReceptionsNumberingModules=Numbering module for receptions ReceptionsReceiptModel=Document templates for receptions NoMorePredefinedProductToDispatch=No more predefined products to dispatch ReceptionExist=A reception exists +ByingPrice=Bying price diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang index 504f0fbcc16..c0e115a20df 100644 --- a/htdocs/langs/en_US/salaries.lang +++ b/htdocs/langs/en_US/salaries.lang @@ -6,6 +6,7 @@ CREATE_NEW_SALARY_WITHOUT_AUTO_PAYMENT=By default, leave empty the option "Autom Salary=Salary Salaries=Salaries NewSalary=New salary +AddSalary=Add salary NewSalaryPayment=New salary card AddSalaryPayment=Add salary payment SalaryPayment=Salary payment @@ -21,4 +22,5 @@ LastSalaries=Latest %s salaries AllSalaries=All salaries SalariesStatistics=Salary statistics SalariesAndPayments=Salaries and payments -ConfirmDeleteSalaryPayment=Do you want to delete this salary payment ? \ No newline at end of file +ConfirmDeleteSalaryPayment=Do you want to delete this salary payment ? +FillFieldFirst=Fill employee field first diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 638221460a6..8c0cc76f075 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -12,9 +12,9 @@ AddWarehouse=Create warehouse AddOne=Add one DefaultWarehouse=Default warehouse WarehouseTarget=Target warehouse -ValidateSending=Confirm sending -CancelSending=Cancel sending -DeleteSending=Delete sending +ValidateSending=Confirm shipment +CancelSending=Cancel shipment +DeleteSending=Delete shipment Stock=Stock Stocks=Stocks MissingStocks=Missing stocks @@ -63,6 +63,7 @@ RuleForWarehouse=Rule for warehouses WarehouseAskWarehouseOnThirparty=Set a warehouse on Third-parties WarehouseAskWarehouseDuringPropal=Set a warehouse on Commercial proposals WarehouseAskWarehouseDuringOrder=Set a warehouse on Sales Orders +WarehouseAskWarehouseDuringProject=Set a warehouse on Projects UserDefaultWarehouse=Set a warehouse on Users MainDefaultWarehouse=Default warehouse MainDefaultWarehouseUser=Use a default warehouse for each user @@ -262,4 +263,4 @@ ErrorSameBatchNumber=Same batch number found in inventory list ProductBatchDoesNotExist=Product with batch/serial does not exist ProductBarcodeDoesNotExist=Product with barcode does not exist WarehouseId=Warehouse ID -WarehouseRef=Warehouse Ref \ No newline at end of file +WarehouseRef=Warehouse Ref diff --git a/htdocs/langs/en_US/ticket.lang b/htdocs/langs/en_US/ticket.lang index 6243e98fdc9..d38358eb74d 100644 --- a/htdocs/langs/en_US/ticket.lang +++ b/htdocs/langs/en_US/ticket.lang @@ -45,6 +45,8 @@ TicketSeverityShortNORMAL=Normal TicketSeverityShortHIGH=High TicketSeverityShortBLOCKING=Critical, Blocking +TicketCategoryShortOTHER=Other + ErrorBadEmailAddress=Field '%s' incorrect MenuTicketMyAssign=My tickets MenuTicketMyAssignNonClosed=My open tickets @@ -316,6 +318,7 @@ BoxTicketLastXDays=Number of new tickets by days the last %s days BoxTicketLastXDayswidget = Number of new tickets by days the last X days BoxNoTicketLastXDays=No new tickets the last %s days BoxNumberOfTicketByDay=Number of new tickets by day -BoxNewTicketVSClose=Number of today's new tickets versus today's closed tickets +BoxNewTicketVSClose=Number of tickets versus closed tickets (today) TicketCreatedToday=Ticket created today -TicketClosedToday=Ticket closed today \ No newline at end of file +TicketClosedToday=Ticket closed today +KMFoundForTicketGroup=We found topics and FAQs that may answers your question, thanks to check them before submitting the ticket diff --git a/htdocs/langs/en_US/trips.lang b/htdocs/langs/en_US/trips.lang index c9a6c792077..9210ede360c 100644 --- a/htdocs/langs/en_US/trips.lang +++ b/htdocs/langs/en_US/trips.lang @@ -112,7 +112,7 @@ ConfirmCloneExpenseReport=Are you sure you want to clone this expense report ? ExpenseReportsIk=Configuration of mileage charges ExpenseReportsRules=Expense report rules ExpenseReportIkDesc=You can modify the calculation of kilometers expense by category and range who they are previously defined. d is the distance in kilometers -ExpenseReportRulesDesc=You can create or update any rules of calculation. This part will be used when user will create a new expense report +ExpenseReportRulesDesc=You can define max amount rules for expense reports. These rules will be applied when a new expense is added to an expense report expenseReportOffset=Offset expenseReportCoef=Coefficient expenseReportTotalForFive=Example with d = 5 @@ -127,19 +127,19 @@ ExpenseReportDomain=Domain to apply ExpenseReportLimitOn=Limit on ExpenseReportDateStart=Date start ExpenseReportDateEnd=Date end -ExpenseReportLimitAmount=Limite amount -ExpenseReportRestrictive=Restrictive +ExpenseReportLimitAmount=Max amount +ExpenseReportRestrictive=Exceeding forbidden AllExpenseReport=All type of expense report OnExpense=Expense line ExpenseReportRuleSave=Expense report rule saved ExpenseReportRuleErrorOnSave=Error: %s RangeNum=Range %d -ExpenseReportConstraintViolationError=Constraint violation id [%s]: %s is superior to %s %s +ExpenseReportConstraintViolationError=Max amount exceeded (rule %s): %s is higher than %s (Exceeding forbidden) byEX_DAY=by day (limitation to %s) byEX_MON=by month (limitation to %s) byEX_YEA=by year (limitation to %s) byEX_EXP=by line (limitation to %s) -ExpenseReportConstraintViolationWarning=Constraint violation id [%s]: %s is superior to %s %s +ExpenseReportConstraintViolationWarning=Max amount exceeded (rule %s): %s is higher than %s (Exceeding authorized) nolimitbyEX_DAY=by day (no limitation) nolimitbyEX_MON=by month (no limitation) nolimitbyEX_YEA=by year (no limitation) diff --git a/htdocs/langs/es_AR/admin.lang b/htdocs/langs/es_AR/admin.lang index b210f358131..f9e77952b89 100644 --- a/htdocs/langs/es_AR/admin.lang +++ b/htdocs/langs/es_AR/admin.lang @@ -91,7 +91,6 @@ Destination=Destino IdModule=ID de módulo IdPermissions=ID de permisos LanguageBrowserParameter=Parámetro %s -ClientTZ=Zona horaria del cliente (usuario) ClientHour=Tiempo del cliente (usuario) OSTZ=Zona horaria del SO del servidor PHPTZ=Zona horaria del servidor PHP diff --git a/htdocs/langs/es_CL/admin.lang b/htdocs/langs/es_CL/admin.lang index be394b057d4..138d8a4b455 100644 --- a/htdocs/langs/es_CL/admin.lang +++ b/htdocs/langs/es_CL/admin.lang @@ -95,7 +95,6 @@ Destination=Destino IdModule=ID del módulo IdPermissions=ID de permisos LanguageBrowserParameter=Parámetro %s -ClientTZ=Zona horaria del cliente (usuario) ClientHour=Hora del cliente (usuario) OSTZ=Zona horaria del servidor OS PHPTZ=Servidor PHP Zona horaria diff --git a/htdocs/langs/es_CO/admin.lang b/htdocs/langs/es_CO/admin.lang index e6e2e7de2cd..84170023e1e 100644 --- a/htdocs/langs/es_CO/admin.lang +++ b/htdocs/langs/es_CO/admin.lang @@ -100,7 +100,6 @@ Destination=Destino IdModule=ID de módulo IdPermissions=ID de permisos LanguageBrowserParameter=Parámetro %s -ClientTZ=Zona Horaria del Cliente (usuario) ClientHour=Hora del Cliente (usuario) OSTZ=Zona Horaria del SO del Servidor PHPTZ=Zona Hora del servidor PHP diff --git a/htdocs/langs/es_EC/admin.lang b/htdocs/langs/es_EC/admin.lang index 1f7f805b2ab..1a42f9095b6 100644 --- a/htdocs/langs/es_EC/admin.lang +++ b/htdocs/langs/es_EC/admin.lang @@ -90,7 +90,6 @@ Destination=Destino IdModule=Módulo de Identificación IdPermissions=ID de permisos LanguageBrowserParameter=Parámetros %s -ClientTZ=Zona horaria del cliente ClientHour=Hora del cliente OSTZ=Zona horaria del servidor PHPTZ=Zona horaria del servidor PHP diff --git a/htdocs/langs/es_ES/admin.lang b/htdocs/langs/es_ES/admin.lang index 9298219c73f..016b303e18b 100644 --- a/htdocs/langs/es_ES/admin.lang +++ b/htdocs/langs/es_ES/admin.lang @@ -280,6 +280,7 @@ SpaceX=Área X SpaceY=Área Y FontSize=Tamaño de fuente Content=Contenido +ContentForLines=Contenido a mostrar por cada línea de producto o servicio (de la variable __LINES__ definida en Contenido) NoticePeriod=Plazo de aviso NewByMonth=Nuevo por mes Emails=E-Mails diff --git a/htdocs/langs/es_ES/bills.lang b/htdocs/langs/es_ES/bills.lang index a2b687a3b3a..dc312787fb3 100644 --- a/htdocs/langs/es_ES/bills.lang +++ b/htdocs/langs/es_ES/bills.lang @@ -244,6 +244,7 @@ EscompteOffered=Descuento (Pronto pago) EscompteOfferedShort=Descuento SendBillRef=Envío de la factura %s SendReminderBillRef=Envío de la factura %s (recordatorio) +SendPaymentReceipt=Envío del recibo de pago %s NoDraftBills=Ninguna factura borrador NoOtherDraftBills=Ninguna otra factura borrador NoDraftInvoices=Sin facturas borrador diff --git a/htdocs/langs/es_MX/admin.lang b/htdocs/langs/es_MX/admin.lang index 46c04d6b049..61a78207c66 100644 --- a/htdocs/langs/es_MX/admin.lang +++ b/htdocs/langs/es_MX/admin.lang @@ -86,7 +86,6 @@ IdModule=ID del módulo IdPermissions=ID de permisos LanguageBrowserParameter=Parámetro %s LocalisationDolibarrParameters=Parametros de localización -ClientTZ=Zona Horaria cliente (usuario) OSTZ=Servidor OS Zona Horaria PHPTZ=Servidor PHP Zona Horaria DaylingSavingTime=Hora de verano diff --git a/htdocs/langs/es_MX/eventorganization.lang b/htdocs/langs/es_MX/eventorganization.lang index bcb01e7daa4..49279d946ab 100644 --- a/htdocs/langs/es_MX/eventorganization.lang +++ b/htdocs/langs/es_MX/eventorganization.lang @@ -3,7 +3,6 @@ ModuleEventOrganizationName =Organización de Eventos EventOrganizationDescription =Organización de Eventos a través el Módulo de Proyectos EventOrganizationDescriptionLong=Administrar organización de evento para conferencias, participantes, presentador, y participantes, con página de suscripción pública EventOrganizationConferenceOrBoothMenuLeft =Conferencia o Puesto -EventOrganizationSetup =Configuración de Organización de Evento EventOrganizationSetupPage =Página de organización de evento EVENTORGANIZATION_TASK_LABEL =Etiqueta de tareas para crear automáticamente cuando el proyecto sea validado EVENTORGANIZATION_TASK_LABELTooltip =Cuando validas un evento organizado, algunas tareas pueden ser creadas automáticamente en el proyecto

    Por ejemplo:
    diff --git a/htdocs/langs/et_EE/mrp.lang b/htdocs/langs/et_EE/mrp.lang index c7146c45dfe..32e99e6e6b7 100644 --- a/htdocs/langs/et_EE/mrp.lang +++ b/htdocs/langs/et_EE/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/eu_ES/mrp.lang b/htdocs/langs/eu_ES/mrp.lang index acf5a23db9b..a6e57a1168a 100644 --- a/htdocs/langs/eu_ES/mrp.lang +++ b/htdocs/langs/eu_ES/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/fa_IR/mrp.lang b/htdocs/langs/fa_IR/mrp.lang index c00afb9dd3a..d536b6b661c 100644 --- a/htdocs/langs/fa_IR/mrp.lang +++ b/htdocs/langs/fa_IR/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/fi_FI/mrp.lang b/htdocs/langs/fi_FI/mrp.lang index 2eafe6926bb..14f2af7e1fe 100644 --- a/htdocs/langs/fi_FI/mrp.lang +++ b/htdocs/langs/fi_FI/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Valmistustilaukset NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/fr_FR/accountancy.lang b/htdocs/langs/fr_FR/accountancy.lang index 069e7bba7a9..a92660eb872 100644 --- a/htdocs/langs/fr_FR/accountancy.lang +++ b/htdocs/langs/fr_FR/accountancy.lang @@ -37,8 +37,8 @@ OtherInfo=Autre information DeleteCptCategory=Supprimer le code comptable du groupe ConfirmDeleteCptCategory=Êtes-vous sur de vouloir supprimer ce compte comptable du groupe comptable ? JournalizationInLedgerStatus=Statut de journalisation -AlreadyInGeneralLedger=Déjà transféré en comptabilité -NotYetInGeneralLedger=Pas encore transféré en comptabilité +AlreadyInGeneralLedger=Already transferred to accounting journals and ledger +NotYetInGeneralLedger=Not yet transferred to accouting journals and ledger GroupIsEmptyCheckSetup=Le groupe est vide. Vérifier la configuration du groupe personnalisé DetailByAccount=Afficher le détail par compte AccountWithNonZeroValues=Comptes avec des valeurs non nulles @@ -246,9 +246,9 @@ DescThirdPartyReport=Consultez ici la liste des tiers clients et fournisseurs et ListAccounts=Liste des comptes comptables UnknownAccountForThirdparty=Compte de tiers inconnu. %s sera utilisé UnknownAccountForThirdpartyBlocking=Compte de tiers inconnu. Erreur bloquante. -ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Subledger account not defined or third party or user unknown. We will use %s +ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Compte auxiliaire non défini ou tiers ou utilisateur inconnu. Nous utiliserons %s ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored=Tiers inconnu et code comptable auxiliaire non défini sur le paiement. Nous conserverons la valeur du compte auxiliaire vide. -ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking=Subledger account not defined or third party or user unknown. Blocking error. +ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking=Compte auxiliaire non défini ou tiers ou utilisateur inconnu. Erreur blocante. UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking=Compte tiers inconnu et compte d'attente non défini. Erreur blocante. PaymentsNotLinkedToProduct=Paiement non lié à un produit / service OpeningBalance=Solde d'ouverture @@ -298,7 +298,7 @@ NoNewRecordSaved=Plus d'enregistrements à journaliser ListOfProductsWithoutAccountingAccount=Liste des produits non liés à un compte comptable ChangeBinding=Changer les liens Accounted=En comptabilité -NotYetAccounted=Pas encore comptabilisé en comptabilité +NotYetAccounted=Not yet transferred to accounting ShowTutorial=Afficher le tutoriel NotReconciled=Non rapproché WarningRecordWithoutSubledgerAreExcluded=Attention : toutes les opérations sans compte auxiliaire défini sont filtrées et exclues de cet écran @@ -329,8 +329,8 @@ ACCOUNTING_DISABLE_BINDING_ON_PURCHASES=Désactiver la liaison et le transfert e ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS=Désactiver la liaison et le transfert en comptabilité des notes de frais (les notes de frais ne seront pas prises en compte en comptabilité). ## Export -NotifiedExportDate=Date d'exportation notifiée (la modification des enregistrements ne sera pas possible) -NotifiedValidationDate=Validation des enregistrements (la modification ou la suppression des enregistrements ne sera pas possible) +NotifiedExportDate=Flag exported lines as exported (modification of the lines will not be possible) +NotifiedValidationDate=Validate the exported entries (modification or deletion of the lines will not be possible) ConfirmExportFile=Confirmation de la génération du fichier d'export comptable ? ExportDraftJournal=Exporter le journal brouillon Modelcsv=Modèle d'export @@ -339,11 +339,11 @@ Modelcsv_normal=Export standard Modelcsv_CEGID=Export vers CEGID Expert comptabilité Modelcsv_COALA=Export vers Sage Coala Modelcsv_bob50=Export vers Sage BOB 50 -Modelcsv_ciel=Export for Sage50, Ciel Compta or Compta Evo. (Format XIMPORT) +Modelcsv_ciel=Export vers Sage50, Ciel Compta ou Compta Evo. (Format XIMPORT) Modelcsv_quadratus=Export vers Quadratus QuadraCompta Modelcsv_ebp=Export vers EBP Modelcsv_cogilog=Export vers Cogilog -Modelcsv_agiris=Export vers Agiris +Modelcsv_agiris=Export for Agiris Isacompta Modelcsv_LDCompta=Export pour LD Compta (v9) (Test) Modelcsv_LDCompta10=Export pour LD Compta (v10 et supérieure) Modelcsv_openconcerto=Export pour OpenConcerto (Test) @@ -351,9 +351,10 @@ Modelcsv_configurable=Export configurable Modelcsv_FEC=Export FEC Modelcsv_FEC2=Export FEC (avec dates enregistrement et document inversées) Modelcsv_Sage50_Swiss=Export pour Sage 50 Suisse -Modelcsv_winfic=Export pour Winfic - eWinfic - WinSis Compta +Modelcsv_winfic=Export for Winfic - eWinfic - WinSis Compta Modelcsv_Gestinumv3=Export vers Gestinum (v3) -Modelcsv_Gestinumv5Export Pour Gestinum (V5) +Modelcsv_Gestinumv5=Export for Gestinum (v5) +Modelcsv_charlemagne=Export for Aplim Charlemagne ChartofaccountsId=Id plan comptable ## Tools - Init accounting account on product / service diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index efab72ea66b..01498f3fce1 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -75,7 +75,7 @@ Dictionary=Dictionnaires ErrorReservedTypeSystemSystemAuto=Erreur, les valeurs 'system' et 'systemauto' sont réservées. Vous pouvez utiliser la valeur 'user' pour ajouter vos propres enregistrements ErrorCodeCantContainZero=Erreur, le code ne peut contenir la valeur 0 DisableJavascript=Désactiver les fonctions Javascript et Ajax -DisableJavascriptNote=Remarque: à des fins de test ou de débogage. Pour une optimisation pour les personnes malvoyantes ou les navigateurs texte, il vaut mieux utiliser la configuration sur le profil utilisateur +DisableJavascriptNote=Note: For test or debug purpose only. For optimization for blind person or text browsers, you may prefer to use the setup on the profile of user UseSearchToSelectCompanyTooltip=Si vous avez un nombre important de tiers (>100 000), vous pourrez améliorer les performances en positionnant la constante COMPANY_DONOTSEARCH_ANYWHERE à 1 dans Configuration->Divers. La recherche sera alors limité au début des chaines. UseSearchToSelectContactTooltip=Si vous avez un nombre important de contacts (>100 000), vous pourrez améliorer les performances en positionnant la constante CONTACT_DONOTSEARCH_ANYWHERE à 1 dans Configuration->Divers. La recherche sera alors limité au début des chaines. DelaiedFullListToSelectCompany=Attendre que vous ayez appuyé sur une touche avant de charger le contenu de la liste déroulante des tiers.
    Cela peut augmenter les performances si vous avez un grand nombre de tiers, mais cela est moins convivial. @@ -133,7 +133,6 @@ IdModule=ID Module IdPermissions=ID Permissions LanguageBrowserParameter=Variable %s LocalisationDolibarrParameters=Paramètres de localisation -ClientTZ=Fuseau horaire client (utilisateur) ClientHour=Heure client (utilisateur) OSTZ=Fuseau horaire OS PHPTZ=Fuseau horaire serveur PHP @@ -161,7 +160,7 @@ Purge=Purger PurgeAreaDesc=Cette page vous permet d'effacer tous les fichiers construits ou stockés par Dolibarr (fichiers temporaires ou tous les fichiers du répertoire %s). L'utilisation de cette fonction n'est pas nécessaire. Elle est fournie pour les utilisateurs qui hébergent Dolibarr chez un hébergeur qui n'offre pas les permissions de supprimer les fichiers sauvegardés par le serveur Web. PurgeDeleteLogFile=Effacer les fichiers de traces de debug, incluant %s défini dans le module 'Journaux et traces' (pas de risque de perte de données) PurgeDeleteTemporaryFiles=Supprimer tous les fichiers journaux et temporaires (aucun risque de perte de données). Le paramètre peut être "tempfilesold", "logfiles" ou les deux "tempfilesold + logfiles". Remarque : la suppression des fichiers temporaires est effectuée uniquement si le répertoire temporaire qui le contient a été créé il y a plus de 24 heures. -PurgeDeleteTemporaryFilesShort=Effacer les fichiers de log et fichiers temporaires +PurgeDeleteTemporaryFilesShort=Delete log and temporary files (no risk of losing data) PurgeDeleteAllFilesInDocumentsDir=Effacer tous les fichiers du répertoire %s.
    Les fichiers temporaires mais aussi les fichiers «dumps» de sauvegarde de base de données, les fichiers joints aux éléments (tiers, factures, ...) ou fichiers stockés dans le module GED seront irrémédiablement effacés. PurgeRunNow=Lancer la purge maintenant PurgeNothingToDelete=Aucun dossier ou fichier à supprimer. @@ -210,8 +209,8 @@ FeatureDisabledInDemo=Fonction désactivée dans la démo FeatureAvailableOnlyOnStable=Fonction disponible uniquement sur les versions officielles stables BoxesDesc=Les widgets sont des composants montrant des informations que vous pouvez ajouter à vos pages pour les personnaliser. Vous pouvez choisir de les afficher ou non en sélectionnant la page cible et en cliquant sur "Activer" ou "Désactiver". OnlyActiveElementsAreShown=Seuls les éléments en rapport avec un module actif sont présentés. -ModulesDesc=Les modules Dolibarr définissent quelles fonctionnalités sont disponibles dans le logiciel. Certains modules / applications nécessitent, après activation, d'accorder des autorisations aux utilisateurs. Cliquez sur le bouton activé/désactivé %s pour activer un module/application. -ModulesDesc2=Cliquez sur l'icône roue dentelée %s pour configurer le module/l'application. +ModulesDesc=Les modules/applications définissent quelles fonctionnalités sont disponibles dans le logiciel. Certains modules nécessitent d'accorder des permissions aux utilisateurs après leur activation. Cliquez sur le bouton Activer/Désactiver %s de chaque module pour activer ou désactiver un module/application. +ModulesDesc2=Cliquez sur l'icône de roue dentelée %s pour configurer le module/l'application. ModulesMarketPlaceDesc=D'autres modules/extensions sont disponibles en téléchargement sur des sites externes sur Internet... ModulesDeployDesc=Si les permissions de votre système de fichier le permettent , vous pouvez utiliser cet outil pour déployer un module externe. Le module sera alors visible dans l'onglet %s. ModulesMarketPlaces=Rechercher un module/application externe @@ -375,8 +374,8 @@ UMask=Masque des nouveaux fichiers sous Unix/Linux/BSD/Mac. UMaskExplanation=Ce paramètre permet de définir les droits des fichiers créés sur le serveur par Dolibarr (lors d'envois par exemple).
    Ce doit être la valeur octale (par exemple 0666 signifie lecture/écriture pour tous).
    Ce paramètre n'a aucun effet sur un serveur Windows. SeeWikiForAllTeam=Voir le wiki pour le détail de tous les contributeurs et leur organisation UseACacheDelay= Délai de mise en cache de l'export en secondes (0 ou vide pour aucun cache) -DisableLinkToHelpCenter=Cacher le lien «Besoin d'aide ou d'assistance» sur la page de connexion -DisableLinkToHelp=Cacher le lien vers l'aide en ligne %s +DisableLinkToHelpCenter=Cacher le lien «Besoin d'aide ou assistance» sur la page de connexion +DisableLinkToHelp=Cacher le lien vers l'aide en ligne "%s" AddCRIfTooLong=Il n'y a pas de coupure de ligne automatique, aussi si votre texte est trop long sur les documents, il faudra ajouter vous même des retours chariot dans la zone de saisie du texte ConfirmPurge=Êtes-vous sûr de vouloir réaliser cette purge ?
    Ceci effacera définitivement tous vos fichiers (espace GED, pièces jointes, etc...). MinLength=Longueur minimale @@ -498,7 +497,7 @@ WarningPHPMail=AVERTISSEMENT: la configuration pour envoyer des e-mails à parti WarningPHPMailA= - L'utilisation des serveurs de prestataires de messagerie augmente le niveau confiance des e-mails, cela augmente donc les chances de délivrabilité en n'étant pas considéré comme spam. WarningPHPMailB=- Certains fournisseurs de services de messagerie (comme Yahoo) ne vous permettent pas d'envoyer un e-mail à partir d'un autre serveur que leur propre serveur. Votre configuration actuelle utilise le serveur de l'application pour envoyer des e-mails et non le serveur de votre fournisseur de messagerie, donc certains destinataires (ceux compatibles avec le protocole DMARC restrictif), demanderont à votre fournisseur de messagerie si ils peuvent accepter votre message et ce fournisseur de messagerie (comme Yahoo) peut répondre «non» parce que le serveur d'envoi n'est pas le leur, aussi une partie de vos e-mails envoyés peuvent ne pas être acceptés pour la livraison (faites également attention au quota d'envoi de votre fournisseur de messagerie). WarningPHPMailC=- Utiliser le serveur SMTP de votre propre fournisseur de services de messagerie pour envoyer des e-mails est également intéressant afin que tous les e-mails envoyés depuis l'application soient également enregistrés dans votre répertoire "Envoyés" de votre boîte aux lettres. -WarningPHPMailD=Aussi, il est donc recommandé de modifier la méthode d'envoi des e-mails sur la valeur "SMTP". Si vous voulez vraiment conserver la méthode par défaut "PHP", alors vous pouvez ignorer cette alerte ou la supprimer en activant à 1 la constante MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP dans Accueil - Configuration - Divers +WarningPHPMailD=Also, it is therefore recommended to change the sending method of e-mails to the value "SMTP". If you really want to keep the default "PHP" method to send emails, just ignore this warning, or remove it by setting the MAIN_HIDE_WARNING_TO_ENCOURAGE_SMTP_SETUP constant to 1 in Home - Setup - Other. WarningPHPMail2=Si votre fournisseur de messagerie SMTP a besoin de restreindre le client de messagerie à certaines adresses IP (très rare), voici l'adresse IP du mail user agent (MUA) de votre application CRM ERP : %s . WarningPHPMailSPF=Si le nom de domaine de votre adresse e-mail d'expéditeur est protégé par un enregistrement SPF (demandez à votre fournisseur de nom de domaine), vous devez inclure les adresses IP suivantes dans l'enregistrement SPF du DNS de votre domaine: %s . ClickToShowDescription=Cliquer pour afficher la description @@ -517,6 +516,9 @@ Field=Champ ProductDocumentTemplates=Modèle de document pour la fiche produit FreeLegalTextOnExpenseReports=Mention complémentaire sur les notes de frais WatermarkOnDraftExpenseReports=Filigrane sur les notes de frais +ProjectIsRequiredOnExpenseReports=The project is mandatory for entering an expense report +PrefillExpenseReportDatesWithCurrentMonth=Pre-fill start and end dates of new expense report with start and end dates of the current month +ForceExpenseReportsLineAmountsIncludingTaxesOnly=Force the entry of expense report amounts always in amount with taxes AttachMainDocByDefault=Définissez cette valeur sur 1 si vous souhaitez joindre le document principal au courrier électronique par défaut (si applicable) FilesAttachedToEmail=Joindre le fichier SendEmailsReminders=Envoyer des rappels agenda par e-mails @@ -566,7 +568,7 @@ Module53Desc=Gestion des services Module54Name=Contrats/Abonnements Module54Desc=Gestion des contrats (services ou abonnements récurrents) Module55Name=Codes-barres -Module55Desc=Code-barre ou QR Code +Module55Desc=Gestion de Code-barre ou QR Code Module56Name=Paiement par virement bancaire Module56Desc=Gestion des paiements de fournisseurs par virement bancaire. Est incluse la génération des fichiers SEPA pour les pays européens. Module57Name=Règlement par Prélèvement @@ -898,6 +900,11 @@ Permission1002=Créer/modifier entrepôts Permission1003=Supprimer entrepôts Permission1004=Consulter les mouvements de stocks Permission1005=Créer/modifier les mouvements de stocks +Permission1011=Voir les inventaires +Permission1012=Créer un nouvel inventaire +Permission1014=Valider l'inventaire +Permission1015=Autoriser à changer la valeur PMP d'un produit +Permission1016=Supprimer l'inventaire Permission1101=Lire les bons de réception Permission1102=Créer/modifier les bons de réception Permission1104=Valider les bons de réception @@ -1035,7 +1042,7 @@ DictionaryFees=Note de frais - Types de lignes de notes de frais DictionarySendingMethods=Méthodes d'expédition DictionaryStaff=Effectifs DictionaryAvailability=Délai de livraison -DictionaryOrderMethods=Méthodes de commandes +DictionaryOrderMethods=Order methods DictionarySource=Origines des propales/commandes DictionaryAccountancyCategory=Groupes personalisés pour les rapports DictionaryAccountancysystem=Modèles de plan comptable @@ -1168,7 +1175,8 @@ DoNotSuggestPaymentMode=Ne pas suggérer NoActiveBankAccountDefined=Aucun compte bancaire actif défini OwnerOfBankAccount=Propriétaire du compte %s BankModuleNotActive=Module comptes bancaires non activé -ShowBugTrackLink=Définir le lien "%s" (vide pour ne pas afficher ce lien, 'github' pour le lien vers le projet Dolibarr ou définir directement une url 'https:/...') +ShowBugTrackLink=Afficher le lien "%s" +ShowBugTrackLinkDesc=Keep empty to not display this link, use value 'github' for the link to the Dolibarr project or define directly an url 'https://...' Alerts=Alertes DelaysOfToleranceBeforeWarning=Délais avant affichage de l'avertissement alerte retard DelaysOfToleranceDesc=Cet écran permet de définir les délais de tolérance après lesquels une alerte sera signalée à l'écran par le pictogramme %s sur chaque élément en retard. @@ -1193,9 +1201,9 @@ SetupDescription2=Les deux étapes obligatoires sont les deux premières entrée SetupDescription3=%s -> %s

    Paramètres basiques pour personnaliser le comportement par défaut du logiciel (comportement lié au pays par exemple). SetupDescription4= %s -> %s

    Ce logiciel est un ensemble de plusieurs modules/applications. Les fonctionnalités en rapport avec vos besoins doivent être activées et configurées. Les entrées menus seront ajoutées avec l'activation de ces modules. SetupDescription5=Les autres entrées de configuration gèrent des paramètres facultatifs. -SetupDescriptionLink=%s - %s -SetupDescription3b=Basic parameters used to customize the default behavior of your application (e.g for country-related features). -SetupDescription4b=This software is a suite of many modules/applications. The modules related to your needs must be enabled and configured. Menu entries will appears with the activation of these modules. +SetupDescriptionLink= %s - %s +SetupDescription3b=Paramètres de base utilisés pour personnaliser le comportement par défaut de votre application (par exemple pour les fonctionnalités liées au pays). +SetupDescription4b=Ce logiciel est une suite de nombreux modules/applications. Les modules liés à vos besoins doivent être activés et configurés. Les entrées de menu apparaîtront avec l'activation de ces modules. AuditedSecurityEvents=Événements de sécurité audités NoSecurityEventsAreAduited=Aucun événement de sécurité n'est audité. Vous pouvez les activer à partir du menu %s Audit=Événements de sécurité @@ -1218,7 +1226,7 @@ SystemAreaForAdminOnly=Cet espace n'est accessible qu'aux utilisateurs de type a CompanyFundationDesc=Modifiez les informations de votre société/organisation. Cliquez sur le bouton "%s" en bas de page pour sauvegarder. AccountantDesc=Si vous avez un comptable externe, vous pouvez saisir ici ses informations. AccountantFileNumber=Code comptable -DisplayDesc=Vous pouvez choisir ici tous les paramètres liés à l'apparence de Dolibarr +DisplayDesc=Les paramètres affectant l'apparence et la présentation de l'application peuvent être modifiés ici. AvailableModules=Modules/applications disponibles ToActivateModule=Pour activer des modules, aller dans l'espace Configuration (Accueil->Configuration->Modules). SessionTimeOut=Délai expiration des sessions @@ -1270,7 +1278,7 @@ SimpleNumRefNoDateModelDesc=Renvoie le numéro de référence au format %s-nnnn ShowProfIdInAddress=Afficher l'identifiant professionnel dans les adresses ShowVATIntaInAddress=Masquer le numéro de TVA intracommunautaire TranslationUncomplete=Traduction partielle -MAIN_DISABLE_METEO=Désactiver la vue météo +MAIN_DISABLE_METEO=Désactiver la vignette météo MeteoStdMod=Mode standard MeteoStdModEnabled=Mode standard activé MeteoPercentageMod=Mode pourcentage @@ -1341,6 +1349,7 @@ BrowserIsKO=Vous utilisez le navigateur %s. Ce navigateur est déconseillé pour PHPModuleLoaded=Le composant PHP %s est chargé PreloadOPCode=Le code OP préchargé est utilisé AddRefInList=Afficher les références client/fournisseur dans les listes (listes déroulantes ou à autocomplétion) et les libellés des liens clicables.
    Les tiers apparaîtront alors sous la forme "CC12345 - SC45678 - La big company coorp", au lieu de "La big company coorp". +AddVatInList=Display Customer/Vendor VAT number. info list (select list or combobox). AddAdressInList=Affiche les informations sur l’adresse du client/fournisseur (liste de sélection ou liste déroulante)
    Les tiers apparaîtront avec le format de nom suivant: "The Big Company corp. - 21, rue du saut 123456 Big town - USA" au lieu de "The Big Company corp". AddEmailPhoneTownInContactList=Afficher l'adresse e-mail du contact (ou les téléphones si non définis) et la ville
    Les contacts apparaîtront avec un nom au format "Dupond Durand - dupond.durand@email.com - Paris" ou "Dupond Durand - 06 07 59 65 66 - Paris" au lieu de "Dupond Durand". AskForPreferredShippingMethod=Demander la méthode d'expédition préférée pour les Tiers @@ -1372,7 +1381,7 @@ AccountCodeManager=Options pour la génération automatique de codes comptable c NotificationsDesc=Les notifications activent l'envoi d'e-mails automatiques pour certains événements de Dolibarr. L'envoi de ces e-mails automatiques peut-être défini : NotificationsDescUser=* par utilisateur, pour chaque utilisateur NotificationsDescContact=* par contacts de tiers (clients ou fournisseur), pour chaque contact -NotificationsDescGlobal=* ou en définissant des emails cibles fixes sur la page de configuration du module. +NotificationsDescGlobal=* ou en définissant des adresses e-mail globales dans la page de configuration du module. ModelModules=Modèle de documents DocumentModelOdt=Génération depuis des modèles OpenDocument (Fichier .ODT ou .ODS LibreOffice, KOffice, TextEdit…) WatermarkOnDraft=Filigrane sur les documents brouillons @@ -1472,10 +1481,10 @@ LDAPSynchronizeMembersTypes=Types d'adhérents de l'annuaire LDAP de l'associati LDAPPrimaryServer=Serveur primaire LDAPSecondaryServer=Serveur secondaire LDAPServerPort=Port du serveur -LDAPServerPortExample=Port par défaut : 389 +LDAPServerPortExample=Standard or StartTLS: 389, LDAPs: 636 LDAPServerProtocolVersion=Version du protocole LDAPServerUseTLS=Utiliser TLS -LDAPServerUseTLSExample=Votre serveur utilise le TLS +LDAPServerUseTLSExample=Your LDAP server use StartTLS LDAPServerDn=DN du serveur LDAPAdminDn=DN de l'administrateur LDAPAdminDnExample=Direction complète (exemple : cn = admin, dc = exemple, dc = com ou cn = Adminitrateur, cn = utilisateurs, dc = exemple, dc = com pour active directory) @@ -1625,8 +1634,7 @@ ProductSetup=Configuration du module Produits ServiceSetup=Configuration du module Services ProductServiceSetup=Configuration des modules Produits et Services NumberOfProductShowInSelect=Nombre maximum de produits dans les listes déroulantes (0=aucune limite) -ViewProductDescInFormAbility=Afficher les descriptions de produits dans les formulaires (sinon, comme info-bulle contextuelle) -DoNotAddProductDescAtAddLines=Ne pas ajouter la description du produit (saisie sur sa fiche) à l'ajout d'un produit +ViewProductDescInFormAbility=Display product descriptions in lines of items (otherwise show description in a tooltip popup) OnProductSelectAddProductDesc=Comment utiliser la description des produits lors de l'ajout d'un produit en tant que ligne d'un document AutoFillFormFieldBeforeSubmit=Remplir automatiquement le champ description avec la description du produit DoNotAutofillButAutoConcat=Ne pas remplir automatiquement le champ de saisie avec la description du produit. La description du produit sera concaténée automatiquement avec la description saisie. @@ -1705,8 +1713,10 @@ FreeLegalTextOnDeliveryReceipts=Mention complémentaire sur les bons de récepti ##### FCKeditor ##### AdvancedEditor=Editeur avancé ActivateFCKeditor=Activer l'éditeur avancé pour : -FCKeditorForCompany=Création/édition WYSIWIG de la description et note des éléments (autre que produits/services) -FCKeditorForProduct=Création/édition WYSIWIG de la description et note des produits/services +FCKeditorForNotePublic=WYSIWIG creation/edition of the field public notes of elements +FCKeditorForNotePrivate=WYSIWIG creation/edition of the field private notes of elements +FCKeditorForCompany=WYSIWIG creation/edition of the field description of elements (except products/services) +FCKeditorForProduct=WYSIWIG creation/edition of the field description of products/services FCKeditorForProductDetails=Création/édition WYSIWYG des lignes de détails produits sur tous les éléments (commandes, propales, factures, etc...). Attention: L'utilisation pour ce cas est fortement déconseillée car peut créer des problèmes dans la gestion de caractères et mise en page des fichiers PDF générés. FCKeditorForMailing= Création/édition WYSIWIG des emailings (Outils->Emailings) FCKeditorForUserSignature=Création/édition WYSIWIG de la signature des utilisateurs @@ -1785,7 +1795,7 @@ ClickToDialSetup=Configuration du module Click To Dial ClickToDialUrlDesc=URL appelée quand un clic sur l'icône téléphone est fait. Dans l'URL, vous pouvez utiliser les tags
    __PHONETO__ qui sera remplacée par le numéro de téléphone de la personne à appeler
    __PHONEFROM__ qui sera remplacée par le numéro de l'appelant (vous)
    __LOGIN__ qui sera remplacée par l'identifiant d'accès de l'utilisateur à l'application d'appel (à définir sur la fiche utilisateur) et
    __PASS__ qui sera remplacée par le mot de passe d'accès de l'utilisateur à l'application d'appel (également à définir sur la fiche utilisateur). ClickToDialDesc=Ce module permet de rendre les numéros de téléphone cliquables lorsque vous utilisez l'application sur un ordinateur de bureau. Un clic sur cette icône composera le numéro de téléphone. Cela peut être utilisé pour commencer une conversation avec un soft phone sur votre bureau ou lorsque vous utilisez un système basé sur le protocole SIP par exemple. Note: Sur un smartphone, les numéros de téléphones sont toujours clicables. ClickToDialUseTelLink=Utiliser un lien "tel:" sur les numéros de téléphone -ClickToDialUseTelLinkDesc=Use this method if your users have a softphone or a software interface, installed on the same computer as the browser, and called when you click on a link starting with "tel:" in your browser. If you need a link that start with "sip:" or a full server solution (no need of local software installation), you must set this to "No" and fill the next field. +ClickToDialUseTelLinkDesc=Utilisez cette méthode si vos utilisateurs disposent d'un softphone ou d'une interface logicielle, installés sur le même ordinateur que le navigateur, et appelés lorsque vous cliquez sur un lien commençant par "tel:" dans votre navigateur. Si vous avez besoin d'un lien commençant par "sip:" ou d'une solution via un serveur (pas besoin d'installation de logiciel local), vous devez définir ce champ sur "Non" et remplir le champ suivant. ##### Point Of Sale (CashDesk) ##### CashDesk=Point de Vente CashDeskSetup=Configuration du module Point de vente/caisse enregistreuse @@ -1919,7 +1929,7 @@ SellTaxRate=Taux de TVA RecuperableOnly=Oui pour une TVA "Non Perçue mais Récupérable" dédiée à certains pays comme la France. Gardez la valeur à "Non" dans tous les autres cas. UrlTrackingDesc=Si le fournisseur ou le service de transport offrent une page ou un site Web pour vérifier l'état de l'expédition, vous pouvez l'entrer ici. Vous pouvez utiliser la clé {TRACKID} dans les paramètres d'URL afin que le système la remplace par la valeur du numéro de suivi entré sur la fiche d'expédition. OpportunityPercent=Lorsque vous créez une opportunité, vous pouvez ďéfinir un montant estimatif de projet/affaire. Selon le statut de l'opportunité, ce montant peut être multiplié par ce taux pour évaluer le montant probable que vos opportunités sont susceptibles de générer. La valeur est un pourcentage (entre 0 et 100). -TemplateForElement=Cet enregistrement modèle est dédié à quel élément +TemplateForElement=This mail template is related to what type of object? An email template is available only when using the "Send Email" button from the related object. TypeOfTemplate=Type de modèle TemplateIsVisibleByOwnerOnly=Le modèle est visible par le propriétaire seulement VisibleEverywhere=Visible partout @@ -1995,8 +2005,12 @@ MAIN_PDF_MARGIN_TOP=Marge haute sur les PDF MAIN_PDF_MARGIN_BOTTOM=Marge bas sur les PDF MAIN_DOCUMENTS_LOGO_HEIGHT=Hauteur du logo sur les PDFs MAIN_GENERATE_PROPOSALS_WITH_PICTURE=Ajouter une image à la ligne de proposition -PROPOSAL_PDF_HIDE_PAYMENTTERM=Hide payments conditions -PROPOSAL_PDF_HIDE_PAYMENTMODE=Hide payment mode +MAIN_PDF_NO_SENDER_FRAME=Masquer les bordures dans le cadre de l'adresse de l'expéditeur +MAIN_PDF_NO_RECIPENT_FRAME=Masquer les bordures dans le cadre de l'adresse du destinataire +MAIN_PDF_HIDE_CUSTOMER_CODE=Masquer le code client +MAIN_PDF_HIDE_SENDER_NAME=Masquer l'expéditeur/le nom de l'entreprise dans le bloc d'adresse +PROPOSAL_PDF_HIDE_PAYMENTTERM=Masquer les conditions de paiement +PROPOSAL_PDF_HIDE_PAYMENTMODE=Masquer le mode de paiement MAIN_PDF_PROPAL_USE_ELECTRONIC_SIGNING=Ajouter une signature électronique au PDF NothingToSetup=Aucune configuration particulière n'est requise pour ce module. SetToYesIfGroupIsComputationOfOtherGroups=Réglez ceci sur Oui si ce groupe est un calcul d'autres groupes @@ -2136,7 +2150,7 @@ AskThisIDToYourBank=Contacter votre établissement bancaire pour obtenir ce code AdvancedModeOnly=Autorisation disponible en mode Autorisations avancées uniquement ConfFileIsReadableOrWritableByAnyUsers=Le fichier conf est lisible ou inscriptible par tous les utilisateurs. Donnez l'autorisation à l'utilisateur et au groupe du serveur Web uniquement. MailToSendEventOrganization=Organisation d'événements -MailToPartnership=Partnership +MailToPartnership=Partenariat AGENDA_EVENT_DEFAULT_STATUS=État de l’événement par défaut lors de la création d’un événement à partir du formulaire YouShouldDisablePHPFunctions=Vous devriez désactiver les fonctions PHP IfCLINotRequiredYouShouldDisablePHPFunctions=Sauf si vous avez besoin de lancer des commandes système, vous devriez désactiver les fonctions PHP @@ -2145,7 +2159,7 @@ NoWritableFilesFoundIntoRootDir=Aucun fichier ou répertoire des programmes cour RecommendedValueIs=Recommandé : %s Recommended=Recommandé NotRecommended=Non recommandé -ARestrictedPath=Un chemin restreint +ARestrictedPath=Some restricted path CheckForModuleUpdate=Vérifier les mises à jour des modules externes CheckForModuleUpdateHelp=Cette action se connecte aux éditeurs des modules externes pour vérifier si une nouvelle version est disponible. ModuleUpdateAvailable=Une mise à jour est disponible @@ -2157,5 +2171,27 @@ DatabasePasswordObfuscated=Le mot de passe de la base de données est masqué da DatabasePasswordNotObfuscated=Le mot de passe de la base de données n'est PAS masqué dans le fichier de configuration APIsAreNotEnabled=Les modules API ne sont pas activés YouShouldSetThisToOff=Vous devriez mettre ceci à 0 ou off -InstallAndUpgradeLockedBy=Install and upgrades are locked by the file %s -OldImplementation=Old implementation +InstallAndUpgradeLockedBy=L'installation et les mises à jour sont verrouillées par le fichier %s +OldImplementation=Ancienne implémentation +PDF_SHOW_LINK_TO_ONLINE_PAYMENT=Si certains modules de paiement en ligne sont activés (Paypal, Stripe, ...), ajouter un lien sur le PDF pour effectuer le paiement en ligne +DashboardDisableGlobal=Disable globally all the thumbs of open objects +BoxstatsDisableGlobal=Disable totally box statistics +DashboardDisableBlocks=Thumbs of open objects (to process or late) on main dashboard +DashboardDisableBlockAgenda=Disable the thumb for agenda +DashboardDisableBlockProject=Disable the thumb for projects +DashboardDisableBlockCustomer=Disable the thumb for customers +DashboardDisableBlockSupplier=Disable the thumb for suppliers +DashboardDisableBlockContract=Disable the thumb for contracts +DashboardDisableBlockTicket=Disable the thumb for tickets +DashboardDisableBlockBank=Disable the thumb for banks +DashboardDisableBlockAdherent=Disable the thumb for memberships +DashboardDisableBlockExpenseReport=Disable the thumb for expense reports +DashboardDisableBlockHoliday=Disable the thumb for leaves +EnabledCondition=Condition to have field enabled (if not enabled, visibility will always be off) +IfYouUseASecondTaxYouMustSetYouUseTheMainTax=If you want to use a second tax, you must enable also the first sale tax +IfYouUseAThirdTaxYouMustSetYouUseTheMainTax=If you want to use a third tax, you must enable also the first sale tax +LanguageAndPresentation=Language and presentation +SkinAndColors=Skin and colors +IfYouUseASecondTaxYouMustSetYouUseTheMainTax=If you want to use a second tax, you must enable also the first sale tax +IfYouUseAThirdTaxYouMustSetYouUseTheMainTax=If you want to use a third tax, you must enable also the first sale tax +PDF_USE_1A=Generate PDF with PDF/A-1b format diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 33faad30cdf..496059137fe 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -64,6 +64,7 @@ ShipmentClassifyClosedInDolibarr=Expédition %s classée payée ShipmentUnClassifyCloseddInDolibarr=Expédition %s réouverte ShipmentBackToDraftInDolibarr=Expédition %s remise au statut brouillon ShipmentDeletedInDolibarr=Expédition %s supprimée +ShipmentCanceledInDolibarr=Shipment %s canceled ReceptionValidatedInDolibarr=Réception %s validée OrderCreatedInDolibarr=Commande %s créée OrderValidatedInDolibarr=Commande %s validée @@ -170,4 +171,4 @@ ReminderType=Type de rappel AddReminder=Créer une notification de rappel automatique pour cet événement ErrorReminderActionCommCreation=Erreur lors de la création de la notification de rappel pour cet événement BrowserPush=Notification par Popup navigateur -ActiveByDefault=Activation par défaut +ActiveByDefault=Activé par défaut diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang index 1a825e09792..f8735a8e417 100644 --- a/htdocs/langs/fr_FR/bills.lang +++ b/htdocs/langs/fr_FR/bills.lang @@ -60,7 +60,7 @@ SupplierBill=Facture fournisseur SupplierBills=Factures fournisseur Payment=Règlement PaymentBack=Remboursement -CustomerInvoicePaymentBack=Rembourser +CustomerInvoicePaymentBack=Remboursement Payments=Règlements PaymentsBack=Remboursements paymentInInvoiceCurrency=Dans la devise des factures @@ -234,12 +234,17 @@ AlreadyPaidBack=Déjà remboursé AlreadyPaidNoCreditNotesNoDeposits=Déjà réglé (hors avoirs et acomptes) Abandoned=Abandonné RemainderToPay=Reste à payer +RemainderToPayMulticurrency=Reste impayé, devise d'origine RemainderToTake=Montant restant à percevoir +RemainderToTakeMulticurrency=Montant restant à encaisser, devise d'origine RemainderToPayBack=Montant restant à rembourser +RemainderToPayBackMulticurrency=Montant restant à rembourser, devise d'origine Rest=Créance AmountExpected=Montant réclamé ExcessReceived=Trop perçu +ExcessReceivedMulticurrency=Excédent reçu, devise d'origine ExcessPaid=Excédent payé +ExcessPaidMulticurrency=Excédent payé, devise d'origine EscompteOffered=Escompte (règl. avt échéance) EscompteOfferedShort=Escompte SendBillRef=Envoi de la facture %s @@ -260,6 +265,7 @@ DateInvoice=Date facturation DatePointOfTax=Date elligibilitée taxe NoInvoice=Aucune facture NoOpenInvoice=Pas de facture ouverte +NbOfOpenInvoices=Number of open invoices ClassifyBill=Classer la facture SupplierBillsToPay=Factures fournisseurs impayées CustomerBillsUnpaid=Factures clients impayées @@ -570,7 +576,7 @@ ToCreateARecurringInvoiceGene=Pour générer de futures factures régulièrement ToCreateARecurringInvoiceGeneAuto=Si vous avez besoin que de telles factures soient générées automatiquement, demandez à votre administrateur d'activer et configurer le module %s. Notez que les deux méthodes de générations de factures (manuelles et automatiques) peuvent être utilisées en cohabitation sans risque de création de doublon. DeleteRepeatableInvoice=Supprimer facture modèle ConfirmDeleteRepeatableInvoice=Est-ce votre sûr de vouloir supprimer la facture modèle ? -CreateOneBillByThird=Créer une facture par tiers (sinon, une facture par commande) +CreateOneBillByThird=Créer une facture par tiers (sinon, une facture par objet sélectionné) BillCreated=%s facture(s) générée(s) BillXCreated=Facture %s générée StatusOfGeneratedDocuments=Statut de génération du document @@ -591,3 +597,5 @@ SituationTotalRayToRest=Reste à payer HT PDFSituationTitle=Situation n°%d SituationTotalProgress=Avancement total %d %% SearchUnpaidInvoicesWithDueDate=Rechercher les factures impayées avec date d'échéance = %s +NoPaymentAvailable=Aucun paiement disponible pour %s +PaymentRegisteredAndInvoiceSetToPaid=Paiement enregistré et facture %s passée à payée diff --git a/htdocs/langs/fr_FR/cashdesk.lang b/htdocs/langs/fr_FR/cashdesk.lang index 1a2381584ed..254d9c766cf 100644 --- a/htdocs/langs/fr_FR/cashdesk.lang +++ b/htdocs/langs/fr_FR/cashdesk.lang @@ -42,7 +42,7 @@ AddTable=Ajouter une table Place=Emplacement TakeposConnectorNecesary='Connecteur TakePOS' requis OrderPrinters=Ajoute un bouton qui permet d'envoyer une commande sans paiement sur certaines imprimantes spécifiques (par exemple pour envoyer une commande en cuisine) -NotAvailableWithBrowserPrinter=Non disponible lorsque l'imprimante pour reçu est définie sur navigateur: +NotAvailableWithBrowserPrinter=Non disponible lorsque l'imprimante pour reçu est définie sur navigateur SearchProduct=Rechercher un produit Receipt=Reçu Header=Entête @@ -128,4 +128,8 @@ PrintPaymentMethodOnReceipts=Imprimer le mode de paiement sur les tickets | reç WeighingScale=échelle de poids ShowPriceHT = Afficher la colonne du prix HT (à l'écran) ShowPriceHTOnReceipt = Afficher la colonne avec le prix hors taxes (sur le ticket de caisse) -CustomerDisplay=Customer display +CustomerDisplay=Affichage client +SplitSale=Fractionner la vente +PrintWithoutDetailsButton=Add "Print without details" button +PrintWithoutDetailsLabelDefault=Line label by default on printing without details +PrintWithoutDetails=Print without details diff --git a/htdocs/langs/fr_FR/categories.lang b/htdocs/langs/fr_FR/categories.lang index 20bfb122c75..3789fd970a1 100644 --- a/htdocs/langs/fr_FR/categories.lang +++ b/htdocs/langs/fr_FR/categories.lang @@ -17,7 +17,6 @@ ContactsCategoriesArea=Espace tags/catégories de contacts AccountsCategoriesArea=Espace des tags/categories de comptes bancaires ProjectsCategoriesArea=Espace des tags/catégories des projets UsersCategoriesArea=Espace des tags/catégories des utilisateurs -TicketsCategoriesArea=Espace tags/catégories des tickets SubCats=Sous-catégories CatList=Liste des tags/catégories CatListAll=Liste de toutes les catégories (de tous types) @@ -90,12 +89,18 @@ CategorieRecursiv=Lier automatiquement avec le(a) tag/catégorie parent(e) CategorieRecursivHelp=Si l'option est activé, quand un produit est ajouté dans une sous-catégorie, le produit sera ajouté aussi dans la catégorie parente. AddProductServiceIntoCategory=Ajouter le produit/service suivant AddCustomerIntoCategory=Assigner cette catégorie au client -AddSupplierIntoCategory=Assigner cette catégorie au fournisseur +AddMemberIntoCategory=Assigner cette catégorie au membre +AddContactIntoCategory=Assigner cette catégorie au contact +AddUserIntoCategory=Assigner cette catégorie à l'utilisateur +AddProjectIntoCategory=Assigner cette catégorie au projet +AddAccountIntoCategory=Assigner cette catégorie au compte AddTicketIntoCategory=Assigner cette catégorie au ticket +AddSupplierIntoCategory=Assigner cette catégorie au fournisseur ShowCategory=Afficher tag/catégorie ByDefaultInList=Par défaut dans la liste ChooseCategory=Choisissez une catégorie StocksCategoriesArea=Catégories d’entrepôt ActionCommCategoriesArea=Catégories d’événements WebsitePagesCategoriesArea=Catégories des pages-conteneurs +KnowledgemanagementsCategoriesArea=KM article Categories UseOrOperatorForCategories=Utiliser l'opérateur 'ou' pour les catégories diff --git a/htdocs/langs/fr_FR/compta.lang b/htdocs/langs/fr_FR/compta.lang index 4628673fd9e..280069f5cf9 100644 --- a/htdocs/langs/fr_FR/compta.lang +++ b/htdocs/langs/fr_FR/compta.lang @@ -142,7 +142,7 @@ PayVAT=Payer une déclaration de TVA PaySalary=Payer un salaire ConfirmPaySocialContribution=Voulez-vous vraiment classer cette taxe sociale ou fiscale comme payée? ConfirmPayVAT=Voulez-vous vraiment classer cette déclaration de TVA comme payée ? -ConfirmPaySalary=Voulez-vous vraiment classer ce salaire comme payée ? +ConfirmPaySalary=Voulez-vous vraiment classer ce salaire comme payé ? DeleteSocialContribution=Effacer une charge fiscale ou sociale DeleteVAT=Supprimer une déclaration de TVA DeleteSalary=Supprimer un salaire @@ -191,9 +191,9 @@ LT2ReportByCustomersES=Rapport par client des IRPF VATReport=Rapport TVA VATReportByPeriods=Rapport de TVA par période VATReportByMonth=Rapport de TVA par mois -VATReportByRates=Rapport TVA par taux -VATReportByThirdParties=Rapport TVA par Tiers -VATReportByCustomers=Rapport par client +VATReportByRates=Rapport de TVA par taux +VATReportByThirdParties=Rapport de TVA par tiers +VATReportByCustomers=Rapport de TVA par client VATReportByCustomersInInputOutputMode=Rapport par client des TVA collectées et payées VATReportByQuartersInInputOutputMode=Rapport par taux des TVA collectées et payées VATReportShowByRateDetails=Afficher les détails de ce taux @@ -204,9 +204,9 @@ LT2ReportByQuartersES=Rapport par taux de IRPF SeeVATReportInInputOutputMode=Cliquer sur %sTVA encaissement%s pour mode de calcul standard SeeVATReportInDueDebtMode=Cliquer sur %sTVA sur débit%s pour mode de calcul avec option sur les débits RulesVATInServices=- Pour les services, le rapport inclut les TVA des règlements effectivement reçus ou émis en se basant sur la date du règlement. -RulesVATInProducts=- Pour les biens matériels, il inclut les TVA des factures en se basant sur la date de facture. +RulesVATInProducts=- Pour les biens matériels, il inclut les TVA des règlements effectivement reçus ou émis en se basant sur la date du règlement. RulesVATDueServices=- Pour les services, le rapport inclut les TVA des factures dues, payées ou non en se basant sur la date de facture. -RulesVATDueProducts=- Pour les biens matériels, il inclut les TVA des factures en se basant sur la date de facture. +RulesVATDueProducts=- Pour les biens matériels, il inclut les TVA des factures dues, payées ou non en se basant sur la date de facture. OptionVatInfoModuleComptabilite=Remarque : Pour les biens matériels, il faudrait utiliser la date de livraison pour être plus juste. ThisIsAnEstimatedValue=Il s'agit d'un aperçu, basé sur les événements métiers et non sur la table du grand livre final, de sorte que les résultats finaux peuvent différer de ces valeurs d'aperçu. PercentOfInvoice=%%/facture @@ -286,9 +286,12 @@ ReportPurchaseTurnover=Chiffre d'affaires d'achat facturé ReportPurchaseTurnoverCollected=Chiffre d'affaires d'achat encaissé IncludeVarpaysInResults = Inclure les paiements divers dans les rapports IncludeLoansInResults = Inclure les prêts dans les rapports -InvoiceLate30Days = Factures en retard > 30 jours -InvoiceLate15Days = Factures en retard > 15 jours -InvoiceLateMinus15Days = Factures en retard -InvoiceNotLate = A recevoir < 15 jours -InvoiceNotLate15Days = A recevoir dans 15 jours -InvoiceNotLate30Days = A recevoir dans 30 jours +InvoiceLate30Days = Factures en retard (plus de 30 jours) +InvoiceLate15Days = Factures en retard (entre 15 et 30 jours) +InvoiceLateMinus15Days = Factures en retard (de moins de 15 jours) +InvoiceNotLate = A recevoir (d'ici 15 jours) +InvoiceNotLate15Days = A recevoir (dans 15 à 30 jours) +InvoiceNotLate30Days = A recevoir (dans plus de 30 jours) +InvoiceToPay=A payer (dans moins de 15 jours) +InvoiceToPay15Days=A payer (d'ici 15 à 30 jours) +InvoiceToPay30Days=A payer (dans plus de 30 jours) diff --git a/htdocs/langs/fr_FR/ecm.lang b/htdocs/langs/fr_FR/ecm.lang index 605cc97625d..e54f1852bf4 100644 --- a/htdocs/langs/fr_FR/ecm.lang +++ b/htdocs/langs/fr_FR/ecm.lang @@ -45,3 +45,5 @@ GenerateImgWebp=Dupliquer toutes les images avec une autre version au format .we ConfirmGenerateImgWebp=Si vous confirmez, vous générerez une image au format .webp pour toutes les images actuellement dans ce dossier (les sous-dossiers ne sont pas inclus)... ConfirmImgWebpCreation=Confirmer la duplication de toutes les images SucessConvertImgWebp=Images dupliquées avec succès +ECMDirName=Dir name +ECMParentDirectory=Parent directory diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index d7955df97e6..ec95b85ed9d 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -83,7 +83,7 @@ ErrorCantSaveADoneUserWithZeroPercentage=Impossible de sauver une action à l'é ErrorRefAlreadyExists=Le référence %s existe déjà. ErrorPleaseTypeBankTransactionReportName=Choisissez le nom du relevé bancaire sur lequel la ligne est rapportées (Format AAAAMM ou AAAAMMJJ) ErrorRecordHasChildren=Impossible de supprimer l'enregistrement car il possède des enregistrements fils. -ErrorRecordHasAtLeastOneChildOfType=L'objet a au moins un enfant de type %s +ErrorRecordHasAtLeastOneChildOfType=Object %s has at least one child of type %s ErrorRecordIsUsedCantDelete=Ne peut effacer l'enregistrement. Ce dernier est déjà utilisé ou inclut dans un autre élément. ErrorModuleRequireJavascript=Le javascript ne doit pas être désactivé pour que cette fonctionnalité soit utilisable. Pour activer/désactiver l'utilisation de javascript, allez dans le menu Accueil->Configuration->Affichage. ErrorPasswordsMustMatch=Les 2 mots de passe saisis doivent correspondre @@ -265,6 +265,12 @@ ErrorAPercentIsRequired=Erreur, le pourcentage doit être indiqué correctement. ErrorYouMustFirstSetupYourChartOfAccount=Vous devez d’abord configurer votre plan comptable. ErrorFailedToFindEmailTemplate=Aucun gabarit trouvé avec le code %s ErrorDurationForServiceNotDefinedCantCalculateHourlyPrice=Durée non définie sur le service. Pas moyen de calculer le prix horaire. +ErrorActionCommPropertyUserowneridNotDefined=Le propriétaire de l'utilisateur est requis +ErrorActionCommBadType=Le type d'événement sélectionné (id: %n, code: %s) n'existe pas dans le dictionnaire des types d'événement +CheckVersionFail=Échec de la vérification de version +ErrorWrongFileName=Le nom du fichier ne peut pas contenir __SOMETHING__ +ErrorNotInDictionaryPaymentConditions=Pas dans le dictionnaire des conditions de paiement, veuillez modifier. +ErrorIsNotADraft=%s is not a draft # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Votre paramètre PHP upload_max_filesize (%s) est supérieur au paramètre PHP post_max_size (%s). Ceci n'est pas une configuration cohérente. @@ -298,8 +304,24 @@ WarningTheHiddenOptionIsOn=Attention, l'option cachée %s est activée WarningCreateSubAccounts=Attention, vous ne pouvez pas créer directement un compte auxiliaire, vous devez créer un tiers ou un utilisateur et leur attribuer un code comptable pour les retrouver dans cette liste WarningAvailableOnlyForHTTPSServers=Disponible uniquement si une connexion sécurisée HTTPS est utilisée WarningModuleXDisabledSoYouMayMissEventHere=Le module %s n’a pas été activé. Par conséquent, il se peut que vous manquiez beaucoup d’événements ici. -ErrorActionCommPropertyUserowneridNotDefined=Le propriétaire de l'utilisateur est requis -ErrorActionCommBadType=Le type d'événement sélectionné (id: %n, code: %s) n'existe pas dans le dictionnaire des types d'événement -CheckVersionFail=Échec de la vérification de version -ErrorWrongFileName=Le nom du fichier ne peut pas contenir __SOMETHING__ -ErrorNotInDictionaryPaymentConditions=Pas dans le dictionnaire des conditions de paiement, veuillez modifier. +WarningPaypalPaymentNotCompatibleWithStrict=La valeur 'Strict' fait que les fonctionnalités de paiement en ligne ne fonctionnent pas correctement. Utilisez plutôt 'Lax'. + +# Validate +RequireValidValue = Valeur non valide +RequireAtLeastXString = Requires at least %s character(s) +RequireXStringMax = Requires %s character(s) max +RequireAtLeastXDigits = Requires at least %s digit(s) +RequireXDigitsMax = Requires %s digit(s) max +RequireValidEmail = L'adresse email n'est pas valide +RequireMaxLength = La longueur doit être inférieure à %s caractères +RequireMinLength = La longueur doit être supérieure à %s caractère(s) +RequireValidUrl = Une URL valide est requise +RequireValidDate = Date valide requise +RequireANotEmptyValue = Est requis +RequireValidDuration = Une durée valide est requise +RequireValidExistingElement = Une valeur existante est requise +RequireValidBool = Un booléen valide est requis +BadSetupOfField = Erreur mauvaise configuration du champ +BadSetupOfFieldClassNotFoundForValidation = Erreur mauvaise configuration du champ : Classe introuvable pour validation +BadSetupOfFieldFileNotFound = Erreur mauvaise configuration du champ : Fichier introuvable pour l'inclusion +BadSetupOfFieldFetchNotCallable = Erreur mauvaise configuration du champ : Fetch non appelable sur la classe diff --git a/htdocs/langs/fr_FR/eventorganization.lang b/htdocs/langs/fr_FR/eventorganization.lang index fa7a9b694df..0efbbf3229e 100644 --- a/htdocs/langs/fr_FR/eventorganization.lang +++ b/htdocs/langs/fr_FR/eventorganization.lang @@ -19,18 +19,22 @@ # ModuleEventOrganizationName = Organisation d'événements EventOrganizationDescription = Organisation de l’événement par le biais du module projet -EventOrganizationDescriptionLong= Gérer l’organisation d'événements pour les conférences, les participants et les conférenciers, avec une page d'inscription publique +EventOrganizationDescriptionLong= Manage the organization of an event (show, conferences, attendees or speakers, with public pages for suggestion, vote or registration) # # Menu # EventOrganizationMenuLeft = Événements organisés EventOrganizationConferenceOrBoothMenuLeft = Conférence ou stand +PaymentEvent=Payment of event + # # Admin page # -EventOrganizationSetup = Configuration de l’organisation de l’événement -Settings = Paramètres +NewRegistration=Registration +EventOrganizationSetup=Configuration de l’organisation de l’événement +EventOrganization=Event organization +Settings=Paramètres EventOrganizationSetupPage = Page de configuration de l’organisation de l’événement EVENTORGANIZATION_TASK_LABEL = Libellé des tâches à créer automatiquement lors de la validation du projet EVENTORGANIZATION_TASK_LABELTooltip = Lorsque vous validez un événement organisé, certaines tâches peuvent être automatiquement créées dans le projet

    Par exemple :
    Envoyer un appel de conférence
    Envoyer un appel pour le stand
    Recevoir un appel de conférences
    Recevoir un appel de stand
    Ouvrir les inscriptions aux événements pour les participants
    Envoyer un rappel de l’événement aux conférenciers
    Envoyer un rappel de l’événement à l’animateur du stand
    Envoyer un rappel de l’événement aux participants @@ -38,8 +42,8 @@ EVENTORGANIZATION_CATEG_THIRDPARTY_CONF = Catégorie à ajouter à des tiers aut EVENTORGANIZATION_CATEG_THIRDPARTY_BOOTH = Catégorie à ajouter à des tiers automatiquement créée lorsque quelqu’un suggère un stand EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_CONF = Modèle de courriel à envoyer après avoir reçu une suggestion de conférence. EVENTORGANIZATION_TEMPLATE_EMAIL_ASK_BOOTH = Modèle de courriel à envoyer après avoir reçu une suggestion d'un stand. -EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_BOOTH = Modèle de courriel à envoyer après paiement d'une inscription à un stand. -EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT = Modèle de courriel à envoyer après paiement d'une inscription à un événement. +EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_BOOTH = Template of email to send after a registration to a booth has been paid. +EVENTORGANIZATION_TEMPLATE_EMAIL_AFT_SUBS_EVENT = Template of email to send after a registration to an event has been paid. EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_SPEAKER = Modèle de courriel pour action de masse aux participants EVENTORGANIZATION_TEMPLATE_EMAIL_BULK_ATTENDES = Modèle de courriel pour action de masse aux intervenants EVENTORGANIZATION_FILTERATTENDEES_CAT = Filtrer la liste de sélection des tiers dans la fiche/le formulaire de création des participants avec/selon la catégorie @@ -49,11 +53,11 @@ EVENTORGANIZATION_FILTERATTENDEES_TYPE = Filtrer la liste de sélection des tier # Object # EventOrganizationConfOrBooth= Conférence ou stand -ManageOrganizeEvent = Gestion d'organisation d'événements +ManageOrganizeEvent = Manage the organization of an event ConferenceOrBooth = Conférence ou stand ConferenceOrBoothTab = Conférence ou stand -AmountOfSubscriptionPaid = Montant de l'inscription payée -DateSubscription = Date de l'inscription +AmountPaid = Amount paid +DateOfRegistration = Date of registration ConferenceOrBoothAttendee = Participant à la conférence ou au stand # @@ -63,25 +67,26 @@ YourOrganizationEventConfRequestWasReceived = Votre demande de conférence a ét YourOrganizationEventBoothRequestWasReceived = Votre demande de stand a été transmise EventOrganizationEmailAskConf = Demande de conférence EventOrganizationEmailAskBooth = Demande de stand -EventOrganizationEmailSubsBooth = Inscription au stand -EventOrganizationEmailSubsEvent = Inscription à un événement +EventOrganizationEmailBoothPayment = Payment of your booth +EventOrganizationEmailRegistrationPayment = Registration for an event EventOrganizationMassEmailAttendees = Communication aux participants EventOrganizationMassEmailSpeakers = Communication aux conférenciers # # Event # -AllowUnknownPeopleSuggestConf=Autoriser des personnes inconnues à suggérer des conférences -AllowUnknownPeopleSuggestConfHelp=Autoriser des personnes inconnues à suggérer des conférences -AllowUnknownPeopleSuggestBooth=Autoriser des personnes inconnues à suggérer un stand -AllowUnknownPeopleSuggestBoothHelp=Autoriser des personnes inconnues à suggérer un stand +AllowUnknownPeopleSuggestConf=Allow people to suggest conferences +AllowUnknownPeopleSuggestConfHelp=Allow unknown people to suggest a conference they want to do +AllowUnknownPeopleSuggestBooth=Allow people to apply for a booth +AllowUnknownPeopleSuggestBoothHelp=Allow unknown people to apply for a booth PriceOfRegistration=Prix de l'inscription -PriceOfRegistrationHelp=Prix de l'inscription +PriceOfRegistrationHelp=Price to pay to register or participate in the event PriceOfBooth=Prix d’inscription pour un stand PriceOfBoothHelp=Prix d’inscription pour un stand EventOrganizationICSLink=Lien ICS des événements ConferenceOrBoothInformation=Renseignements sur la conférence ou le stand -Attendees = Participants +Attendees=Participants +ListOfAttendeesOfEvent=List of attendees of the event project DownloadICSLink = Télécharger le lien ICS EVENTORGANIZATION_SECUREKEY = Clé sécurisée pour le lien d’inscription public à une conférence SERVICE_BOOTH_LOCATION = Service utilisé pour la ligne de facture concernant l'emplacement d'un stand @@ -100,27 +105,41 @@ EvntOrgCancelled = Annulé # Public page # SuggestForm = Page de suggestions -RegisterPage = Page pour conférences ou stands -EvntOrgRegistrationHelpMessage = Ici, vous pouvez voter pour un événement, ou suggérer une nouvelle conférence ou un nouveau stand pour le projet -EvntOrgRegistrationConfHelpMessage = Ici, vous pouvez suggérer une nouvelle conférence pour le projet -EvntOrgRegistrationBoothHelpMessage = Ici, vous pouvez suggérer un nouveau stand pour le projet +SuggestOrVoteForConfOrBooth = Page de suggestion ou de vote +EvntOrgRegistrationHelpMessage = Here, you can vote for a conference or suggest a new one for the event. You can also apply to have a booth during the event. +EvntOrgRegistrationConfHelpMessage = Here, you can suggest a new conference to animate during the event. +EvntOrgRegistrationBoothHelpMessage = Here, you can apply to have a booth during the event. ListOfSuggestedConferences = Liste des conférences suggérées ListOfSuggestedBooths = Liste des stands suggérés +ListOfConferencesOrBooths=List of conferences or booths of event project SuggestConference = Proposer une nouvelle conférence SuggestBooth = Proposer un stand ViewAndVote = Voir et voter pour les événements suggérés -PublicAttendeeSubscriptionPage = Lien d’inscription public à une conférence +PublicAttendeeSubscriptionGlobalPage = Lien public pour l'inscription à l'événement +PublicAttendeeSubscriptionPage = Lien d’inscription public à un événement MissingOrBadSecureKey = La clé de sécurité est invalide ou manquante -EvntOrgWelcomeMessage = Ce formulaire vous permet de vous inscrire en tant que nouveau participant à la conférence : '%s' +EvntOrgWelcomeMessage = This form allows you to register as a new participant to the event : %s EvntOrgDuration = Cette conférence commence le %s et se termine le %s. ConferenceAttendeeFee = Frais de participation à la conférence pour l'événement : '%s' se produisant du %s au %s. BoothLocationFee = Frais de participation à l'événement : '%s' se produisant du %s au %s. EventType = Type événement LabelOfBooth=Libellé du stand LabelOfconference=Libellé de la conférence -ConferenceIsNotConfirmed=Inscription non disponible, la conférence n'est pas encore confirmée -DateMustBeBeforeThan=%s must be before %s -DateMustBeAfterThan=%s must be after %s +ConferenceIsNotConfirmed=Registration not available, conference is not confirmed yet +DateMustBeBeforeThan=%s doit être avant %s +DateMustBeAfterThan=%s doit être après %s + +NewSubscription=Registration +OrganizationEventConfRequestWasReceived=Your suggestion for a conference has been received +OrganizationEventBoothRequestWasReceived=Your request for a booth has been received +OrganizationEventPaymentOfBoothWasReceived=Your payment for your booth has been recorded +OrganizationEventPaymentOfRegistrationWasReceived=Your payment for your event registration has been recorded +OrganizationEventBulkMailToAttendees=This is a remind about your participation in the event as an attendee +OrganizationEventBulkMailToSpeakers=This is a reminder on your participation in the event as a speaker +OrganizationEventLinkToThirdParty=Link to third party (customer, supplier or partner) + +NewSuggestionOfBooth=Application for a booth +NewSuggestionOfConference=Application for a conference # # Vote page @@ -133,17 +152,14 @@ VoteOk = Votre vote a été accepté. AlreadyVoted = Vous avez déjà voté pour cet événement. VoteError = Une erreur s'est produite lors du vote, veuillez réessayer. -# -# SubscriptionOk page -# -SubscriptionOk = Votre inscription à cette conférence a été validée -# -# Subscription validation mail -# -ConfAttendeeSubscriptionConfirmation = Confirmation de votre inscription à une conférence -# -# Payment page -# +SubscriptionOk = Your registration has been validated +ConfAttendeeSubscriptionConfirmation = Confirmation of your subscription to an event Attendee = Participant PaymentConferenceAttendee = Paiement de participation à la conférence PaymentBoothLocation = Paiement de l'emplacement du stand +DeleteConferenceOrBoothAttendee=Remove attendee +RegistrationAndPaymentWereAlreadyRecorder=A registration and a payment were already recorded for the email %s +EmailAttendee=Attendee email +EmailCompanyForInvoice=Company email (for invoice, if different of attendee email) +ErrorSeveralCompaniesWithEmailContactUs=Several companies with this email has been found so we can't validate automaticaly your registration. Please contact us at %s for a manual validation +ErrorSeveralCompaniesWithNameContactUs=Several companies with this name has been found so we can't validate automaticaly your registration. Please contact us at %s for a manual validation diff --git a/htdocs/langs/fr_FR/hrm.lang b/htdocs/langs/fr_FR/hrm.lang index 81fee383b56..647ff720bf9 100644 --- a/htdocs/langs/fr_FR/hrm.lang +++ b/htdocs/langs/fr_FR/hrm.lang @@ -1,4 +1,6 @@ # Dolibarr language file - en_US - hrm + + # Admin HRM_EMAIL_EXTERNAL_SERVICE=Adresse email du service GRH externe à prévenir Establishments=Etablissements @@ -17,3 +19,74 @@ Employees=Salariés Employee=Salarié NewEmployee=Nouveau salarié ListOfEmployees=List des salariés +HrmSetup = Hrm setup +HrmSetupPage = Hrm setup page +HRM_MAXRANK=Maximum rank for a skill +HRM_DEFAULT_SKILL_DESCRIPTION=Default description of ranks when skill is created +HrmAbout = About Hrm +traduction_note=Translate +deplacement=Shift +DateEval=Evaluation date +JobCard=Job card +Job=Travail planifié +Jobs=Jobs +NewSkill=New Skill +SkillType=Skill type +Skilldets=List of ranks for this skill +Skilldet=Skill level +rank=Rank +ErrNoSkillSelected=No skill selected +ErrSkillAlreadyAdded=This skill is already in the list +SkillHasNoLines=This skill has no lines +skill=Skill +Skills=Skills +SkillCard=Skill card +EmployeeSkillsUpdated=Employee skills have been updated (see "Skills" tab of employee card) +Eval=Evaluation +Evals=Evaluations +NewEval=New evaluation +ValidateEvaluation=Validate evaluation +ConfirmValidateEvaluation=Are you sure you want to validate this evaluation with reference %s? +EvaluationCard=Evaluation card +RequiredRank=Required rank for this job +EmployeeRank=Employee rank for this skill +Position=Position +Positions=Positions +PositionCard=Position card +EmployeesInThisPosition=Employees in this position +group1ToCompare=Usergroup to analyze +group2ToCompare=Second usergroup for comparison +OrJobToCompare=Compare to job skills requirements +difference=Difference +CompetenceAcquiredByOneOrMore=Competence acquired by one or more users but not requested by the second comparator +MaxlevelGreaterThan=Max level greater than the one requested +MaxLevelEqualTo=Max level equal to that demand +MaxLevelLowerThan=Max level lower than that demand +MaxlevelGreaterThanShort=Employee level greater than the one requested +MaxLevelEqualToShort=Employee level equals to that demand +MaxLevelLowerThanShort=Employee level lower than that demand +SkillNotAcquired=Skill not acquired by all users and requested by the second comparator +legend=Légende +TypeSkill=Skill type +AddSkill=Add skills to job +RequiredSkills=Required skills for this job +UserRank=User Rank +SkillList=Skill list +SaveRank=Save rank +knowHow=Know how +HowToBe=How to be +knowledge=Knowledge +AbandonmentComment=Abandonment comment +DateLastEval=Date last evaluation +NoEval=No evaluation done for this employee +HowManyUserWithThisMaxNote=Number of users with this rank +HighestRank=Highest rank +SkillComparison=Skill comparison +ReadSkillJobPosition=Read skills / jobs / positions +CreateUpdateSkillJobPosition=Create / update skills / jobs / positions +DeleteSkillJobPosition=Delete skills / jobs / positions +ReadEval=Read evaluations +CreateUpdateEval=Create / update evaluations +ValidateEval=Validate evaluations +DeleteEval=Delete evaluations +SeeComparisonMenu=Access skills comparison menu diff --git a/htdocs/langs/fr_FR/languages.lang b/htdocs/langs/fr_FR/languages.lang index bee596ccf44..46214457660 100644 --- a/htdocs/langs/fr_FR/languages.lang +++ b/htdocs/langs/fr_FR/languages.lang @@ -2,10 +2,11 @@ Language_am_ET=Ethiopien Language_ar_AR=Arabe Language_ar_EG=Arabe (Egypte) -Language_ar_MA=Arabic (Moroco) +Language_ar_MA=Arabe (Maroc) Language_ar_SA=Arabe Language_ar_TN=Arabe (Tunisie) Language_ar_IQ=Arabe (Irak) +Language_as_IN=Assamese Language_az_AZ=Azerbaïdjanais Language_bn_BD=Bengalais Language_bn_IN=Bengali (Inde) @@ -72,6 +73,7 @@ Language_it_IT=Italien Language_it_CH=Italien (Suisse) Language_ja_JP=Japonais Language_ka_GE=Géorgien +Language_kk_KZ=Kazakh Language_km_KH=Khmer Language_kn_IN=Kannada Language_ko_KR=Corée @@ -92,6 +94,7 @@ Language_ro_MD=Roumain (Moldavie) Language_ro_RO=Roumain Language_ru_RU=Russe Language_ru_UA=Russe (Ukraine) +Language_tg_TJ=Tajik Language_tr_TR=Turque Language_sl_SI=Slovène Language_sv_SV=Suédois diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index 9aecafe3f34..da62020916d 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -246,7 +246,7 @@ DefaultModel=Modèle de document par défaut Action=Action About=À propos Number=Nombre -NumberByMonth=Nombre total des signalements par mois +NumberByMonth=Nombre total par mois AmountByMonth=Montant par mois Numero=Numéro Limit=Limite @@ -804,6 +804,7 @@ LinkToSupplierInvoice=Lier à une facture fournisseur LinkToContract=Lier à un contrat LinkToIntervention=Lier à une intervention LinkToTicket=Lien vers le ticket +LinkToMo=Link to Mo CreateDraft=Créer brouillon SetToDraft=Retour en brouillon ClickToEdit=Cliquer ici pour éditer @@ -924,7 +925,7 @@ WebSiteAccounts=Comptes de site web ExpenseReport=Note de frais ExpenseReports=Notes de frais HR=HR -HRAndBank=Salarié +HRAndBank=RH et banque AutomaticallyCalculated=Calculé automatiquement TitleSetToDraft=Retour à l'état de brouillon ConfirmSetToDraft=Etes vous sûr de vouloir revenir à l'état Brouillon ? @@ -1137,17 +1138,23 @@ CopiedToClipboard=Copié dans le presse-papier InformationOnLinkToContract=Ce montant n’est que le total de toutes les lignes du contrat. Aucune notion de temps n’est prise en considération. ConfirmCancel=Êtes-vous sûr de vous annuler EmailMsgID=E-mail MsgID -SetToEnabled=Activer -SetToDisabled=Désactiver -ConfirmMassEnabling=Confirmation d'activation en masse -ConfirmMassEnablingQuestion=Êtes-vous sur de vouloir activer les %s enregistrement(s) sélectionné(s) ? -ConfirmMassDisabling=Confirmation de desactivation en masse -ConfirmMassDisablingQuestion=Êtes-vous sur de vouloir desactiver les %s enregistrement(s) sélectionné(s) ? +SetToEnabled=Définir sur activé +SetToDisabled=Définir sur désactivé +ConfirmMassEnabling=confirmation d'activation en masse +ConfirmMassEnablingQuestion=Êtes-vous sûr de vouloir activer les %s enregistrement(s) sélectionné(s) ? +ConfirmMassDisabling=confirmation de désactivation en masse +ConfirmMassDisablingQuestion=Êtes-vous sûr de vouloir désactiver les %s enregistrement(s) sélectionné(s) ? RecordsEnabled=%s enregistrement(s) activé(s) RecordsDisabled=%s enregistrement(s) désactivé(s) RecordEnabled=Enregistrement activé RecordDisabled=Enregistrement désactivé -ConfirmMassLeaveApprovalQuestion=Êtes-vous sur de vouloir approuver les %s enregistrement(s) sélectionné(s) ? -ConfirmMassLeaveApproval=Confirmation d'approbation de congé en masse +Forthcoming=À venir +Currently=Actuellement +ConfirmMassLeaveApprovalQuestion=Êtes-vous sûr de vouloir approuver le(s) %s enregistrement(s) sélectionné(s) ? +ConfirmMassLeaveApproval=Confirmation de l'approbation en masse des congés RecordAproved=Enregistrement approuvé RecordsApproved=%s enregistrement(s) approuvé(s) +Properties=Properties +hasBeenValidated=%s has been validated +ClientTZ=Fuseau horaire client (utilisateur) +NotClosedYet=Not yet closed diff --git a/htdocs/langs/fr_FR/margins.lang b/htdocs/langs/fr_FR/margins.lang index fabd7851aad..dd1247311ff 100644 --- a/htdocs/langs/fr_FR/margins.lang +++ b/htdocs/langs/fr_FR/margins.lang @@ -22,7 +22,7 @@ ProductService=Produit ou Service AllProducts=Tous les produits et services ChooseProduct/Service=Choisissez le produit ou le service ForceBuyingPriceIfNull=Forcer le prix d'achat au prix de vente si non renseigné -ForceBuyingPriceIfNullDetails=Si le prix d'achat/revient n'est pas défini quand on ajouter une nouvelle ligne, et que cette option est "ON", la marge sera de 0 sur la nouvelle ligne (le prix d'achat/revient = prix de vente). Si l'option est à "OFF" (recommandé), la marge sera égale à la valeur suggérée par défaut (et peut être 100% si aucune valeur par défaut n'est trouvé). +ForceBuyingPriceIfNullDetails=If buying/cost price not provided when we add a new line, and this option is "ON", the margin will be 0%% on the new line (buying/cost price = selling price). If this option is "OFF" (recommended), margin will be equal to the value suggested by default (and may be 100%% if no default value can be found). MARGIN_METHODE_FOR_DISCOUNT=Méthode de gestion des remises globales UseDiscountAsProduct=Comme un produit UseDiscountAsService=Comme un service diff --git a/htdocs/langs/fr_FR/members.lang b/htdocs/langs/fr_FR/members.lang index 88a0aa11246..b848c156383 100644 --- a/htdocs/langs/fr_FR/members.lang +++ b/htdocs/langs/fr_FR/members.lang @@ -7,7 +7,7 @@ Members=Adhérents ShowMember=Afficher fiche adhérent UserNotLinkedToMember=Utilisateur non lié à un adhérent ThirdpartyNotLinkedToMember=Tiers non lié à un adhérent -MembersTickets=Étiquettes d'adhérents +MembersTickets=Étiquettes d'adresses adhérents FundationMembers=Membres de l'association ListOfValidatedPublicMembers=Liste des adhérents publics validés ErrorThisMemberIsNotPublic=Cet adhérent n'est pas public @@ -19,8 +19,8 @@ MembersCards=Carte de visite pour les adhérents MembersList=Liste des adhérents MembersListToValid=Liste des adhérents brouillons (à valider) MembersListValid=Liste des adhérents valides -MembersListUpToDate=Liste des adhérents validés avec une adhésion à jour -MembersListNotUpToDate=Liste des adhérents validés avec une adhésion expirée +MembersListUpToDate=Liste des adhérents validés avec une cotisation à jour +MembersListNotUpToDate=Liste des adhérents validés avec une cotisation expirée MembersListExcluded=Liste des adhérents exclus MembersListResiliated=Liste des adhérents résiliés MembersListQualified=Liste des adhérents qualifiés @@ -32,7 +32,7 @@ MembersWithSubscriptionToReceive=Adhérents avec cotisation à recevoir MembersWithSubscriptionToReceiveShort=Cotisations à recevoir DateSubscription=Date adhésion DateEndSubscription=Date fin adhésion -EndSubscription=La cotisation arrive à échéance +EndSubscription=Fin adhésion SubscriptionId=Id adhésion WithoutSubscription=Sans adhésion MemberId=Id adhérent @@ -45,7 +45,7 @@ MemberStatusDraft=Brouillon (à valider) MemberStatusDraftShort=Brouillon MemberStatusActive=Validé (attente cotisation) MemberStatusActiveShort=Validé -MemberStatusActiveLate=Adhésion/cotisation expirée +MemberStatusActiveLate=Adhésion / cotisation expirée MemberStatusActiveLateShort=Expiré MemberStatusPaid=Adhésions à jour MemberStatusPaidShort=A jour @@ -68,10 +68,10 @@ DeleteAMemberType=Supprimer un type d'adhérent ConfirmDeleteMemberType=Êtes-vous sur de vouloir supprimer ce type d' adhérent ? MemberTypeDeleted=Type d'adhérent supprimé MemberTypeCanNotBeDeleted=Ce type d'adhérent ne peut pas être supprimé -NewSubscription=Nouvelle adhésion +NewSubscription=Nouvelle cotisation NewSubscriptionDesc=Ce formulaire permet de vous inscrire comme nouvel adhérent de l'association. Pour un renouvellement (si vous êtes déjà adhérent), contactez plutôt l'association par email %s. -Subscription=Adhésion/cotisation -Subscriptions=Adhésions/cotisations +Subscription=Adhésion / cotisation +Subscriptions=Adhésions / cotisations SubscriptionLate=En retard SubscriptionNotReceived=Cotisation non reçue ListOfSubscriptions=Liste des cotisations @@ -88,11 +88,12 @@ Moral=Personne morale MorAndPhy=Personnes morales et physiques Reenable=Réactiver ExcludeMember=Exclure un adhérent +Exclude=Exclure ConfirmExcludeMember=Êtes-vous sûr de vouloir exclure cet adhérent ? ResiliateMember=Résilier un adhérent ConfirmResiliateMember=Êtes-vous sûr de vouloir résilier cet adhérent ? DeleteMember=Effacer un membre -ConfirmDeleteMember=Êtes-vous sûr de vouloir effacer ce membre (Effacer un membre efface aussi toutes ses cotisations) ? +ConfirmDeleteMember=Êtes-vous sûr de vouloir supprimer ce membre (Supprimer un membre supprime aussi toutes ses cotisations) ? DeleteSubscription=Effacer une adhésion ConfirmDeleteSubscription=Êtes-vous sûr de vouloir effacer cette adhésion ? Filehtpasswd=Fichier htpasswd @@ -104,7 +105,7 @@ BlankSubscriptionForm=Formulaire d'auto-inscription publique BlankSubscriptionFormDesc=Dolibarr peut vous fournir un URL/site web public afin de permettre aux visiteurs externes de faire une demande d'inscription à la fondation. Si un module de paiement est actif, un formulaire de paiement sera également fourni automatiquement. EnablePublicSubscriptionForm=Activer le formulaire public d'auto-inscription ForceMemberType=Forcer le type d'adhérent -ExportDataset_member_1=Adhérents et adhésions +ExportDataset_member_1=Adhérents et cotisations ImportDataset_member_1=Adhérents LastMembersModified=Les %s derniers adhérents modifiés LastSubscriptionsModified=Les %s dernières adhésions modifiées @@ -139,7 +140,7 @@ ThisIsContentOfSubscriptionReminderEmail=Nous voulons vous informer que votre ad ThisIsContentOfYourCard=Ceci est un rappel des informations que nous avons vous concernant. N'hésitez pas à nous contacter en cas d'erreur.

    DescADHERENT_AUTOREGISTER_NOTIF_MAIL_SUBJECT=Sujet de l'email reçu en cas d'auto-inscription d'un invité DescADHERENT_AUTOREGISTER_NOTIF_MAIL=Email reçu en cas d'auto-inscription d'un invité -DescADHERENT_EMAIL_TEMPLATE_AUTOREGISTER=Modèle Email à utiliser pour envoyer un email à un adhérent sur auto-adhésion de l'adhérent +DescADHERENT_EMAIL_TEMPLATE_AUTOREGISTER=Modèle Email à utiliser pour envoyer un email à un adhérent sur auto-inscription de l'adhérent DescADHERENT_EMAIL_TEMPLATE_MEMBER_VALIDATION=Modèle d'email à utiliser pour envoyer un email à un membre sur la validation d'un membre DescADHERENT_EMAIL_TEMPLATE_SUBSCRIPTION=Modèle d'email électronique à utiliser pour envoyer un courrier électronique à un membre lors de l'enregistrement d'une nouvelle cotisation DescADHERENT_EMAIL_TEMPLATE_REMIND_EXPIRATION=Modèle d'email électronique à utiliser pour envoyer un rappel par courrier électronique lorsque l'adhésion est sur le point d'expirer @@ -156,7 +157,7 @@ DescADHERENT_CARD_FOOTER_TEXT=Texte imprimé sur le bas des cartes d'adhérent ShowTypeCard=Voir type '%s' HTPasswordExport=Génération fichier htpassword NoThirdPartyAssociatedToMember=Pas de tiers associé à cet adhérent -MembersAndSubscriptions= Adhérents et Adhésions +MembersAndSubscriptions=Adhérents et Cotisations MoreActions=Action complémentaire à l'enregistrement MoreActionsOnSubscription=Action complémentaire proposée par défaut à l'enregistrement de l'adhésion MoreActionBankDirect=Création une écriture directe sur le compte bancaire ou caisse @@ -168,7 +169,7 @@ DocForAllMembersCards=Génération de cartes pour tous les adhérents DocForOneMemberCards=Génération de cartes pour un adhérent particulier DocForLabels=Génération d'étiquettes d'adresses SubscriptionPayment=Paiement cotisation -LastSubscriptionDate=Date de dernière adhésion +LastSubscriptionDate=Date de la dernière cotisation LastSubscriptionAmount=Montant dernière adhésion LastMemberType=Dernier type d'adhérent MembersStatisticsByCountries=Statistiques des membres par pays @@ -186,7 +187,7 @@ MembersByRegion=Cet écran vous montre les statistiques sur les adhérents par r MembersStatisticsDesc=Choisissez les statistiques que vous désirez consulter... MenuMembersStats=Statistiques LastMemberDate=Date dernière adhésion -LatestSubscriptionDate=Date de dernière adhésion +LatestSubscriptionDate=Date de dernière cotisation MemberNature=Nature de l'adhérent MembersNature=Nature des adhérents Public=Informations publiques @@ -194,15 +195,15 @@ NewMemberbyWeb=Nouvel adhérent ajouté. En attente de validation NewMemberForm=Nouvel Adhérent form SubscriptionsStatistics=Statistiques sur les cotisations NbOfSubscriptions=Nombre de cotisations -AmountOfSubscriptions=Montant de cotisations +AmountOfSubscriptions=Montant des cotisations TurnoverOrBudget=Chiffre affaire (pour société) ou Budget (asso ou collectivité) DefaultAmount=Montant par défaut de la cotisation -CanEditAmount=Le visiteur peut modifier/choisir le montant de sa cotisation +CanEditAmount=Le visiteur peut modifier / choisir le montant de sa cotisation MEMBER_NEWFORM_PAYONLINE=Rediriger sur la page intégrée de paiement en ligne ByProperties=Par nature MembersStatisticsByProperties=Statistiques des adhérents par nature -VATToUseForSubscriptions=Taux de TVA pour les adhésions -NoVatOnSubscription=Pas de TVA sur les adhésions +VATToUseForSubscriptions=Taux de TVA pour les cotisations +NoVatOnSubscription=Pas de TVA pour les cotisations ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS=Produit/Service utilisé pour la ligne de cotisation dans la facture: %s NameOrCompany=Nom ou société SubscriptionRecorded=Adhésion enregistré @@ -215,3 +216,5 @@ YouMayFindYourInvoiceInThisEmail=Vous pouvez trouver votre facture jointe à cet XMembersClosed=%s adhérent(s) résilié(s) XExternalUserCreated=%s utilisateur(s) externe(s) créé(s) ForceMemberNature=Forcer la nature de l'adhérent (personne physique ou morale) +CreateDolibarrLoginDesc=La création d'un login utilisateur pour les membres leur permet de se connecter à l'application. En fonction des autorisations accordées, ils pourront par exemple consulter ou modifier eux-mêmes leur dossier. +CreateDolibarrThirdPartyDesc=Un tiers est l'entité juridique qui sera utilisée sur la facture si vous décidez de générer une facture pour chaque cotisation. Vous pourrez le créer plus tard au cours du processus d'enregistrement de la cotisation. diff --git a/htdocs/langs/fr_FR/mrp.lang b/htdocs/langs/fr_FR/mrp.lang index cdff650c34b..5a89a594cc3 100644 --- a/htdocs/langs/fr_FR/mrp.lang +++ b/htdocs/langs/fr_FR/mrp.lang @@ -9,6 +9,7 @@ LatestBOMModified=Le %s dernières BOMs modifiées LatestMOModified=Les %s derniers Ordres de Fabrication modifiés Bom=Nomenclatures produits (BOM) BillOfMaterials=Nomenclature BOM +BillOfMaterialsLines=Lignes de nomenclature BOMsSetup=Configuration du module BOM ListOfBOMs=Liste des BOMs ListOfManufacturingOrders=Liste des Ordres de Fabrication @@ -55,6 +56,7 @@ WarehouseForProduction=Entrepôt pour la fabrication CreateMO=Créer OF ToConsume=A consommer ToProduce=Produire +ToObtain=A obtenir QtyAlreadyConsumed=Qté déjà consommée QtyAlreadyProduced=Qté déjà produite QtyRequiredIfNoLoss=Quantité requise s'il n'y a pas de perte (l'efficacité de fabrication est de 100%%) @@ -72,6 +74,7 @@ NoStockChangeOnServices=Aucune variation de stock sur les services ProductQtyToConsumeByMO=Quantité de produit restant à consommer par OF ouvert ProductQtyToProduceByMO=Quantités restant à produire avec les OF ouverts AddNewConsumeLines=Ajouter une nouvelle ligne à consommer +AddNewProduceLines=Ajouter une nouvelle ligne à produire ProductsToConsume=Produits à consommer ProductsToProduce=Produits à produire UnitCost=Coût unitaire @@ -101,3 +104,6 @@ HumanMachine=Humain/machine WorkstationArea=Espace Poste de travail Machines=Machines THMEstimatedHelp=Ce taux permet de définir un coût prévisionnel de l'article +MOAndLines=Ordres de fabrication et lignes +BOM=Nomenclature +CollapseBOMHelp=Vous pouvez définir l'affichage par défaut du détail des nomenclature dans la configuration du module "Nomenclature Produits" diff --git a/htdocs/langs/fr_FR/opensurvey.lang b/htdocs/langs/fr_FR/opensurvey.lang index 35a9031583f..d9538d4c3e5 100644 --- a/htdocs/langs/fr_FR/opensurvey.lang +++ b/htdocs/langs/fr_FR/opensurvey.lang @@ -48,6 +48,8 @@ AddEndHour=Ajouter heure de fin votes=vote(s) NoCommentYet=Pas de commentaires laissés pour le moment sur ce sondage CanComment=Les votants peuvent poster des commentaires +YourVoteIsPrivate=This poll is private, nobody can see your vote. +YourVoteIsPublic=This poll is public, anybody with the link can see your vote. CanSeeOthersVote=Les votants peuvent voir les votes des autres SelectDayDesc=Pour chaque jour, vous pouvez choisir, ou pas, les heures au format suivant :
    - laisser vide,
    - "8h", "8H" ou "8:00" pour définir uniquement une heure de début,
    - "8-11", "8h-11h", "8H-11H" ou "8:00-11:00" pour définir une heure de début et de fin,
    - "8h15-11h15", "8H15-11H15" ou "8:15-11:15" pour définir une heure de début et fin avec précision sur les minutes. BackToCurrentMonth=Retour au mois en cours diff --git a/htdocs/langs/fr_FR/printing.lang b/htdocs/langs/fr_FR/printing.lang index 62cad4af2c5..49ac6d2292d 100644 --- a/htdocs/langs/fr_FR/printing.lang +++ b/htdocs/langs/fr_FR/printing.lang @@ -1,10 +1,10 @@ # Dolibarr language file - Source file is en_US - printing -Module64000Name=Impressions Directe -Module64000Desc=Activer le système d'impression Directe -PrintingSetup=Réglages du module Impression Directe -PrintingDesc=Ce module ajoute un bouton Imprimer afin d'envoyer directement les documents à une imprimante (sans ouvrir le document dans une application). -MenuDirectPrinting=Travaux d'impressions directe -DirectPrint=Impressions Directe +Module64000Name=One click Printing +Module64000Desc=Enable One click Printing System +PrintingSetup=Setup of One click Printing System +PrintingDesc=This module adds a Print button to various modules to allow documents to be printed directly to a printer with no need to open the document into another application. +MenuDirectPrinting=One click Printing jobs +DirectPrint=One click Print PrintingDriverDesc=Paramètres de configuration pour le driver d'impression ListDrivers=Liste des drivers PrintTestDesc=Liste des imprimantes @@ -50,5 +50,5 @@ GoogleAuthNotConfigured=Configuration Google OAuth non terminé. Activer le modu GoogleAuthConfigured=Identifiants Google OAuth trouvé dans la configuration du module OAuth. PrintingDriverDescprintgcp=Paramètres de configuration des drivers Google Cloud Print pour les impressions. PrintingDriverDescprintipp=Variables de configuration pour le pilotes d'impression Cups. -PrintTestDescprintgcp=List des imprimantes Google Cloud Print. +PrintTestDescprintgcp=Liste des imprimantes Google Cloud Print. PrintTestDescprintipp=Liste des imprimantes pour Cups. diff --git a/htdocs/langs/fr_FR/productbatch.lang b/htdocs/langs/fr_FR/productbatch.lang index 193ecb503e1..ccd5e43d3d7 100644 --- a/htdocs/langs/fr_FR/productbatch.lang +++ b/htdocs/langs/fr_FR/productbatch.lang @@ -27,9 +27,9 @@ StockDetailPerBatch=Stock détaillé par lot SerialNumberAlreadyInUse=Le numéro de série %s est déjà utilisé pour le produit %s TooManyQtyForSerialNumber=Vous ne pouvez avoir qu'un seul produit %s pour le numéro de série %s ManageLotMask=Masque personnalisé -CustomMasks=Option to define a different numbering mask for each product -BatchLotNumberingModules=Numbering rule for automatic generation of lot number -BatchSerialNumberingModules=Numbering rule for automatic generation of serial number (for products with property 1 unique lot/serial for each product) +CustomMasks=Option pour définir un masque de numérotation différent pour chaque produit +BatchLotNumberingModules=Règle de numérotation pour la génération automatique de numéro de lot +BatchSerialNumberingModules=Règle de numérotation pour la génération automatique de numéro de série (pour les produits avec propriété 1 lot/série unique pour chaque produit) QtyToAddAfterBarcodeScan=Quantité à ajouter pour chaque code à barres/lot/série scanné LifeTime=Durée de vie (en jours) EndOfLife=Fin d'utilisation @@ -37,7 +37,8 @@ ManufacturingDate=Date de fabrication DestructionDate=Date de destruction FirstUseDate=Date de première mise en service QCFrequency=Fréquence du contrôle qualité (en jours) - +ShowAllLots=Show all lots +HideLots=Hide lots #Traceability - qc status OutOfOrder=Hors d'usage InWorkingOrder=En état de marche diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 013d75d2ec0..be7b4a2726e 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -75,6 +75,7 @@ SellingPriceTTC=Prix de vente TTC SellingMinPriceTTC=Prix de vente min. (TTC) CostPriceDescription=Ce champ de prix (hors taxes) peut être utilisé pour saisir le montant moyen que ce produit coûte à votre société. Il peut s'agir de n'importe quel prix que vous calculez vous-même, par exemple à partir du prix d'achat moyen plus le coût moyen de production et de distribution. CostPriceUsage=Cette valeur peut être utilisée dans le calcul des marges. +ManufacturingPrice=Manufacturing price SoldAmount=Solde PurchasedAmount=Montant des achats NewPrice=Nouveau prix @@ -397,5 +398,13 @@ ActionAvailableOnVariantProductOnly=Action disponible uniquement sur la variante ProductsPricePerCustomer=Prix produit par clients ProductSupplierExtraFields=Attributs supplémentaires (Prix fournisseur) DeleteLinkedProduct=Supprimer le produit enfant lié à la combinaison +AmountUsedToUpdateWAP=Amount to use to update the Weighted Average Price PMPValue=Prix moyen pondéré (PMP) PMPValueShort=PMP +mandatoryperiod=Mandatory periods +mandatoryPeriodNeedTobeSet=Attention periods not entered and mandatory +mandatoryPeriodNeedTobeSetMsgValidate=A service requires a start and end period +mandatoryHelper=Message to the user on the need to enter a start date and an end date on a service when creating / validating an invoice, commercial proposal, sales order.
    This action is not blocking in the process of confirmation +DefaultBOM=Nomenclature par défaut +DefaultBOMDesc=La nomenclature par défaut qu'il est recommandé d'utiliser pour fabriquer ce produit. Ce champ ne peut être défini que si la nature du produit est '%s'. +Rank=Rank diff --git a/htdocs/langs/fr_FR/projects.lang b/htdocs/langs/fr_FR/projects.lang index 9a7f3c189bc..53e1e80a0e8 100644 --- a/htdocs/langs/fr_FR/projects.lang +++ b/htdocs/langs/fr_FR/projects.lang @@ -274,6 +274,7 @@ NewInter=Nouvelle intervention OneLinePerTask=Une ligne par tâche OneLinePerPeriod=Une ligne par période OneLinePerTimeSpentLine=Une ligne pour chaque déclaration de temps passé +AddDetailDateAndDuration=Avec date et durée dans la description de la ligne RefTaskParent=Réf. Tâche parent ProfitIsCalculatedWith=Le bénéfice est calculé sur la base de AddPersonToTask=Ajouter également aux tâches @@ -281,3 +282,4 @@ UsageOrganizeEvent=Utilisation: Organisation d'événements PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE=Classer le projet comme étant clos lorsque toutes ses tâches sont terminées (progression 100%%) PROJECT_CLASSIFY_CLOSED_WHEN_ALL_TASKS_DONE_help=Remarque : les projets existants avec toutes les tâches terminées à 100 %% ne seront pas affectés : vous devrez les fermer manuellement. Cette option n’affecte que les projets ouverts. SelectLinesOfTimeSpentToInvoice=Sélectionnez les lignes de temps consacré non facturées, puis l'action groupée "Générer la facture" pour les facturer +ProjectTasksWithoutTimeSpent=Project tasks without time spent diff --git a/htdocs/langs/fr_FR/propal.lang b/htdocs/langs/fr_FR/propal.lang index b019b275e6e..3728eba94d3 100644 --- a/htdocs/langs/fr_FR/propal.lang +++ b/htdocs/langs/fr_FR/propal.lang @@ -33,7 +33,7 @@ PropalStatusSigned=Signée (à facturer) PropalStatusNotSigned=Non signée (fermée) PropalStatusBilled=Facturée PropalStatusDraftShort=Brouillon -PropalStatusValidatedShort=Validé (ouvert) +PropalStatusValidatedShort=Ouvert PropalStatusClosedShort=Fermée PropalStatusSignedShort=Signée PropalStatusNotSignedShort=Non signée @@ -89,4 +89,11 @@ IdProposal=ID de la proposition commerciale IdProduct=ID produit PrParentLine=Ligne parent de proposition LineBuyPriceHT=Prix d'achat HT de la ligne - +SignPropal=Signer la proposition commerciale +RefusePropal=Refuser la proposition commerciale +Sign=Signer +PropalAlreadyRefused=Proposition commerciale déjà refusée +PropalAlreadySigned=Proposition commerciale déjà signée +PropalSigned=Proposition commerciale signée +PropalRefused=Proposition commerciale refusée +ConfirmRefusePropal=Êtes-vous sûr de vouloir refuser cette proposition commerciale ? diff --git a/htdocs/langs/fr_FR/receptions.lang b/htdocs/langs/fr_FR/receptions.lang index 2becadf52c4..afdb38558ae 100644 --- a/htdocs/langs/fr_FR/receptions.lang +++ b/htdocs/langs/fr_FR/receptions.lang @@ -36,7 +36,7 @@ StatsOnReceptionsOnlyValidated=Statistiques effectuées sur les réceptionss val SendReceptionByEMail=Envoyer la réception par email SendReceptionRef=Envoi du bordereau de réception %s ActionsOnReception=Événements sur la réception -ReceptionCreationIsDoneFromOrder=Pour le moment, la création d'une nouvelle réception se fait depuis la fiche commande. +ReceptionCreationIsDoneFromOrder=Pour le moment, la création d'une nouvelle réception se fait depuis la fiche commande fournisseur. ReceptionLine=Ligne de réception ProductQtyInReceptionAlreadySent=Quantité de produit en commande ouverte déjà expédiée ProductQtyInSuppliersReceptionAlreadyRecevied=Quantité de produit déjà reçu en commandes fournisseur ouvertes @@ -45,3 +45,4 @@ ReceptionsNumberingModules=Module de numérotation pour les réceptions ReceptionsReceiptModel=Modèles de document pour les réceptions NoMorePredefinedProductToDispatch=Plus de produits prédéfinis à expédier ReceptionExist=Une réception existe +ByingPrice=Bying price diff --git a/htdocs/langs/fr_FR/salaries.lang b/htdocs/langs/fr_FR/salaries.lang index cdabb1c9f35..0dcf1a6d869 100644 --- a/htdocs/langs/fr_FR/salaries.lang +++ b/htdocs/langs/fr_FR/salaries.lang @@ -22,3 +22,4 @@ AllSalaries=Tous les salaires SalariesStatistics=Statistiques SalariesAndPayments=Salaires et paiements ConfirmDeleteSalaryPayment=Voulez-vous supprimer ce paiement de salaire ? +FillFieldFirst=Remplisez d'abord le champ salarié diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index 1fc01004248..9244b3db53d 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -14,7 +14,7 @@ DefaultWarehouse=Entrepôt par défaut WarehouseTarget=Entrepôt destination ValidateSending=Valider expédition CancelSending=Annuler expédition -DeleteSending=Supprimer expédition +DeleteSending=Supprimer l'expédition Stock=Stock Stocks=Stocks MissingStocks=Stocks manquants @@ -37,7 +37,7 @@ AllWarehouses=Tous les entrepôts IncludeEmptyDesiredStock=Inclure aussi les stocks négatifs quand le stock désiré optimal n'est pas défini IncludeAlsoDraftOrders=Inclure également les commandes brouillons Location=Lieu -LocationSummary=Nom court du lieu +LocationSummary=Nom court de l'emplacement NumberOfDifferentProducts=Nombre de produits uniques NumberOfProducts=Nombre total de produits LastMovement=Dernier mouvement @@ -62,7 +62,7 @@ AllowAddLimitStockByWarehouse=Gérez également les valeurs des stocks minimums RuleForWarehouse=Règle pour les entrepôts WarehouseAskWarehouseOnThirparty=Définir un entrepôt sur les tiers WarehouseAskWarehouseDuringPropal=Définir un entrepôt sur les propositions commerciales -WarehouseAskWarehouseDuringOrder=Définir un entrepôt sur les commandes +WarehouseAskWarehouseDuringOrder=Définir un entrepôt sur les commandes clients UserDefaultWarehouse=Définir un entrepôt sur les utilisateurs MainDefaultWarehouse=Entrepôt par défaut MainDefaultWarehouseUser=Utiliser un entrepôt par défaut pour chaque utilisateur @@ -75,9 +75,9 @@ OrderDispatch=Réceptions RuleForStockManagementDecrease=Règle de gestion des décrémentations automatiques de stock (la décrémentation manuelle est toujours possible, même si une décrémentation automatique est activée) RuleForStockManagementIncrease=Règle de gestion des incrémentations de stock (l'incrémentation manuelle est toujours possible, même si une incrémentation automatique est activée) DeStockOnBill=Décrémenter les stocks physiques sur validation des factures/avoirs clients -DeStockOnValidateOrder=Décrémenterr les stocks physiques sur validation des commandes clients +DeStockOnValidateOrder=Décrémenter les stocks physiques sur validation des commandes clients DeStockOnShipment=Décrémenter les stocks physiques sur validation des expéditions -DeStockOnShipmentOnClosing=Décrémente les stocks physiques au classement "clôturée" de l'expédition +DeStockOnShipmentOnClosing=Décrémenter les stocks physiques au classement "clôturée" de l'expédition ReStockOnBill=Incrémenter les stocks physiques sur validation des factures/avoirs fournisseurs ReStockOnValidateOrder=Incrémenter les stocks physiques sur approbation des commandes fournisseurs ReStockOnDispatchOrder=Incrémenter les stocks physiques sur ventilation manuelle dans les entrepôts, après réception de la marchandise @@ -256,8 +256,10 @@ AutofillWithExpected=Remplir la quantité réelle avec la quantité prévue ShowAllBatchByDefault=Par défaut, afficher les détails des lots sur l'onglet "stock" du produit CollapseBatchDetailHelp=Vous pouvez définir l'affichage par défaut des détails du lot dans la configuration du module de stocks FieldCannotBeNegative=Le champ "%s" ne peut pas être négatif -ErrorWrongBarcodemode=Unknown Barcode mode -ProductDoesNotExist=Product does not exist -ErrorSameBatchNumber=Same batch number found in inventory list -ProductBatchDoesNotExist=Product with batch/serial does not exist -ProductBarcodeDoesNotExist=Product with barcode does not exist +ErrorWrongBarcodemode=Mode code-barres inconnu +ProductDoesNotExist=Le produit n'existe pas +ErrorSameBatchNumber=Même numéro de lot trouvé dans la liste d'inventaire +ProductBatchDoesNotExist=Le produit avec ce lot/série n'existe pas +ProductBarcodeDoesNotExist=Le produit avec ce code-barres n'existe pas +WarehouseId=ID entrepôt +WarehouseRef=Réf entrepôt diff --git a/htdocs/langs/fr_FR/ticket.lang b/htdocs/langs/fr_FR/ticket.lang index b166e963caf..04dbafe507f 100644 --- a/htdocs/langs/fr_FR/ticket.lang +++ b/htdocs/langs/fr_FR/ticket.lang @@ -45,6 +45,8 @@ TicketSeverityShortNORMAL=Normal TicketSeverityShortHIGH=Élevé TicketSeverityShortBLOCKING=Critique, bloquant +TicketCategoryShortOTHER=Autre + ErrorBadEmailAddress=Champ '%s' incorrect MenuTicketMyAssign=Mes tickets MenuTicketMyAssignNonClosed=Mes tickets ouverts @@ -66,7 +68,7 @@ NeedMoreInformation=Attente retour demandeur NeedMoreInformationShort=En attente de retour Answered=Répondu Waiting=En attente -SolvedClosed=Solved +SolvedClosed=Résolu Deleted=Supprimé # Dict @@ -180,17 +182,17 @@ MessageSuccessfullyAdded=Ticket créé TicketMessageSuccessfullyAdded=Message ajouté avec succès TicketMessagesList=Liste des messages NoMsgForThisTicket=Pas de message pour ce ticket -Properties=Classification +TicketProperties=Classification LatestNewTickets=Les %s derniers tickets (non lus) TicketSeverity=Sévérité ShowTicket=Voir le ticket RelatedTickets=Tickets liés TicketAddIntervention=Créer intervention -CloseTicket=Close|Solve ticket -AbandonTicket=Abandon ticket -CloseATicket=Close|Solve a ticket +CloseTicket=Fermer|Résoudre ticket +AbandonTicket=Abandonner le ticket +CloseATicket=Fermer|Résoudre un ticket ConfirmCloseAticket=Confirmer la fermeture du ticket -ConfirmAbandonTicket=Do you confirm the closing of the ticket to status 'Abandonned' +ConfirmAbandonTicket=Confirmez-vous la fermeture du ticket au statut 'Abandonné' ConfirmDeleteTicket=Confirmez la suppression du ticket TicketDeletedSuccess=Ticket supprimé avec succès TicketMarkedAsClosed=Ticket indiqué fermé @@ -319,3 +321,4 @@ BoxNumberOfTicketByDay=Nombre de nouveaux tickets par jour BoxNewTicketVSClose=Nombre de nouveaux tickets aujourd’hui par rapport aux tickets fermés aujourd’hui TicketCreatedToday=Ticket créé aujourd'hui TicketClosedToday=Ticket fermé aujourd'hui +KMFoundForTicketGroup=We found topics and FAQs that may answers your question, thanks to check them before submitting the ticket diff --git a/htdocs/langs/gl_ES/main.lang b/htdocs/langs/gl_ES/main.lang index a330cb6d7c1..1e13deb814d 100644 --- a/htdocs/langs/gl_ES/main.lang +++ b/htdocs/langs/gl_ES/main.lang @@ -4,7 +4,7 @@ DIRECTION=ltr # msungstdlight or cid0ct are for traditional Chinese (traditional does not render with Ubuntu pdf reader) # stsongstdlight or cid0cs are for simplified Chinese # To read Chinese pdf with Linux: sudo apt-get install poppler-data -FONTFORPDF=helvética +FONTFORPDF=helvetica FONTSIZEFORPDF=10 SeparatorDecimal=, SeparatorThousand=. diff --git a/htdocs/langs/he_IL/mrp.lang b/htdocs/langs/he_IL/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/he_IL/mrp.lang +++ b/htdocs/langs/he_IL/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/hi_IN/mrp.lang b/htdocs/langs/hi_IN/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/hi_IN/mrp.lang +++ b/htdocs/langs/hi_IN/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/hr_HR/mrp.lang b/htdocs/langs/hr_HR/mrp.lang index dd2c40eda6c..00710061f2a 100644 --- a/htdocs/langs/hr_HR/mrp.lang +++ b/htdocs/langs/hr_HR/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Proizvodni nalozi NewMO=Novi proizvodni nalog QtyToProduce=Qty to produce diff --git a/htdocs/langs/hu_HU/mrp.lang b/htdocs/langs/hu_HU/mrp.lang index 350817adedb..0623b3a8447 100644 --- a/htdocs/langs/hu_HU/mrp.lang +++ b/htdocs/langs/hu_HU/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Gyártási rendelések NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/id_ID/mrp.lang b/htdocs/langs/id_ID/mrp.lang index 76290ed5ea9..6f0d5c87b0a 100644 --- a/htdocs/langs/id_ID/mrp.lang +++ b/htdocs/langs/id_ID/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Nilai 0,95 berarti rata-rata 5%% dari kehilan DeleteBillOfMaterials=Hapus Bill Of Material DeleteMo=Hapus Pesanan Pembuatan ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Pesanan Manufaktur NewMO=Pesanan Manufaktur Baru QtyToProduce=Jumlah yang akan diproduksi diff --git a/htdocs/langs/is_IS/mrp.lang b/htdocs/langs/is_IS/mrp.lang index 8fe3fd8f4c1..ca52ce21b60 100644 --- a/htdocs/langs/is_IS/mrp.lang +++ b/htdocs/langs/is_IS/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/it_IT/mrp.lang b/htdocs/langs/it_IT/mrp.lang index 1e6247f3799..6d54470bf3f 100644 --- a/htdocs/langs/it_IT/mrp.lang +++ b/htdocs/langs/it_IT/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Il valore di 0,95 indica una media di 5%% di DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Elimina Ordine di Produzione ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Ordini di produzione NewMO=Nuovo ordine di produzione QtyToProduce=Qtà da produrre diff --git a/htdocs/langs/ka_GE/mrp.lang b/htdocs/langs/ka_GE/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/ka_GE/mrp.lang +++ b/htdocs/langs/ka_GE/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/kk_KZ/mrp.lang b/htdocs/langs/kk_KZ/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/kk_KZ/mrp.lang +++ b/htdocs/langs/kk_KZ/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/km_KH/mrp.lang b/htdocs/langs/km_KH/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/km_KH/mrp.lang +++ b/htdocs/langs/km_KH/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/kn_IN/mrp.lang b/htdocs/langs/kn_IN/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/kn_IN/mrp.lang +++ b/htdocs/langs/kn_IN/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/ko_KR/main.lang b/htdocs/langs/ko_KR/main.lang index d4c9db86587..4866f431c83 100644 --- a/htdocs/langs/ko_KR/main.lang +++ b/htdocs/langs/ko_KR/main.lang @@ -4,7 +4,7 @@ DIRECTION=ltr # msungstdlight or cid0ct are for traditional Chinese (traditional does not render with Ubuntu pdf reader) # stsongstdlight or cid0cs are for simplified Chinese # To read Chinese pdf with Linux: sudo apt-get install poppler-data -FONTFORPDF=헬 베티 카 +FONTFORPDF=cid0kr FONTSIZEFORPDF=10 SeparatorDecimal=. SeparatorThousand=None diff --git a/htdocs/langs/ko_KR/mrp.lang b/htdocs/langs/ko_KR/mrp.lang index 131e1f376ac..9ea63ea0c0c 100644 --- a/htdocs/langs/ko_KR/mrp.lang +++ b/htdocs/langs/ko_KR/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/lo_LA/mrp.lang b/htdocs/langs/lo_LA/mrp.lang index 00db7f202ec..daffab535ba 100644 --- a/htdocs/langs/lo_LA/mrp.lang +++ b/htdocs/langs/lo_LA/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/lt_LT/mrp.lang b/htdocs/langs/lt_LT/mrp.lang index 9760b1babbe..a88ffc2687d 100644 --- a/htdocs/langs/lt_LT/mrp.lang +++ b/htdocs/langs/lt_LT/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/lv_LV/main.lang b/htdocs/langs/lv_LV/main.lang index d380a59d050..9f0539dac39 100644 --- a/htdocs/langs/lv_LV/main.lang +++ b/htdocs/langs/lv_LV/main.lang @@ -4,7 +4,7 @@ DIRECTION=ltr # msungstdlight or cid0ct are for traditional Chinese (traditional does not render with Ubuntu pdf reader) # stsongstdlight or cid0cs are for simplified Chinese # To read Chinese pdf with Linux: sudo apt-get install poppler-data -FONTFORPDF=Helvetica +FONTFORPDF=helvetica FONTSIZEFORPDF=10 SeparatorDecimal=, SeparatorThousand=None diff --git a/htdocs/langs/mk_MK/mrp.lang b/htdocs/langs/mk_MK/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/mk_MK/mrp.lang +++ b/htdocs/langs/mk_MK/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/mn_MN/mrp.lang b/htdocs/langs/mn_MN/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/mn_MN/mrp.lang +++ b/htdocs/langs/mn_MN/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/ne_NP/mrp.lang b/htdocs/langs/ne_NP/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/ne_NP/mrp.lang +++ b/htdocs/langs/ne_NP/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/nl_BE/admin.lang b/htdocs/langs/nl_BE/admin.lang index f083382f5cb..8484cbcff71 100644 --- a/htdocs/langs/nl_BE/admin.lang +++ b/htdocs/langs/nl_BE/admin.lang @@ -48,7 +48,6 @@ NotConfigured=Module/Applicatie is niet geconfigureerd OtherSetup=Overige instellingen CurrentValueSeparatorThousand=Duizend scheidingsteken LocalisationDolibarrParameters=Lokalisatieparameters -ClientTZ=Tijdzone van de klant (gebruiker) ClientHour=Tijd bij de klant (gebruiker) PHPTZ=Tijdzone binnen de PHP server DaylingSavingTime=Zomertijd (gebruiker) diff --git a/htdocs/langs/nl_NL/mrp.lang b/htdocs/langs/nl_NL/mrp.lang index d94344175c0..143e3cb4d55 100644 --- a/htdocs/langs/nl_NL/mrp.lang +++ b/htdocs/langs/nl_NL/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Waarde van 0,95 betekent een gemiddelde van 5 DeleteBillOfMaterials=Stuklijst verwijderen DeleteMo=Productieorder verwijderen ConfirmDeleteBillOfMaterials=Weet u zeker dat u deze stuklijst wilt verwijderen? -ConfirmDeleteMo=Weet u zeker dat u deze stuklijst wilt verwijderen? +ConfirmDeleteMo=Weet u zeker dat u deze Productieorder wilt verwijderen? MenuMRP=Productieorders NewMO=Nieuwe productieorder QtyToProduce=Te produceren aantal diff --git a/htdocs/langs/pt_BR/admin.lang b/htdocs/langs/pt_BR/admin.lang index 8efa423b8f0..5278c86bced 100644 --- a/htdocs/langs/pt_BR/admin.lang +++ b/htdocs/langs/pt_BR/admin.lang @@ -107,7 +107,6 @@ CurrentValueSeparatorThousand=Separador de milhar IdModule=Módulo ID IdPermissions=Permissão ID LanguageBrowserParameter=Parâmetro de Linguagem %s -ClientTZ=Fuso Horário do cliente (usuário) ClientHour=Horário do Cliente (usuário) OSTZ=Fuso Horário do OS do Servidor PHPTZ=Fuso Horário do servidor PHP @@ -1196,7 +1195,6 @@ ServiceSetup=Configurações do módulo de serviços ProductServiceSetup=Configurações dos módulos de produtos e serviços NumberOfProductShowInSelect=Número máximo de produtos para mostrar em listas de seleção de combinação (0 = sem limite) ViewProductDescInFormAbility=Exibir descrições de produtos em formulários (mostrados de outra forma em um pop-up de dicas de ferramentas) -DoNotAddProductDescAtAddLines=Não adicionar descrição do produto (do cartão do produto) no envio, adicione linhas nos formulários OnProductSelectAddProductDesc=Como usar a descrição dos produtos ao adicionar um produto como uma linha de um documento AutoFillFormFieldBeforeSubmit=Preencher automaticamente o campo de entrada da descrição com a descrição do produto DoNotAutofillButAutoConcat=Não preencha automaticamente o campo de entrada com a descrição do produto. A descrição do produto será concatenada com a descrição inserida automaticamente. diff --git a/htdocs/langs/pt_BR/eventorganization.lang b/htdocs/langs/pt_BR/eventorganization.lang index 1046596e57e..ad883105022 100644 --- a/htdocs/langs/pt_BR/eventorganization.lang +++ b/htdocs/langs/pt_BR/eventorganization.lang @@ -2,6 +2,5 @@ ModuleEventOrganizationName =Organização do Evento EventOrganizationDescription =Organização do Evento atraves do modulo Projetos EventOrganizationMenuLeft =Eventos organizados -EventOrganizationSetup =Configuracao de Organização do Evento EventOrganizationSetupPage =Organização do Eventos pagina de configuracao EvntOrgDraft =Minuta diff --git a/htdocs/langs/pt_PT/mrp.lang b/htdocs/langs/pt_PT/mrp.lang index 025f164f94e..39982e5bd35 100644 --- a/htdocs/langs/pt_PT/mrp.lang +++ b/htdocs/langs/pt_PT/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Eliminar Faturas de Materiais DeleteMo=Eliminar Encomenda de Manufaturação ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Encomendas de Manufatura NewMO=Nova Encomenda de Manufatura QtyToProduce=Qt. a produzir diff --git a/htdocs/langs/sk_SK/mrp.lang b/htdocs/langs/sk_SK/mrp.lang index d620b7e31e3..9917552ba94 100644 --- a/htdocs/langs/sk_SK/mrp.lang +++ b/htdocs/langs/sk_SK/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/sl_SI/mrp.lang b/htdocs/langs/sl_SI/mrp.lang index 30bf0ca0238..b700927dd12 100644 --- a/htdocs/langs/sl_SI/mrp.lang +++ b/htdocs/langs/sl_SI/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/sq_AL/mrp.lang b/htdocs/langs/sq_AL/mrp.lang index 29554c164a3..20a6d7238de 100644 --- a/htdocs/langs/sq_AL/mrp.lang +++ b/htdocs/langs/sq_AL/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/sr_RS/mrp.lang b/htdocs/langs/sr_RS/mrp.lang index 16ab0c8ac49..999a6ec67b8 100644 --- a/htdocs/langs/sr_RS/mrp.lang +++ b/htdocs/langs/sr_RS/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/sw_SW/mrp.lang b/htdocs/langs/sw_SW/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/sw_SW/mrp.lang +++ b/htdocs/langs/sw_SW/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/tg_TJ/mrp.lang b/htdocs/langs/tg_TJ/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/tg_TJ/mrp.lang +++ b/htdocs/langs/tg_TJ/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/th_TH/main.lang b/htdocs/langs/th_TH/main.lang index 367ef49849e..7f635f1da50 100644 --- a/htdocs/langs/th_TH/main.lang +++ b/htdocs/langs/th_TH/main.lang @@ -4,7 +4,7 @@ DIRECTION=ltr # msungstdlight or cid0ct are for traditional Chinese (traditional does not render with Ubuntu pdf reader) # stsongstdlight or cid0cs are for simplified Chinese # To read Chinese pdf with Linux: sudo apt-get install poppler-data -FONTFORPDF=Helvetica +FONTFORPDF=helvetica FONTSIZEFORPDF=10 SeparatorDecimal=. SeparatorThousand=, diff --git a/htdocs/langs/th_TH/mrp.lang b/htdocs/langs/th_TH/mrp.lang index d5d061b855b..229690f76fd 100644 --- a/htdocs/langs/th_TH/mrp.lang +++ b/htdocs/langs/th_TH/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/tr_TR/mrp.lang b/htdocs/langs/tr_TR/mrp.lang index 574ddefd491..b9c69a56364 100644 --- a/htdocs/langs/tr_TR/mrp.lang +++ b/htdocs/langs/tr_TR/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Üretim Emri Sil ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Üretim Emirleri NewMO=Yeni Üretim Emiri QtyToProduce=Qty to produce diff --git a/htdocs/langs/uk_UA/mrp.lang b/htdocs/langs/uk_UA/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/uk_UA/mrp.lang +++ b/htdocs/langs/uk_UA/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/vi_VN/mrp.lang b/htdocs/langs/vi_VN/mrp.lang index f708bed87af..d24ddfe3b48 100644 --- a/htdocs/langs/vi_VN/mrp.lang +++ b/htdocs/langs/vi_VN/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Xóa hóa đơn vật liệu DeleteMo=Xóa đơn hàng sản xuất ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Đơn đặt hàng sản xuất NewMO=Thêm Đơn hàng sản xuất QtyToProduce=Số lượng để sản xuất diff --git a/htdocs/langs/zh_CN/mrp.lang b/htdocs/langs/zh_CN/mrp.lang index 86170bd9d91..e9f0381124a 100644 --- a/htdocs/langs/zh_CN/mrp.lang +++ b/htdocs/langs/zh_CN/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/langs/zh_HK/mrp.lang b/htdocs/langs/zh_HK/mrp.lang index 2414a92cefb..5d226c0f77b 100644 --- a/htdocs/langs/zh_HK/mrp.lang +++ b/htdocs/langs/zh_HK/mrp.lang @@ -31,7 +31,7 @@ ValueOfMeansLossForProductProduced=Value of 0.95 means an average of 5%% of loss DeleteBillOfMaterials=Delete Bill Of Materials DeleteMo=Delete Manufacturing Order ConfirmDeleteBillOfMaterials=Are you sure you want to delete this Bill Of Materials? -ConfirmDeleteMo=Are you sure you want to delete this Bill Of Materials? +ConfirmDeleteMo=Are you sure you want to delete this Manufacturing Order? MenuMRP=Manufacturing Orders NewMO=New Manufacturing Order QtyToProduce=Qty to produce diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index f54da087731..88701e35166 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -429,7 +429,7 @@ if ($id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->loan->write) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $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); @@ -446,9 +446,10 @@ if ($id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } @@ -621,7 +622,6 @@ if ($id > 0) { print ''; print '
    '; - print '
    '; /* * Payments @@ -693,7 +693,6 @@ if ($id > 0) { dol_print_error($db); } - print '
    '; print '
    '; print ''; @@ -717,22 +716,22 @@ if ($id > 0) { // Edit if (($object->paid == 0 || $object->paid == 2) && $user->rights->loan->write) { - print ''; + print ''; } // Emit payment if (($object->paid == 0 || $object->paid == 2) && ((price2num($object->capital) > 0 && round($staytopay) < 0) || (price2num($object->capital) > 0 && round($staytopay) > 0)) && $user->rights->loan->write) { - print ''; + print ''; } // Classify 'paid' if (($object->paid == 0 || $object->paid == 2) && round($staytopay) <= 0 && $user->rights->loan->write) { - print ''; + print ''; } // Delete if (($object->paid == 0 || $object->paid == 2) && $user->rights->loan->delete) { - print ''; + print ''; } print ""; diff --git a/htdocs/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index 0ec7786fc20..ec9ce00b7e9 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -517,17 +517,17 @@ class Loan extends CommonObject unset($this->labelStatus); // Force to reset the array of status label, because label can change depending on parameters if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; - $this->labelStatus[self::STATUS_UNPAID] = $langs->trans('Unpaid'); - $this->labelStatus[self::STATUS_PAID] = $langs->trans('Paid'); - $this->labelStatus[self::STATUS_STARTED] = $langs->trans("BillStatusStarted"); + $this->labelStatus[self::STATUS_UNPAID] = $langs->transnoentitiesnoconv('Unpaid'); + $this->labelStatus[self::STATUS_PAID] = $langs->transnoentitiesnoconv('Paid'); + $this->labelStatus[self::STATUS_STARTED] = $langs->transnoentitiesnoconv("BillStatusStarted"); if ($status == 0 && $alreadypaid > 0) { - $this->labelStatus[self::STATUS_UNPAID] = $langs->trans("BillStatusStarted"); + $this->labelStatus[self::STATUS_UNPAID] = $langs->transnoentitiesnoconv("BillStatusStarted"); } - $this->labelStatusShort[self::STATUS_UNPAID] = $langs->trans('Unpaid'); - $this->labelStatusShort[self::STATUS_PAID] = $langs->trans('Enabled'); - $this->labelStatusShort[self::STATUS_STARTED] = $langs->trans("BillStatusStarted"); + $this->labelStatusShort[self::STATUS_UNPAID] = $langs->transnoentitiesnoconv('Unpaid'); + $this->labelStatusShort[self::STATUS_PAID] = $langs->transnoentitiesnoconv('Enabled'); + $this->labelStatusShort[self::STATUS_STARTED] = $langs->transnoentitiesnoconv("BillStatusStarted"); if ($status == 0 && $alreadypaid > 0) { - $this->labelStatusShort[self::STATUS_UNPAID] = $langs->trans("BillStatusStarted"); + $this->labelStatusShort[self::STATUS_UNPAID] = $langs->transnoentitiesnoconv("BillStatusStarted"); } } diff --git a/htdocs/loan/document.php b/htdocs/loan/document.php index 97c0ea56b15..ce63cb248f7 100644 --- a/htdocs/loan/document.php +++ b/htdocs/loan/document.php @@ -71,6 +71,8 @@ if ($id > 0) { $upload_dir = $conf->loan->dir_output.'/'.dol_sanitizeFileName($object->ref); $modulepart = 'loan'; +$permissiontoadd = $user->rights->loan->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php + /* * Actions @@ -106,7 +108,7 @@ if ($object->id) { $morehtmlref .= '
    '.$langs->trans('Project').' : '; if ($user->rights->loan->write) { //if ($action != 'classify') - // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + // $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 .= '
    '; @@ -122,9 +124,10 @@ if ($object->id) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/loan/info.php b/htdocs/loan/info.php index 7ecc41fe4d6..3a5e95c7823 100644 --- a/htdocs/loan/info.php +++ b/htdocs/loan/info.php @@ -72,7 +72,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= '
    '.$langs->trans('Project').' : '; if ($user->rights->loan->write) { //if ($action != 'classify') - // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + // $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 .= ''; @@ -88,9 +88,10 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/loan/note.php b/htdocs/loan/note.php index a17445db6cf..0b982728b9e 100644 --- a/htdocs/loan/note.php +++ b/htdocs/loan/note.php @@ -97,7 +97,7 @@ if ($id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' : '; if ($user->rights->loan->write) { //if ($action != 'classify') - // $morehtmlref .= '' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + // $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 .= ''; @@ -113,9 +113,10 @@ if ($id > 0) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/loan/payment/card.php b/htdocs/loan/payment/card.php index 0292fbf5b2c..198025215b7 100644 --- a/htdocs/loan/payment/card.php +++ b/htdocs/loan/payment/card.php @@ -222,7 +222,7 @@ print '
    '; if (empty($action) && !empty($user->rights->loan->delete)) { if (!$disable_delete) { - print ''.$langs->trans('Delete').''; + print ''.$langs->trans('Delete').''; } else { print ''.$langs->trans('Delete').''; } diff --git a/htdocs/loan/schedule.php b/htdocs/loan/schedule.php index 6dae3383d47..ca6f5d50534 100644 --- a/htdocs/loan/schedule.php +++ b/htdocs/loan/schedule.php @@ -154,7 +154,7 @@ if (!empty($conf->projet->enabled)) { $morehtmlref .= '
    '.$langs->trans('Project').' : '; if ($user->rights->loan->write) { if ($action != 'classify') { - //$morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + //$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 .= ''; @@ -171,9 +171,10 @@ if (!empty($conf->projet->enabled)) { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 6bb5b39507b..25bc42046a9 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -72,7 +72,7 @@ function realCharForNumericEntities($matches) return chr((int) $newstringnumentity); } - return '&#'.$matches[1]; // Value will be unchanged because regex was /&#( )/ + return '&#'.$matches[1]; // Value will be unchanged because regex was /&#( )/ } /** @@ -94,7 +94,7 @@ function testSqlAndScriptInject($val, $type) do { $oldval = $val; $val = html_entity_decode($val, ENT_QUOTES | ENT_HTML5); - $val = preg_replace_callback('/&#(x?[0-9][0-9a-f]+)/i', 'realCharForNumericEntities', $val); // Sometimes we have entities without the ; at end so html_entity_decode does not work but entities is still interpreted by browser. + $val = preg_replace_callback('/&#(x?[0-9][0-9a-f]+)/i', 'realCharForNumericEntities', $val); // Sometimes we have entities without the ; at end so html_entity_decode does not work but entities is still interpreted by browser. } while ($oldval != $val); //print "after decoding $val\n"; @@ -146,7 +146,7 @@ function testSqlAndScriptInject($val, $type) $inj += preg_match('/=data:/si', $val); // List of dom events is on https://www.w3schools.com/jsref/dom_obj_event.asp and https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers $inj += preg_match('/on(mouse|drag|key|load|touch|pointer|select|transition)([a-z]*)\s*=/i', $val); // onmousexxx can be set on img or any html tag like - $inj += preg_match('/on(abort|afterprint|animation|auxclick|beforeprint|beforeunload|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)\s*=/i', $val); + $inj += preg_match('/on(abort|afterprint|animation|auxclick|beforecopy|beforecut|beforeprint|beforeunload|blur|cancel|canplay|canplaythrough|change|click|close|contextmenu|cuechange|copy|cut)\s*=/i', $val); $inj += preg_match('/on(dblclick|drop|durationchange|emptied|ended|error|focus|focusin|focusout|formdata|gotpointercapture|hashchange|input|invalid)\s*=/i', $val); $inj += preg_match('/on(lostpointercapture|offline|online|pagehide|pageshow)\s*=/i', $val); $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|reset|resize|scroll|search|seeked|seeking|show|stalled|start|submit|suspend)\s*=/i', $val); @@ -450,60 +450,67 @@ if (!defined('NOTOKENRENEWAL') && !defined('NOSESSION')) { $_SESSION['token'] = $_SESSION['newtoken']; } - // Save in $_SESSION['newtoken'] what will be next token. Into forms, we will add param token = $_SESSION['newtoken'] - $token = dol_hash(uniqid(mt_rand(), false), 'md5'); // Generates a hash of a random number. We don't need a secured hash, just a changing random value. - $_SESSION['newtoken'] = $token; - dol_syslog("NEW TOKEN generated by : " . $_SERVER['PHP_SELF'], LOG_DEBUG); + if (!isset($_SESSION['newtoken']) || getDolGlobalInt('MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL')) { + // Save in $_SESSION['newtoken'] what will be next token. Into forms, we will add param token = $_SESSION['newtoken'] + $token = dol_hash(uniqid(mt_rand(), false), 'md5'); // Generates a hash of a random number. We don't need a secured hash, just a changing random value. + $_SESSION['newtoken'] = $token; + dol_syslog("NEW TOKEN generated by : ".$_SERVER['PHP_SELF'], LOG_DEBUG); + } } } //dol_syslog("aaaa - ".defined('NOCSRFCHECK')." - ".$dolibarr_nocsrfcheck." - ".$conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN." - ".$_SERVER['REQUEST_METHOD']." - ".GETPOST('token', 'alpha')); // Check validity of token, only if option MAIN_SECURITY_CSRF_WITH_TOKEN enabled or if constant CSRFCHECK_WITH_TOKEN is set into page -if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)) || defined('CSRFCHECK_WITH_TOKEN')) { +if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && getDolGlobalInt('MAIN_SECURITY_CSRF_WITH_TOKEN')) || defined('CSRFCHECK_WITH_TOKEN')) { // Array of action code where CSRFCHECK with token will be forced (so token must be provided on url request) - $arrayofactiontoforcetokencheck = array( - 'activate', 'add', 'addrights', 'addtimespent', - 'confirm_create_user', 'confirm_create_thirdparty', 'confirm_delete', 'confirm_deletedir', 'confirm_deletefile', 'confirm_purge', 'confirm_reject_check', - 'delete', 'deletefilter', 'deleteoperation', 'deleteprof', 'deletepayment', 'delrights', - 'disable', - 'doprev', 'donext', 'dvprev', 'dvnext', - 'enable', - 'install', - 'setpricelevel', - 'update' - ); $sensitiveget = false; - if (in_array(GETPOST('action', 'aZ09'), $arrayofactiontoforcetokencheck)) { + if ((GETPOSTISSET('massaction') || GETPOST('action', 'aZ09')) && getDolGlobalInt('MAIN_SECURITY_CSRF_WITH_TOKEN') >= 3) { + // All GET actions and mass actions are processed as sensitive. $sensitiveget = true; + } elseif (getDolGlobalInt('MAIN_SECURITY_CSRF_WITH_TOKEN') >= 2) { + // Few GET actions coded with a &token into url are processed as sensitive. + $arrayofactiontoforcetokencheck = array( + 'activate', + 'doprev', 'donext', 'dvprev', 'dvnext', + 'install', + 'reopen' + ); + if (in_array(GETPOST('action', 'aZ09'), $arrayofactiontoforcetokencheck)) { + $sensitiveget = true; + } + if (preg_match('/^(add|classify|close|confirm|copy|del|disable|enable|remove|set|unset|update|save)/', GETPOST('action', 'aZ09'))) { + $sensitiveget = true; + } } - if (preg_match('/^(disable_|enable_|setremise)/', GETPOST('action', 'aZ09'))) { - $sensitiveget = true; - } - // Check a token is provided for all cases that need a mandatory token // (all POST actions + all login, actions and mass actions on pages with CSRFCHECK_WITH_TOKEN set + all sensitive GET actions) if ( $_SERVER['REQUEST_METHOD'] == 'POST' || $sensitiveget || - ((GETPOSTISSET('actionlogin') || GETPOSTISSET('action') || GETPOSTISSET('massaction')) && defined('CSRFCHECK_WITH_TOKEN')) + GETPOSTISSET('massaction') || + ((GETPOSTISSET('actionlogin') || GETPOSTISSET('action')) && defined('CSRFCHECK_WITH_TOKEN')) ) { // If token is not provided or empty, error (we are in case it is mandatory) if (!GETPOST('token', 'alpha') || GETPOST('token', 'alpha') == 'notrequired') { if (GETPOST('uploadform', 'int')) { - dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"])?'':$_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused. File size too large."); + dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused. File size too large."); $langs->loadLangs(array("errors", "install")); print $langs->trans("ErrorFileSizeTooLarge").' '; print $langs->trans("ErrorGoBackAndCorrectParameters"); die; } else { if (defined('CSRFCHECK_WITH_TOKEN')) { - dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"])?'':$_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (CSRFCHECK_WITH_TOKEN protection) in main.inc.php. Token not provided.", LOG_WARNING); + dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (CSRFCHECK_WITH_TOKEN protection) in main.inc.php. Token not provided.", LOG_WARNING); print "Access to a page that needs a token (constant CSRFCHECK_WITH_TOKEN is defined) is refused by CSRF protection in main.inc.php. Token not provided.\n"; } else { - dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"])?'':$_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (POST method or GET with a sensible value for 'action' parameter) in main.inc.php. Token not provided.", LOG_WARNING); + dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (POST method or GET with a sensible value for 'action' parameter) in main.inc.php. Token not provided.", LOG_WARNING); print "Access to this page this way (POST method or GET with a sensible value for 'action' parameter) is refused by CSRF protection in main.inc.php. Token not provided.\n"; - print "If you access your server behind a proxy using url rewriting and the parameter is provided by caller, you might check that all HTTP header are propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0 into setup).\n"; + print "If you access your server behind a proxy using url rewriting and the parameter is provided by caller, you might check that all HTTP header are propagated (or add the line \$dolibarr_nocsrfcheck=1 into your conf.php file or MAIN_SECURITY_CSRF_WITH_TOKEN to 0"; + if (!empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)) { + print " instead of ".$conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN; + } + print " into setup).\n"; } die; } @@ -513,10 +520,9 @@ if ((!defined('NOCSRFCHECK') && empty($dolibarr_nocsrfcheck) && !empty($conf->gl $sessiontokenforthisurl = (empty($_SESSION['token']) ? '' : $_SESSION['token']); // TODO Get the sessiontokenforthisurl into the array of session token if (GETPOSTISSET('token') && GETPOST('token') != 'notrequired' && GETPOST('token', 'alpha') != $sessiontokenforthisurl) { - dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"])?'':$_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (invalid token), so we disable POST and some GET parameters - referer=".$_SERVER['HTTP_REFERER'].", action=".GETPOST('action', 'aZ09').", _GET|POST['token']=".GETPOST('token', 'alpha').", _SESSION['token']=".$_SESSION['token'], LOG_WARNING); + dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." refused by CSRF protection (invalid token), so we disable POST and some GET parameters - referer=".$_SERVER['HTTP_REFERER'].", action=".GETPOST('action', 'aZ09').", _GET|POST['token']=".GETPOST('token', 'alpha').", _SESSION['token']=".$_SESSION['token'], LOG_WARNING); //print 'Unset POST by CSRF protection in main.inc.php.'; // Do not output anything because this create problems when using the BACK button on browsers. setEventMessages('SecurityTokenHasExpiredSoActionHasBeenCanceledPleaseRetry', null, 'warnings'); - //if ($conf->global->MAIN_FEATURES_LEVEL >= 1) setEventMessages('Unset POST and GET params by CSRF protection in main.inc.php (Token provided was not generated by the previous page).'."
    \n".'$_SERVER[REQUEST_URI] = '.$_SERVER['REQUEST_URI'].' $_SERVER[REQUEST_METHOD] = '.$_SERVER['REQUEST_METHOD'].' GETPOST(token) = '.GETPOST('token', 'alpha').' $_SESSION[token] = '.$_SESSION['token'], null, 'warnings'); if (isset($_POST['id'])) $savid = ((int) $_POST['id']); unset($_POST); //unset($_POST['action']); unset($_POST['massaction']); @@ -778,7 +784,7 @@ if (!defined('NOLOGIN')) { // End test login / passwords if (!$login || (in_array('ldap', $authmode) && empty($passwordtotest))) { // With LDAP we refused empty password because some LDAP are "opened" for anonymous access so connexion is a success. // No data to test login, so we show the login page. - dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"])?'':$_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." - action=".GETPOST('action', 'aZ09')." - actionlogin=".GETPOST('actionlogin', 'aZ09')." - showing the login form and exit", LOG_INFO); + dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"]." - action=".GETPOST('action', 'aZ09')." - actionlogin=".GETPOST('actionlogin', 'aZ09')." - showing the login form and exit", LOG_INFO); if (defined('NOREDIRECTBYMAINTOLOGIN')) { return 'ERROR_NOT_LOGGED'; } else { @@ -1039,6 +1045,28 @@ if (!defined('NOLOGIN')) { $user->rights->user->user->supprimer = 1; $user->rights->user->self->creer = 1; $user->rights->user->self->password = 1; + + //Required if advanced permissions are used with MAIN_USE_ADVANCED_PERMS + if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { + if (empty($user->rights->user->user_advance)) { + $user->rights->user->user_advance = new stdClass(); // To avoid warnings + } + if (empty($user->rights->user->self_advance)) { + $user->rights->user->self_advance = new stdClass(); // To avoid warnings + } + if (empty($user->rights->user->group_advance)) { + $user->rights->user->group_advance = new stdClass(); // To avoid warnings + } + + $user->rights->user->user_advance->readperms = 1; + $user->rights->user->user_advance->write = 1; + $user->rights->user->self_advance->readperms = 1; + $user->rights->user->self_advance->writeperms = 1; + $user->rights->user->group_advance->read = 1; + $user->rights->user->group_advance->readperms = 1; + $user->rights->user->group_advance->write = 1; + $user->rights->user->group_advance->delete = 1; + } } /* @@ -1147,7 +1175,7 @@ if (!defined('NOLOGIN')) { $user->getrights(); } -dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"])?'':$_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"].' - action='.GETPOST('action', 'aZ09').', massaction='.GETPOST('massaction', 'aZ09').(defined('NOTOKENRENEWAL') ? ' NOTOKENRENEWAL='.constant('NOTOKENRENEWAL') : ''), LOG_NOTICE); +dol_syslog("--- Access to ".(empty($_SERVER["REQUEST_METHOD"]) ? '' : $_SERVER["REQUEST_METHOD"].' ').$_SERVER["PHP_SELF"].' - action='.GETPOST('action', 'aZ09').', massaction='.GETPOST('massaction', 'aZ09').(defined('NOTOKENRENEWAL') ? ' NOTOKENRENEWAL='.constant('NOTOKENRENEWAL') : ''), LOG_NOTICE); //Another call for easy debugg //dol_syslog("Access to ".$_SERVER["PHP_SELF"].' '.$_SERVER["HTTP_REFERER"].' GET='.join(',',array_keys($_GET)).'->'.join(',',$_GET).' POST:'.join(',',array_keys($_POST)).'->'.join(',',$_POST)); @@ -1408,7 +1436,9 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr print ''."\n"; // Do not index print ''."\n"; // Scale for mobile device print ''."\n"; - + if (getDolGlobalInt('MAIN_FEATURES_LEVEL')) { + print ''."\n"; + } // Favicon $favicon = DOL_URL_ROOT.'/theme/dolibarr_256x256_color.png'; if (!empty($mysoc->logo_squarred_mini)) { @@ -1597,11 +1627,6 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr } else { print ''."\n"; } - /*if (! empty($conf->global->MAIN_FEATURES_LEVEL) && ! defined('JS_JQUERY_MIGRATE_DISABLED')) - { - if (defined('JS_JQUERY_MIGRATE') && constant('JS_JQUERY_MIGRATE')) print ''."\n"; - else print ''."\n"; - }*/ if (defined('JS_JQUERY_UI') && constant('JS_JQUERY_UI')) { print ''."\n"; } else { @@ -1764,7 +1789,6 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead global $hookmanager, $menumanager; $searchform = ''; - $bookmarks = ''; // Instantiate hooks for external modules $hookmanager->initHooks(array('toprightmenu')); @@ -1789,12 +1813,12 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead print "\n".''."\n"; - print '
    '; // dol_invisible_topmenu differs from dol_hide_topmenu: dol_invisible_topmenu means we output menu but we make it invisible. + print '
    '; // dol_invisible_topmenu differs from dol_hide_topmenu: dol_invisible_topmenu means we output menu but we make it invisible. // Show menu entries print '
    '."\n"; $menumanager->atarget = $target; - $menumanager->showmenu('top', array('searchform'=>$searchform, 'bookmarks'=>$bookmarks)); // This contains a \n + $menumanager->showmenu('top', array('searchform'=>$searchform)); // This contains a \n print "
    \n"; // Define link to login card @@ -1812,8 +1836,8 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead $appli .= " ".DOL_VERSION; } - if (!empty($conf->global->MAIN_FEATURES_LEVEL)) { - $appli .= "
    ".$langs->trans("LevelOfFeature").': '.$conf->global->MAIN_FEATURES_LEVEL; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL')) { + $appli .= "
    ".$langs->trans("LevelOfFeature").': '.getDolGlobalInt('MAIN_FEATURES_LEVEL'); } $logouttext = ''; @@ -1859,7 +1883,7 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead } // Link to print main content area - if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $conf->browser->layout != 'phone') { + if (empty($conf->global->MAIN_PRINT_DISABLELINK) && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $qs = dol_escape_htmltag($_SERVER["QUERY_STRING"]); if (isset($_POST) && is_array($_POST)) { @@ -1973,7 +1997,7 @@ function top_menu($head, $title = '', $target = '', $disablejs = 0, $disablehead print "
    \n"; // end div class="login_block" - print '
    '; + print ''; print '
    '; print "\n\n"; @@ -1998,6 +2022,8 @@ function top_menu_user($hideloginname = 0, $urllogout = '') global $dolibarr_main_authentication, $dolibarr_main_demo; global $menumanager; + $langs->load('companies'); + $userImage = $userDropDownImage = ''; if (!empty($user->photo)) { $userImage = Form::showphoto('userphoto', $user, 0, 0, 0, 'photouserphoto userphoto', 'small', 0, 1); @@ -2248,7 +2274,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_company') .'
    '. $langs->trans("ThirdParty") .'
    + '. img_picto('', 'object_company').'
    '.$langs->trans("ThirdParty").'
    '; } @@ -2259,7 +2285,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_contact') .'
    '. $langs->trans("Contact") .'
    + '. img_picto('', 'object_contact').'
    '.$langs->trans("Contact").'
    '; } @@ -2270,7 +2296,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_propal') .'
    '. $langs->trans("Proposal") .'
    + '. img_picto('', 'object_propal').'
    '.$langs->trans("Proposal").'
    '; } @@ -2281,7 +2307,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_order') .'
    '. $langs->trans("Order") .'
    + '. img_picto('', 'object_order').'
    '.$langs->trans("Order").'
    '; } @@ -2292,7 +2318,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_bill') .'
    '. $langs->trans("Bill") .'
    + '. img_picto('', 'object_bill').'
    '.$langs->trans("Bill").'
    '; } @@ -2303,7 +2329,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_contract') .'
    '. $langs->trans("Contract") .'
    + '. img_picto('', 'object_contract').'
    '.$langs->trans("Contract").'
    '; } @@ -2314,7 +2340,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_propal') .'
    '. $langs->trans("AskPrice") .'
    + '. img_picto('', 'object_propal').'
    '.$langs->trans("AskPrice").'
    '; } @@ -2325,7 +2351,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_order') .'
    '. $langs->trans("SupplierOrder") .'
    + '. img_picto('', 'object_order').'
    '.$langs->trans("SupplierOrder").'
    '; } @@ -2336,7 +2362,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_bill') .'
    '. $langs->trans("SupplierBill") .'
    + '. img_picto('', 'object_bill').'
    '.$langs->trans("SupplierBill").'
    '; } @@ -2347,7 +2373,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_product') .'
    '. $langs->trans("Product") .'
    + '. img_picto('', 'object_product').'
    '.$langs->trans("Product").'
    '; } @@ -2358,7 +2384,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_service') .'
    '. $langs->trans("Service") .'
    + '. img_picto('', 'object_service').'
    '.$langs->trans("Service").'
    '; } @@ -2369,7 +2395,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_trip') .'
    '. $langs->trans("ExpenseReport") .'
    + '. img_picto('', 'object_trip').'
    '.$langs->trans("ExpenseReport").'
    '; } @@ -2380,7 +2406,7 @@ function top_menu_quickadd()
    - '. img_picto('', 'object_holiday') .'
    '. $langs->trans("Holidays") .'
    + '. img_picto('', 'object_holiday').'
    '.$langs->trans("Holidays").'
    '; } @@ -2679,7 +2705,6 @@ function left_menu($menu_array_before, $helppagename = '', $notused = '', $menu_ global $hookmanager, $menumanager; $searchform = ''; - $bookmarks = ''; if (!empty($menu_array_before)) { dol_syslog("Deprecated parameter menu_array_before was used when calling main::left_menu function. Menu entries of module should now be defined into module descriptor and not provided when calling left_menu.", LOG_WARNING); @@ -2750,7 +2775,7 @@ function left_menu($menu_array_before, $helppagename = '', $notused = '', $menu_ // Show left menu with other forms $menumanager->menu_array = $menu_array_before; $menumanager->menu_array_after = $menu_array_after; - $menumanager->showmenu('left', array('searchform'=>$searchform, 'bookmarks'=>$bookmarks)); // output menu_array and menu found in database + $menumanager->showmenu('left', array('searchform'=>$searchform)); // output menu_array and menu found in database // Dolibarr version + help + bug report link print "\n"; @@ -2825,12 +2850,12 @@ function left_menu($menu_array_before, $helppagename = '', $notused = '', $menu_ $bugbaseurl .= urlencode("[*Short description*]\n"); $bugbaseurl .= urlencode("\n"); $bugbaseurl .= urlencode("## Environment\n"); - $bugbaseurl .= urlencode("- **Version**: " . DOL_VERSION . "\n"); - $bugbaseurl .= urlencode("- **OS**: " . php_uname('s') . "\n"); - $bugbaseurl .= urlencode("- **Web server**: " . $_SERVER["SERVER_SOFTWARE"] . "\n"); - $bugbaseurl .= urlencode("- **PHP**: " . php_sapi_name() . ' ' . phpversion() . "\n"); - $bugbaseurl .= urlencode("- **Database**: " . $db::LABEL . ' ' . $db->getVersion() . "\n"); - $bugbaseurl .= urlencode("- **URL(s)**: " . $_SERVER["REQUEST_URI"] . "\n"); + $bugbaseurl .= urlencode("- **Version**: ".DOL_VERSION."\n"); + $bugbaseurl .= urlencode("- **OS**: ".php_uname('s')."\n"); + $bugbaseurl .= urlencode("- **Web server**: ".$_SERVER["SERVER_SOFTWARE"]."\n"); + $bugbaseurl .= urlencode("- **PHP**: ".php_sapi_name().' '.phpversion()."\n"); + $bugbaseurl .= urlencode("- **Database**: ".$db::LABEL.' '.$db->getVersion()."\n"); + $bugbaseurl .= urlencode("- **URL(s)**: ".$_SERVER["REQUEST_URI"]."\n"); $bugbaseurl .= urlencode("\n"); $bugbaseurl .= urlencode("## Expected and actual behavior\n"); $bugbaseurl .= urlencode("[*Verbose description*]\n"); @@ -3050,7 +3075,7 @@ if (!function_exists("llxFooter")) { */ function llxFooter($comment = '', $zone = 'private', $disabledoutputofmessages = 0) { - global $conf, $db, $langs, $user, $mysoc, $object; + global $conf, $db, $langs, $user, $mysoc, $object, $hookmanager; global $delayedhtmlcontent; global $contextpage, $page, $limit; global $dolibarr_distrib; @@ -3192,6 +3217,7 @@ if (!function_exists("llxFooter")) { if (($_SERVER["PHP_SELF"] == DOL_URL_ROOT.'/index.php') || $forceping) { //print ''; $hash_unique_id = md5('dolibarr'.$conf->file->instance_unique_id); + if (empty($conf->global->MAIN_FIRST_PING_OK_DATE) || (!empty($conf->file->instance_unique_id) && ($hash_unique_id != $conf->global->MAIN_FIRST_PING_OK_ID) && ($conf->global->MAIN_FIRST_PING_OK_ID != 'disabled')) || $forceping) { @@ -3200,7 +3226,7 @@ if (!function_exists("llxFooter")) { print "\n\n"; } elseif (empty($_COOKIE['DOLINSTALLNOPING_'.$hash_unique_id]) || $forceping) { // Cookie is set when we uncheck the checkbox in the installation wizard. // MAIN_LAST_PING_KO_DATE - // Disable ping if MAIN_LAST_PING_KO_DATE is set and is recent + // Disable ping if MAIN_LAST_PING_KO_DATE is set and is recent (this month) if (!empty($conf->global->MAIN_LAST_PING_KO_DATE) && substr($conf->global->MAIN_LAST_PING_KO_DATE, 0, 6) == dol_print_date(dol_now(), '%Y%m') && !$forceping) { print "\n\n"; } else { @@ -3273,6 +3299,11 @@ if (!function_exists("llxFooter")) { } } + $reshook = $hookmanager->executeHooks('beforeBodyClose'); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + print $hookmanager->resPrint; + } + print "\n"; print "\n"; } diff --git a/htdocs/margin/admin/margin.php b/htdocs/margin/admin/margin.php index 2c224678f60..30c85197337 100644 --- a/htdocs/margin/admin/margin.php +++ b/htdocs/margin/admin/margin.php @@ -155,9 +155,9 @@ if (!empty($conf->use_javascript_ajax)) { print ajax_constantonoff('DISPLAY_MARGIN_RATES'); } else { if (empty($conf->global->DISPLAY_MARGIN_RATES)) { - print ''.img_picto($langs->trans("Disabled"), 'off').''; + print ''.img_picto($langs->trans("Disabled"), 'off').''; } else { - print ''.img_picto($langs->trans("Enabled"), 'on').''; + print ''.img_picto($langs->trans("Enabled"), 'on').''; } } print ''; @@ -172,9 +172,9 @@ if (!empty($conf->use_javascript_ajax)) { print ajax_constantonoff('DISPLAY_MARK_RATES'); } else { if (empty($conf->global->DISPLAY_MARK_RATES)) { - print ''.img_picto($langs->trans("Disabled"), 'off').''; + print ''.img_picto($langs->trans("Disabled"), 'off').''; } else { - print ''.img_picto($langs->trans("Enabled"), 'on').''; + print ''.img_picto($langs->trans("Enabled"), 'on').''; } } print ''; @@ -189,9 +189,9 @@ if (!empty($conf->use_javascript_ajax)) { print ajax_constantonoff('ForceBuyingPriceIfNull'); } else { if (empty($conf->global->ForceBuyingPriceIfNull)) { - print ''.img_picto($langs->trans("Disabled"), 'off').''; + print ''.img_picto($langs->trans("Disabled"), 'off').''; } else { - print ''.img_picto($langs->trans("Enabled"), 'on').''; + print ''.img_picto($langs->trans("Enabled"), 'on').''; } } print ''; @@ -208,7 +208,7 @@ $methods = array( print ''; print ''; -print ""; +print ''; print '
    '; print ''; print ''; print ''; print ''; print ''; } @@ -135,7 +135,7 @@ if ($socid > 0) { print showValueWithClipboardCPButton(dol_escape_htmltag($object->code_fournisseur)); $tmpcheck = $object->check_codefournisseur(); if ($tmpcheck != 0 && $tmpcheck != -5) { - print ' ('.$langs->trans("WrongSupplierCode").')'; + print ' ('.$langs->trans("WrongSupplierCode").')'; } print ''; } diff --git a/htdocs/modulebuilder/admin/setup.php b/htdocs/modulebuilder/admin/setup.php index 5aaae9f93eb..e5ccb0c3966 100644 --- a/htdocs/modulebuilder/admin/setup.php +++ b/htdocs/modulebuilder/admin/setup.php @@ -125,9 +125,9 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { print ajax_constantonoff('MODULEBUILDER_USE_ABOUT'); } else { if (empty($conf->global->MODULEBUILDER_USE_ABOUT)) { - print ''.img_picto($langs->trans("Disabled"), 'off').''; + print ''.img_picto($langs->trans("Disabled"), 'off').''; } else { - print ''.img_picto($langs->trans("Enabled"), 'on').''; + print ''.img_picto($langs->trans("Enabled"), 'on').''; } } print ''; diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index db8bc85816e..1ab03743747 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -262,6 +262,7 @@ if ($dirins && $action == 'initmodule' && $modulename) { // Delete some files related to Object (because the previous dolCopyDir has copied everything) dol_delete_file($destdir.'/myobject_card.php'); + dol_delete_file($destdir.'/myobject_contact.php'); dol_delete_file($destdir.'/myobject_note.php'); dol_delete_file($destdir.'/myobject_document.php'); dol_delete_file($destdir.'/myobject_agenda.php'); @@ -337,6 +338,14 @@ if ($dirins && $action == 'initmodule' && $modulename) { setEventMessages('ModuleInitialized', null); $module = $modulename; $modulename = ''; + + clearstatcache(true); + if (function_exists('opcache_invalidate')) { + opcache_reset(); // remove the include cache hell ! + } + + header("Location: ".$_SERVER["PHP_SELF"].'?module='.$modulename); + exit; } } @@ -953,7 +962,7 @@ if ($dirins && $action == 'initobject' && $module && GETPOST('createtablearray', if ($notnull) { $string .= ", 'notnull'=>".$notnull; } - if ($fieldname == 'ref') { + if ($fieldname == 'ref' || $fieldname == 'code') { $string .= ", 'showoncombobox'=>1"; } $string .= ", 'position'=>".$position; @@ -1295,21 +1304,33 @@ if ($dirins && $action == 'addproperty' && empty($cancel) && !empty($module) && $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Type")), null, 'errors'); } + } - if (!$error) { - $addfieldentry = array( - 'name'=>GETPOST('propname', 'aZ09'), 'label'=>GETPOST('proplabel', 'alpha'), 'type'=>GETPOST('proptype', 'alpha'), - 'arrayofkeyval'=>GETPOST('proparrayofkeyval', 'restricthtml'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}' - 'visible'=>GETPOST('propvisible', 'int'), 'enabled'=>GETPOST('propenabled', 'int'), - 'position'=>GETPOST('propposition', 'int'), 'notnull'=>GETPOST('propnotnull', 'int'), 'index'=>GETPOST('propindex', 'int'), 'searchall'=>GETPOST('propsearchall', 'int'), - 'isameasure'=>GETPOST('propisameasure', 'int'), 'comment'=>GETPOST('propcomment', 'alpha'), 'help'=>GETPOST('prophelp', 'alpha'), - 'css'=>GETPOST('propcss', 'aZ09'), 'cssview'=>GETPOST('propcssview', 'aZ09'), 'csslist'=>GETPOST('propcsslist', 'aZ09'), - 'validate' => GETPOST('propvalidate', 'int') - ); + if (!$error) { + $addfieldentry = array( + 'name'=>GETPOST('propname', 'aZ09'), + 'label'=>GETPOST('proplabel', 'alpha'), + 'type'=>GETPOST('proptype', 'alpha'), + 'arrayofkeyval'=>GETPOST('proparrayofkeyval', 'restricthtml'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}' + 'visible'=>GETPOST('propvisible', 'int'), + 'enabled'=>GETPOST('propenabled', 'int'), + 'position'=>GETPOST('propposition', 'int'), + 'notnull'=>GETPOST('propnotnull', 'int'), + 'index'=>GETPOST('propindex', 'int'), + 'searchall'=>GETPOST('propsearchall', 'int'), + 'isameasure'=>GETPOST('propisameasure', 'int'), + 'comment'=>GETPOST('propcomment', 'alpha'), + 'help'=>GETPOST('prophelp', 'alpha'), + 'css'=>GETPOST('propcss', 'aZ09'), + 'cssview'=>GETPOST('propcssview', 'aZ09'), + 'csslist'=>GETPOST('propcsslist', 'aZ09'), + 'default'=>GETPOST('propdefault', 'restricthtml'), + 'noteditable'=>intval(GETPOST('propnoteditable', 'int')), + 'validate' => GETPOST('propvalidate', 'int') + ); - if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) { - $addfieldentry['arrayofkeyval'] = json_decode($addfieldentry['arrayofkeyval'], true); - } + if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) { + $addfieldentry['arrayofkeyval'] = json_decode($addfieldentry['arrayofkeyval'], true); } } @@ -1405,6 +1426,14 @@ if ($dirins && $action == 'confirm_deletemodule') { if ($result > 0) { setEventMessages($langs->trans("DirWasRemoved", $modulelowercase), null); + + clearstatcache(true); + if (function_exists('opcache_invalidate')) { + opcache_reset(); // remove the include cache hell ! + } + + header("Location: ".$_SERVER["PHP_SELF"].'?module=deletemodule'); + exit; } else { setEventMessages($langs->trans("PurgeNothingToDelete"), null, 'warnings'); } @@ -1530,7 +1559,8 @@ if ($dirins && $action == 'generatepackage') { if (!dol_is_dir($dirofmodule)) { dol_mkdir($dirofmodule); } - $result = dol_compress_dir($dir, $outputfilezip, 'zip', '', $modulelowercase); + // Note: We exclude /bin/ to not include the already generated zip + $result = dol_compress_dir($dir, $outputfilezip, 'zip', '/\/bin\//', $modulelowercase); } else { $result = -1; } @@ -1694,8 +1724,8 @@ print load_fiche_titre($text, '', 'title_setup'); print ''.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'
    '; -print $textforlistofdirs; -print '
    '; +//print $textforlistofdirs; +//print '
    '; //var_dump($listofmodules); @@ -1720,7 +1750,7 @@ if ($message) { } //print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'
    '; -$infomodulesfound = '
    '.$form->textwithpicto(''.$langs->trans("ModuleBuilderDesc3", count($listofmodules)).'', $langs->trans("ModuleBuilderDesc4", $FILEFLAG)).'
    '; +$infomodulesfound = '
    '.$form->textwithpicto(''.$langs->trans("ModuleBuilderDesc3", count($listofmodules)).'', $langs->trans("ModuleBuilderDesc4", $FILEFLAG).'
    '.$textforlistofdirs).'
    '; // Load module descriptor @@ -1744,6 +1774,10 @@ if (!empty($module) && $module != 'initmodule' && $module != 'deletemodule') { $loadclasserrormessage = $e->getMessage()."
    \n"; $loadclasserrormessage .= 'File: '.$e->getFile()."
    \n"; $loadclasserrormessage .= 'Line: '.$e->getLine()."
    \n"; + } catch (Exception $e) { + $loadclasserrormessage = $e->getMessage()."
    \n"; + $loadclasserrormessage .= 'File: '.$e->getFile()."
    \n"; + $loadclasserrormessage .= 'Line: '.$e->getLine()."
    \n"; } if (class_exists($class)) { @@ -1758,6 +1792,7 @@ if (!empty($module) && $module != 'initmodule' && $module != 'deletemodule') { $error++; } $langs->load("errors"); + print ''; print img_warning('').' '.$langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module).'
    '; print $loadclasserrormessage; } @@ -1833,9 +1868,11 @@ if (is_array($listofmodules) && count($listofmodules) > 0) { $linktoenabledisable .= '   '.img_picto($langs->trans("Setup"), "setup", 'style="padding-right: 8px"').''; } } else { - $linktoenabledisable .= ''; - $linktoenabledisable .= img_picto($langs->trans("ModuleIsNotActive", $urltomodulesetup), 'switch_off', 'style="padding-right: 8px"', false, 0, 0, '', 'classfortooltip', 1); - $linktoenabledisable .= "\n"; + if (!empty($moduleobj)) { + $linktoenabledisable .= ''; + $linktoenabledisable .= img_picto($langs->trans("ModuleIsNotActive", $urltomodulesetup), 'switch_off', 'style="padding-right: 8px"', false, 0, 0, '', 'classfortooltip', 1); + $linktoenabledisable .= "\n"; + } } // Loop to show tab of each module @@ -1999,15 +2036,15 @@ if ($module == 'initmodule') { print '
    '; print ''; 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); + print $form->selectarray('search_'.$key, $val['arrayofkeyval'], $searchkey, $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, $search[$key], '', '', 'search_', 'maxwidth125', 1); + print $object->showInputField($val, $key, $searchkey, '', '', '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')); @@ -469,9 +470,9 @@ foreach ($object->fields as $key => $val) { 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') { - print $formadmin->select_language($search[$key], 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); + print $formadmin->select_language($searchkey, 'search_lang', 0, null, 1, 0, 0, 'minwidth150 maxwidth200', 2); } else { - print ''; + print ''; } print '
    '.$langs->trans("MARGIN_METHODE_FOR_DISCOUNT").''; @@ -224,13 +224,13 @@ print ''; // INTERNAL CONTACT TYPE USED AS COMMERCIAL AGENT print '
    '; print ''; -print ""; +print ''; print '
    '.$langs->trans("AgentContactType").''; $formcompany = new FormCompany($db); $facture = new Facture($db); -print $formcompany->selectTypeContact($facture, $conf->global->AGENT_CONTACT_TYPE, "AGENT_CONTACT_TYPE", "internal", "code", 1); +print $formcompany->selectTypeContact($facture, $conf->global->AGENT_CONTACT_TYPE, "AGENT_CONTACT_TYPE", "internal", "code", 1, "maxwidth250"); print ''; print ''; diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php index 6861f67db0d..7fe151b93f7 100644 --- a/htdocs/margin/customerMargins.php +++ b/htdocs/margin/customerMargins.php @@ -229,14 +229,14 @@ if (!empty($TSelectedCats)) { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'categorie_product as cp ON cp.fk_product=d.fk_product'; } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; if ($socid > 0) { $sql .= ' AND s.rowid = '.((int) $socid); } -if (!$user->rights->societe->client->voir && !$socid) { +if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } $sql .= " AND f.fk_statut NOT IN (".$db->sanitize(implode(', ', $invoice_status_except_list)).")"; diff --git a/htdocs/margin/index.php b/htdocs/margin/index.php index cab6dd9f0da..0dcab7435f7 100644 --- a/htdocs/margin/index.php +++ b/htdocs/margin/index.php @@ -32,4 +32,4 @@ if ($user->rights->produit->lire) { $page = 'agentMargins'; } -header('Location: '.dol_buildpath('/margin/'.$page.'.php', 1)); +header('Location: '.DOL_URL_ROOT.'/margin/'.$page.'.php'); diff --git a/htdocs/margin/tabs/productMargins.php b/htdocs/margin/tabs/productMargins.php index 3b14f1db808..062462be267 100644 --- a/htdocs/margin/tabs/productMargins.php +++ b/htdocs/margin/tabs/productMargins.php @@ -139,7 +139,7 @@ if ($id > 0 || !empty($ref)) { $sql = "SELECT s.nom as name, s.rowid as socid, s.code_client,"; $sql .= " f.rowid as facid, f.ref, f.total_ht,"; $sql .= " f.datef, f.paye, f.fk_statut as statut, f.type,"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " sc.fk_soc, sc.fk_user,"; } $sql .= " sum(d.total_ht) as selling_price,"; // may be negative or positive @@ -149,7 +149,7 @@ if ($id > 0 || !empty($ref)) { $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= ", ".MAIN_DB_PREFIX."facture as f"; $sql .= ", ".MAIN_DB_PREFIX."facturedet as d"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; } $sql .= " WHERE f.fk_soc = s.rowid"; @@ -157,7 +157,7 @@ if ($id > 0 || !empty($ref)) { $sql .= " AND f.entity IN (".getEntity('invoice').")"; $sql .= " AND d.fk_facture = f.rowid"; $sql .= " AND d.fk_product = ".((int) $object->id); - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); } if (!empty($socid)) { @@ -170,7 +170,7 @@ if ($id > 0 || !empty($ref)) { $sql .= " AND d.buy_price_ht <> 0"; } $sql .= " GROUP BY s.nom, s.rowid, s.code_client, f.rowid, f.ref, f.total_ht, f.datef, f.paye, f.fk_statut, f.type"; - if (!$user->rights->societe->client->voir && !$socid) { + if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= ", sc.fk_soc, sc.fk_user"; } $sql .= $db->order($sortfield, $sortorder); diff --git a/htdocs/margin/tabs/thirdpartyMargins.php b/htdocs/margin/tabs/thirdpartyMargins.php index 1b3cc468e5c..43e9c87c6e6 100644 --- a/htdocs/margin/tabs/thirdpartyMargins.php +++ b/htdocs/margin/tabs/thirdpartyMargins.php @@ -124,7 +124,7 @@ if ($socid > 0) { print showValueWithClipboardCPButton(dol_escape_htmltag($object->code_client)); $tmpcheck = $object->check_codeclient(); if ($tmpcheck != 0 && $tmpcheck != -5) { - print ' ('.$langs->trans("WrongCustomerCode").')'; + print ' ('.$langs->trans("WrongCustomerCode").')'; } print '
    '; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; print '
    '.$langs->trans("ReadmeFile").' : '.$pathtofilereadme.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; print '
    '.$langs->trans("ChangeLog").' : '.$pathtochangelog.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; @@ -2177,8 +2214,8 @@ if ($module == 'initmodule') { $pathtofile = 'langs/'.$langfile['relativename']; } print '
    '.$langs->trans("LanguageFile").' '.basename(dirname($pathtofile)).' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; print '
    '; @@ -2226,7 +2263,7 @@ if ($module == 'initmodule') { print '
    '; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; if (is_array($dicts) && !empty($dicts)) { print ' '.$langs->trans("LanguageFile").' : '; @@ -2309,7 +2346,7 @@ if ($module == 'initmodule') { $i++; } } else { - print '
    '.$langs->trans("None").'
    '.$langs->trans("None").'
    '; @@ -2408,8 +2445,8 @@ if ($module == 'initmodule') { print ''.$langs->trans("EnterNameOfObjectDesc").'

    '; print '
    '; - print ' '.$form->textwithpicto($langs->trans("IncludeRefGeneration"), $langs->trans("IncludeRefGenerationHelp")).'
    '; - print ' '.$form->textwithpicto($langs->trans("IncludeDocGeneration"), $langs->trans("IncludeDocGenerationHelp")).'
    '; + print '
    '; + print '
    '; print ''; print '
    '; print '
    '; @@ -2502,13 +2539,13 @@ if ($module == 'initmodule') { print '
    '; print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoclass).($realpathtoclass ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print ' '.$langs->trans("ApiClassFile").' : '.($realpathtoapi ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoapi).($realpathtoapi ? '' : '').''; if (dol_is_file($realpathtoapi)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; print '   '; if (empty($conf->global->$const_name)) { // If module is not activated print ''.$langs->trans("GoToApiExplorer").''; @@ -2517,99 +2554,99 @@ if ($module == 'initmodule') { } } else { //print ''.$langs->trans("FileNotYetGenerated").' '; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; + print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; } // PHPUnit print '
    '; print ' '.$langs->trans("TestClassFile").' : '.($realpathtophpunit ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtophpunit).($realpathtophpunit ? '' : '').''; if (dol_is_file($realpathtophpunit)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; } else { //print ''.$langs->trans("FileNotYetGenerated").' '; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; + print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; } print '
    '; print '
    '; print ' '.$langs->trans("PageForLib").' : '.($realpathtolib ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtolib).($realpathtolib ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print ' '.$langs->trans("PageForObjLib").' : '.($realpathtoobjlib ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoobjlib).($realpathtoobjlib ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print ' '.$langs->trans("Image").' : '.($realpathtopicto ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtopicto).($realpathtopicto ? '' : '').''; - //print ' '.img_picto($langs->trans("Edit"), 'edit').''; + //print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print '
    '; print ' '.$langs->trans("SqlFile").' : '.($realpathtosql ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtosql).($realpathtosql ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print '   '.$langs->trans("DropTableIfEmpty").''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print '   '.$langs->trans("DropTableIfEmpty").''; //print '   '.$langs->trans("RunSql").''; print '
    '; print ' '.$langs->trans("SqlFileKey").' : '.($realpathtosqlkey ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlkey).($realpathtosqlkey ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; //print '   '.$langs->trans("RunSql").''; print '
    '; print ' '.$langs->trans("SqlFileExtraFields").' : '.($realpathtosqlextra ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlextra).($realpathtosqlextra ? '' : '').''; if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; print '   '; - print ''.$langs->trans("DropTableIfEmpty").''; + print ''.$langs->trans("DropTableIfEmpty").''; } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; + print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; } //print '   '.$langs->trans("RunSql").''; print '
    '; print ' '.$langs->trans("SqlFileKeyExtraFields").' : '.($realpathtosqlextrakey ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtosqlextrakey).($realpathtosqlextrakey ? '' : '').''; if (dol_is_file($realpathtosqlextra) && dol_is_file($realpathtosqlextrakey)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; } else { - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; + print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; } print '
    '; print '
    '; print '
    '; print ' '.$langs->trans("PageForList").' : '.($realpathtolist ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtolist).($realpathtolist ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print ' '.$langs->trans("PageForCreateEditView").' : '.($realpathtocard ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtocard).($realpathtocard ? '' : '').'?action=create'; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print ' '.$langs->trans("PageForContactTab").' : '.($realpathtocontact ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtocontact).($realpathtocontact ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; if (dol_is_file($realpathtocontact)) { print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; } print '
    '; print ' '.$langs->trans("PageForDocumentTab").' : '.($realpathtodocument ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtodocument).($realpathtodocument ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; if (dol_is_file($realpathtodocument)) { print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; } print '
    '; print ' '.$langs->trans("PageForNoteTab").' : '.($realpathtonote ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtonote).($realpathtonote ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; if (dol_is_file($realpathtonote)) { print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; } print '
    '; print ' '.$langs->trans("PageForAgendaTab").' : '.($realpathtoagenda ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoagenda).($realpathtoagenda ? '' : '').''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; if (dol_is_file($realpathtoagenda)) { print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; } print '
    '; print '
    '; @@ -2618,6 +2655,7 @@ if ($module == 'initmodule') { print '


    '; + clearstatcache(true); if (function_exists('opcache_invalidate')) { opcache_invalidate($dirread.'/'.$pathtoclass, true); // remove the include cache hell ! } @@ -2804,7 +2842,7 @@ if ($module == 'initmodule') { print ''; print '
    '; - print ''; + print ''; print ''; print ''; @@ -2928,7 +2966,7 @@ if ($module == 'initmodule') { $format = 'markdown'; } print ' '.$langs->trans("SpecificationFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; } } else { @@ -3020,7 +3058,7 @@ if ($module == 'initmodule') { print '
    '; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print '
    '; @@ -3106,7 +3144,7 @@ if ($module == 'initmodule') { print '
    '.$langs->trans("None").'
    '.$langs->trans("None").'
    '; @@ -3153,7 +3191,7 @@ if ($module == 'initmodule') { print '
    '; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print '
    '; @@ -3199,7 +3237,7 @@ if ($module == 'initmodule') { print '
    '.$langs->trans("None").'
    '.$langs->trans("None").'
    '; @@ -3243,7 +3281,7 @@ if ($module == 'initmodule') { print '
    '; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; print ''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; @@ -3252,7 +3290,7 @@ if ($module == 'initmodule') { if (dol_is_file($dirins.'/'.$pathtohook)) { print ''.$pathtohook.''; print ''.img_picto($langs->trans("Edit"), 'edit').' '; + print ''.img_picto($langs->trans("Edit"), 'edit').' '; print ''.img_picto($langs->trans("Delete"), 'delete').'
    '; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; print ''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print ' '.$langs->trans("TriggersFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').'
    '; - print ' '.$langs->trans("NoTrigger"); + print ' '.$langs->trans("TriggersFile"); + print ' : '.$langs->trans("FileNotYetGenerated").''; print ''.img_picto('Generate', 'generate', 'class="paddingleft"').'
    '.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').''.img_picto('Generate', 'generate', 'class="paddingleft"').''.img_picto('Generate', 'generate', 'class="paddingleft"').'
    '.$langs->trans("WidgetFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ''.img_picto($langs->trans("Delete"), 'delete').''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Delete"), 'delete').'
    '.$langs->trans("WidgetFile").' : '.$langs->trans("NoWidget").''; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; + print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; print '
    '; @@ -3502,7 +3541,7 @@ if ($module == 'initmodule') { print '
    '; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; } else { $fullpathoffile = dol_buildpath($file, 0); @@ -3572,13 +3611,13 @@ if ($module == 'initmodule') { $pathtofile = $clifile['relpath']; print '
    '.$langs->trans("CLIFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').''.img_picto($langs->trans("Edit"), 'edit').''.img_picto($langs->trans("Delete"), 'delete').'
    '.$langs->trans("CLIFile").' : '.$langs->trans("FileNotYetGenerated");''; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; + print '
    '.$langs->trans("CLIFile").' : '.$langs->trans("FileNotYetGenerated"); ''; + print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; print '
    '; @@ -3618,7 +3657,7 @@ if ($module == 'initmodule') { print '
    '; print ' '.$langs->trans("DescriptorFile").' : '.$pathtofile.''; - print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '.img_picto($langs->trans("Edit"), 'edit').''; print '
    '; print '
    '; @@ -3696,7 +3735,7 @@ if ($module == 'initmodule') { print '
    '.$langs->trans("None").'
    '.$langs->trans("None").'
    '; @@ -3746,14 +3785,14 @@ if ($module == 'initmodule') { } print ''; print ' '.$langs->trans("SpecificationFile").' : '.$pathtofile.''; - print ''.img_picto($langs->trans("Edit"), 'edit').''; - print ''.img_picto($langs->trans("Delete"), 'delete').''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Delete"), 'delete').''; print ''; } } else { print ''; print ' '.$langs->trans("SpecificationFile").' : '.$langs->trans("FileNotYetGenerated").''; - print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; + print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; print ''; } print ''; diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php index 9007eab60cc..8a9937dfd2f 100644 --- a/htdocs/modulebuilder/template/admin/setup.php +++ b/htdocs/modulebuilder/template/admin/setup.php @@ -354,13 +354,14 @@ if ($action == 'edit') { $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) . '
    '; } - $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"); @@ -389,7 +390,7 @@ if ($action == 'edit') { print ''; print ''; } else { print '
    '.$langs->trans("NothingToSetup"); @@ -598,13 +599,13 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { // Active if (in_array($name, $def)) { print ''."\n"; - print ''; + print ''; print img_picto($langs->trans("Enabled"), 'switch_on'); print ''; print ''; } else { print ''."\n"; - print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print ""; } @@ -614,9 +615,9 @@ foreach ($myTmpObjects as $myTmpObjectKey => $myTmpObjectArray) { if ($conf->global->$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').''; + 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 'scandir).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print ''; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 44ec157f0c8..6e5d6efcff4 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -83,7 +83,7 @@ class MyObject extends CommonObject * '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 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). + * '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 @@ -430,13 +430,13 @@ class MyObject extends CommonObject $records = array(); - $sql = 'SELECT '; + $sql = "SELECT "; $sql .= $this->getFieldList('t'); - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as 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).')'; + $sql .= " WHERE t.entity IN (".getEntity($this->table_element).")"; } else { - $sql .= ' WHERE 1 = 1'; + $sql .= " WHERE 1 = 1"; } // Manage filter $sqlwhere = array(); @@ -767,7 +767,7 @@ class MyObject extends CommonObject if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) { $add_save_lastsearch_values = 1; } - if ($add_save_lastsearch_values) { + if ($url && $add_save_lastsearch_values) { $url .= '&save_lastsearch_values=1'; } } @@ -784,13 +784,13 @@ class MyObject extends CommonObject $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); } - if ($option == 'nolink') { + if ($option == 'nolink' || empty($url)) { $linkstart = ''; - if ($option == 'nolink') { + if ($option == 'nolink' || empty($url)) { $linkend = ''; } else { $linkend = ''; @@ -847,6 +847,17 @@ class MyObject extends CommonObject 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 * @@ -872,12 +883,12 @@ class MyObject extends CommonObject if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("mymodule@mymodule"); - $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Enabled'); - $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); - $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Enabled'); - $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $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; @@ -897,10 +908,11 @@ class MyObject extends CommonObject */ 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)) { @@ -960,7 +972,7 @@ class MyObject extends CommonObject $this->lines = array(); $objectline = new MyObjectLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_myobject = '.$this->id)); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_myobject = '.((int) $this->id))); if (is_numeric($result)) { $this->error = $this->error; diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php index 4e154b5665d..9126da0070d 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/doc_generic_myobject_odt.modules.php @@ -301,11 +301,14 @@ class doc_generic_myobject_odt extends ModelePDFMyObject // Recipient name $contactobject = null; if (!empty($usecontact)) { - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { - $socobject = $object->contact; + // We can use the company of contact instead of thirdparty company + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { + $object->contact->fetch_thirdparty(); + $socobject = $object->contact->thirdparty; + $contactobject = $object->contact; } else { $socobject = $object->thirdparty; - // if we have a CUSTOMER contact and we dont use it as recipient we store the contact object for later use + // if we have a CUSTOMER contact and we dont use it as thirdparty recipient we store the contact object for later use $contactobject = $object->contact; } } else { diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php index 1b95a2a0c20..1a435d3763d 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php @@ -1110,7 +1110,7 @@ class pdf_standard_myobject extends ModelePDFMyObject } // Recipient name - if ($usecontact && ($object->contact->fk_soc != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)))) { + if ($object->contact->socid != $object->thirdparty->id && (!isset($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT) || !empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT))) { $thirdparty = $object->contact; } else { $thirdparty = $object->thirdparty; diff --git a/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php b/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php index 67aac8c0e98..2f0ecd06774 100644 --- a/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php +++ b/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php @@ -22,7 +22,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; @@ -50,7 +50,7 @@ foreach ($linkedObjectBlock as $key => $objectlink) { date, 'day'); ?> getLibStatut(7); ?> - ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> + ">transnoentitiesnoconv("RemoveLink"), 'unlink'); ?> tabs = array( // 'entity:-tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__' //); // to remove a tab - complete_head_from_modules($conf, $langs, null, $head, $h, 'mymodule'); + complete_head_from_modules($conf, $langs, null, $head, $h, 'mymodule@mymodule'); + + complete_head_from_modules($conf, $langs, $object, $head, $h, 'mymodule@mymodule', 'remove'); return $head; } diff --git a/htdocs/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php index c0c98d88e8f..15f3d83ac54 100644 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ b/htdocs/modulebuilder/template/mymoduleindex.php @@ -173,7 +173,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) END MODULEBUILDER DRAFT MYOBJECT */ -print '
    '; +print '
    '; $NBMAX = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; @@ -234,7 +234,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) } */ -print '
    '; +print ''; // End of page llxFooter(); diff --git a/htdocs/modulebuilder/template/myobject_agenda.php b/htdocs/modulebuilder/template/myobject_agenda.php index cc49275e5f8..add786498b2 100644 --- a/htdocs/modulebuilder/template/myobject_agenda.php +++ b/htdocs/modulebuilder/template/myobject_agenda.php @@ -206,7 +206,7 @@ if ($object->id > 0) { $morehtmlref.='
    '.$langs->trans('Project') . ' '; if ($permissiontoadd) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; } $morehtmlref.=' : '; if ($action == 'classify') { diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 87a28615806..43c57ca1f94 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -368,7 +368,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $langs->load("projects"); $morehtmlref .= '
    '.$langs->trans('Project') . ' '; if ($permissiontoadd) { - //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; + //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); @@ -558,7 +558,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; + print '
    '; $MAXEVENT = 10; @@ -571,7 +571,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, $object->element.'@'.$object->module, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); - print '
    '; + print ''; } //Select mail models is same action as presend diff --git a/htdocs/modulebuilder/template/myobject_contact.php b/htdocs/modulebuilder/template/myobject_contact.php index 171ef3aab1d..d2de342c861 100644 --- a/htdocs/modulebuilder/template/myobject_contact.php +++ b/htdocs/modulebuilder/template/myobject_contact.php @@ -171,7 +171,7 @@ if ($object->id) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/modulebuilder/template/myobject_document.php b/htdocs/modulebuilder/template/myobject_document.php index 2db325b8b41..5e8d09db179 100644 --- a/htdocs/modulebuilder/template/myobject_document.php +++ b/htdocs/modulebuilder/template/myobject_document.php @@ -188,7 +188,7 @@ if ($object->id) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 11a55126884..ac4f6be13b8 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -135,7 +135,7 @@ if (!$sortorder) { } // Initialize array of search criterias -$search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'); +$search_all = GETPOST('search_all', 'alphanohtml'); $search = array(); foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { @@ -266,7 +266,7 @@ $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 @@ -432,9 +432,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]); } } @@ -660,7 +662,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { if (!$i) { $totalarray['nbfield']++; } - if (!empty($val['isameasure'])) { + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; } diff --git a/htdocs/modulebuilder/template/myobject_note.php b/htdocs/modulebuilder/template/myobject_note.php index 7f324fbd456..d1c4e4c8837 100644 --- a/htdocs/modulebuilder/template/myobject_note.php +++ b/htdocs/modulebuilder/template/myobject_note.php @@ -162,7 +162,7 @@ if ($id > 0 || !empty($ref)) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/mrp/class/api_mos.class.php b/htdocs/mrp/class/api_mos.class.php index a59a7247338..86d4758b45f 100644 --- a/htdocs/mrp/class/api_mos.class.php +++ b/htdocs/mrp/class/api_mos.class.php @@ -22,7 +22,7 @@ require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php'; /** - * \file mrp/class/api_mo.class.php + * \file htdocs/mrp/class/api_mos.class.php * \ingroup mrp * \brief File for API management of MO. */ @@ -353,6 +353,9 @@ class Mos extends DolibarrApi $stockmove = new MouvementStock($this->db); + $consumptioncomplete = true; + $productioncomplete = true; + if (!empty($arraytoconsume) && !empty($arraytoproduce)) { $pos = 0; $arrayofarrayname = array("arraytoconsume","arraytoproduce"); @@ -382,7 +385,9 @@ class Mos extends DolibarrApi if (!$error && $value["fk_warehouse"] > 0) { // Record stock movement $id_product_batch = 0; - $stockmove->origin = $this->mo; + + $stockmove->setOrigin($this->mo->element, $this->mo->id); + if ($qtytoprocess >= 0) { $moline = new MoLine($this->db); $moline->fk_mo = $this->mo->id; @@ -457,9 +462,6 @@ class Mos extends DolibarrApi } } if (!$error) { - $consumptioncomplete = true; - $productioncomplete = true; - if ($autoclose <= 0) { $consumptioncomplete = false; $productioncomplete = false; @@ -476,20 +478,21 @@ class Mos extends DolibarrApi if (isset($line->fk_warehouse)) { // If there is a warehouse to set if (!($line->fk_warehouse > 0)) { // If there is no warehouse set. $langs->load("errors"); - throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref)); $error++; + throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref)); } if ($tmpproduct->status_batch) { $langs->load("errors"); - throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref)); $error++; + throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref)); } } $idstockmove = 0; if (!$error && $line->fk_warehouse > 0) { // Record stock movement $id_product_batch = 0; - $stockmove->origin = $this->mo; + $stockmove->origin_type = 'mo'; + $stockmove->origin_id = $this->mo->id; if ($qtytoprocess >= 0) { $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); } else { @@ -535,20 +538,21 @@ class Mos extends DolibarrApi if (isset($line->fk_warehouse)) { // If there is a warehouse to set if (!($line->fk_warehouse > 0)) { // If there is no warehouse set. $langs->load("errors"); - throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref)); $error++; + throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref)); } if ($tmpproduct->status_batch) { $langs->load("errors"); - throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref)); $error++; + throw new RestException(500, $langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref)); } } $idstockmove = 0; if (!$error && $line->fk_warehouse > 0) { // Record stock movement $id_product_batch = 0; - $stockmove->origin = $this->mo; + $stockmove->origin_type = 'mo'; + $stockmove->origin_id = $this->mo->id; if ($qtytoprocess >= 0) { $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement, dol_now(), '', '', $tmpproduct->status_batch, $id_product_batch, $codemovement); } else { @@ -586,9 +590,6 @@ class Mos extends DolibarrApi } if (!$error) { - $consumptioncomplete = true; - $productioncomplete = true; - if ($autoclose > 0) { foreach ($this->mo->lines as $line) { if ($line->role == 'toconsume') { @@ -620,6 +621,7 @@ class Mos extends DolibarrApi } } } + // Update status of MO dol_syslog("consumptioncomplete = ".$consumptioncomplete." productioncomplete = ".$productioncomplete); //var_dump("consumptioncomplete = ".$consumptioncomplete." productioncomplete = ".$productioncomplete); @@ -716,7 +718,7 @@ class Mos extends DolibarrApi if (!isset($data[$field])) { throw new RestException(400, "$field field missing"); } - $myobject[$field] = $data[$field]; + $myobject[$field] = $data[$field]; } return $myobject; } diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index f4069bfc518..cdad4e71968 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -625,6 +625,7 @@ class Mo extends CommonObject public function updateProduction(User $user, $notrigger = true) { $error = 0; + $role = ""; if ($this->status != self::STATUS_DRAFT) { $this->error = 'BadStatus'; @@ -659,6 +660,12 @@ class Mo extends CommonObject $role = 'toconsume'; $moline->role = 'toproduce'; } + } else { + if ($this->mrptype == 1) { + $moline->role = 'toconsume'; + } else { + $moline->role = 'toproduce'; + } } $resultline = $moline->create($user, false); // Never use triggers here @@ -1021,9 +1028,9 @@ class Mo extends CommonObject $label .= '
    '.$langs->trans('Label').': '.$this->label; } - $url = dol_buildpath('/mrp/mo_card.php', 1).'?id='.$this->id; + $url = DOL_URL_ROOT.'/mrp/mo_card.php?id='.$this->id; if ($option == 'production') { - $url = dol_buildpath('/mrp/mo_production.php', 1).'?id='.$this->id; + $url = DOL_URL_ROOT.'/mrp/mo_production.php?id='.$this->id; } if ($option != 'nolink') { @@ -1200,7 +1207,7 @@ class Mo extends CommonObject $this->lines = array(); $objectline = new MoLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_mo = '.$this->id)); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_mo = '.((int) $this->id))); if (is_numeric($result)) { $this->error = $this->error; diff --git a/htdocs/mrp/index.php b/htdocs/mrp/index.php index cbb7b5da305..c4480f76ed0 100644 --- a/htdocs/mrp/index.php +++ b/htdocs/mrp/index.php @@ -147,7 +147,7 @@ if ($conf->use_javascript_ajax) { print '
    '; -print '
    '; +print '
    '; /* * Last modified BOM @@ -245,7 +245,7 @@ if ($resql) { dol_print_error($db); } -print '
    '; +print ''; $parameters = array( //'type' => $type, diff --git a/htdocs/mrp/lib/mrp_mo.lib.php b/htdocs/mrp/lib/mrp_mo.lib.php index 8fe07df89c1..08bc07f298a 100644 --- a/htdocs/mrp/lib/mrp_mo.lib.php +++ b/htdocs/mrp/lib/mrp_mo.lib.php @@ -104,5 +104,7 @@ function moPrepareHead($object) //); // to remove a tab complete_head_from_modules($conf, $langs, $object, $head, $h, 'mo@mrp'); + complete_head_from_modules($conf, $langs, $object, $head, $h, 'mo@mrp', 'remove'); + return $head; } diff --git a/htdocs/mrp/mo_agenda.php b/htdocs/mrp/mo_agenda.php index bbd2724fb1c..95dab4e62ab 100644 --- a/htdocs/mrp/mo_agenda.php +++ b/htdocs/mrp/mo_agenda.php @@ -158,7 +158,7 @@ if ($object->id > 0) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($permissiontoadd) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_soc, $object->fk_project, 'projectid', 0, 0, 1, 1); diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index fc8cab806c7..b2c3de8f101 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -199,7 +199,7 @@ $form = new Form($db); $formfile = new FormFile($db); $formproject = new FormProjets($db); -$title = $langs->trans('Mo')." - ".$langs->trans("Card"); +$title = $langs->trans('ManufacturingOrder')." - ".$langs->trans("Card"); llxHeader('', $title, ''); @@ -452,7 +452,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($permissiontoadd) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_soc, $object->fk_project, 'projectid', 0, 0, 1, 1); @@ -609,7 +609,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Modify if ($object->status == $object::STATUS_DRAFT) { if ($permissiontoadd) { - print ''.$langs->trans("Modify").''."\n"; + print ''.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } @@ -688,7 +688,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; + print '
    '; $MAXEVENT = 10; @@ -699,9 +699,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'mo', $socid, 1, '', $MAXEVENT, '', $morehtmlright); + $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlright); - print '
    '; + print ''; } //Select mail models is same action as presend diff --git a/htdocs/mrp/mo_document.php b/htdocs/mrp/mo_document.php index 211fa897c09..c81ed1f995e 100644 --- a/htdocs/mrp/mo_document.php +++ b/htdocs/mrp/mo_document.php @@ -83,12 +83,14 @@ if ($id > 0 || !empty($ref)) { $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); $result = restrictedArea($user, 'mrp', $object->id, 'mrp_mo', '', 'fk_soc', 'rowid', $isdraft); +$permissiontoadd = $user->rights->mrp->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php + /* * Actions */ -include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; +include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles.inc.php /* @@ -134,7 +136,7 @@ if ($object->id) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($permissiontoadd) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_soc, $object->fk_project, 'projectid', 0, 0, 1, 1); diff --git a/htdocs/mrp/mo_list.php b/htdocs/mrp/mo_list.php index 5b4215f91db..e5648cad5f7 100644 --- a/htdocs/mrp/mo_list.php +++ b/htdocs/mrp/mo_list.php @@ -84,7 +84,7 @@ if (!$sortorder) { } // Initialize array of search criterias -$search_all = GETPOST('search_all', 'alphanohtml') ? GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'); +$search_all = GETPOST('search_all', 'alphanohtml'); $search = array(); foreach ($object->fields as $key => $val) { if (GETPOST('search_'.$key, 'alpha') !== '') { @@ -207,7 +207,7 @@ $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 @@ -270,14 +270,13 @@ $sql .= $hookmanager->resPrint; /* If a group by is required $sql.= " GROUP BY "; -foreach($object->fields as $key => $val) -{ +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.', ' : ''); + $sql .= ($extrafields->attributes[$object->table_element]['type'][$key] != 'separate' ? "ef.".$key.", " : ""); } } // Add where from hooks @@ -343,9 +342,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]); } } @@ -566,7 +567,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { if (!$i) { $totalarray['nbfield']++; } - if (!empty($val['isameasure'])) { + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; } diff --git a/htdocs/mrp/mo_movements.php b/htdocs/mrp/mo_movements.php index bab57db22ea..3b1ac109e5d 100644 --- a/htdocs/mrp/mo_movements.php +++ b/htdocs/mrp/mo_movements.php @@ -328,7 +328,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($permissiontoadd) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_soc, $object->fk_project, 'projectid', 0, 0, 1, 1); diff --git a/htdocs/mrp/mo_note.php b/htdocs/mrp/mo_note.php index fd1e2d8cbfa..6fb173c4295 100644 --- a/htdocs/mrp/mo_note.php +++ b/htdocs/mrp/mo_note.php @@ -60,7 +60,7 @@ if ($id > 0 || !empty($ref)) { $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); $result = restrictedArea($user, 'mrp', $object->id, 'mrp_mo', '', 'fk_soc', 'rowid', $isdraft); -$permissionnote = $user->rights->mrp->write; // Used by the include of actions_setnotes.inc.php +$permissionnote = $user->rights->mrp->write; // Used by the include of actions_setnotes.inc.php @@ -112,7 +112,7 @@ if ($id > 0 || !empty($ref)) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($permissiontoadd) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_soc, $object->fk_project, 'projectid', 0, 0, 1, 1); diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index 678865805d7..554ad59cbab 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -38,7 +38,7 @@ dol_include_once('/bom/class/bom.class.php'); dol_include_once('/mrp/lib/mrp_mo.lib.php'); // Load translation files required by the page -$langs->loadLangs(array("mrp", "stocks", "other", "productbatch")); +$langs->loadLangs(array("mrp", "stocks", "other", "product", "productbatch")); // Get parameters $id = GETPOST('id', 'int'); @@ -149,14 +149,19 @@ if (empty($reshook)) { $result = $object->setStatut($object::STATUS_INPROGRESS, 0, '', 'MRP_REOPEN'); } - if ($action == 'confirm_addconsumeline' && GETPOST('addconsumelinebutton') && $permissiontoadd) { + if (($action == 'confirm_addconsumeline' && GETPOST('addconsumelinebutton') && $permissiontoadd) + || ($action == 'confirm_addproduceline' && GETPOST('addproducelinebutton') && $permissiontoadd)) { $moline = new MoLine($db); // Line to produce $moline->fk_mo = $object->id; $moline->qty = GETPOST('qtytoadd', 'int'); ; $moline->fk_product = GETPOST('productidtoadd', 'int'); - $moline->role = 'toconsume'; + if (GETPOST('addconsumelinebutton')) { + $moline->role = 'toconsume'; + } else { + $moline->role = 'toproduce'; + } $moline->origin_type = 'free'; // free consume line $moline->position = 0; @@ -206,7 +211,8 @@ if (empty($reshook)) { if (!$error && GETPOST('idwarehouse-'.$line->id.'-'.$i) > 0) { // Record stock movement $id_product_batch = 0; - $stockmove->origin = $object; + $stockmove->setOrigin($object->element, $object->id); + if ($qtytoprocess >= 0) { $idstockmove = $stockmove->livraison($user, $line->fk_product, GETPOST('idwarehouse-'.$line->id.'-'.$i), $qtytoprocess, 0, $labelmovement, dol_now(), '', '', GETPOST('batch-'.$line->id.'-'.$i), $id_product_batch, $codemovement); } else { @@ -278,7 +284,9 @@ if (empty($reshook)) { if (!$error && GETPOST('idwarehousetoproduce-'.$line->id.'-'.$i) > 0) { // Record stock movement $id_product_batch = 0; - $stockmove->origin = $object; + $stockmove->origin_type = $object->element; + $stockmove->origin_id = $object->id; + $idstockmove = $stockmove->reception($user, $line->fk_product, GETPOST('idwarehousetoproduce-'.$line->id.'-'.$i), $qtytoprocess, $pricetoprocess, $labelmovement, '', '', GETPOST('batchtoproduce-'.$line->id.'-'.$i), dol_now(), $id_product_batch, $codemovement); if ($idstockmove < 0) { $error++; @@ -498,9 +506,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print $formconfirm; - // Object card + // MO file // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
    '; /* @@ -515,7 +523,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($permissiontoadd) { if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; } if ($action == 'classify') { //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_soc, $object->fk_project, 'projectid', 0, 0, 1, 1); @@ -642,7 +650,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
    '; } - if (in_array($action, array('consumeorproduce', 'consumeandproduceall', 'addconsumeline'))) { + if (in_array($action, array('consumeorproduce', 'consumeandproduceall', 'addconsumeline', 'addproduceline'))) { print ''; print ''; print ''; @@ -686,6 +694,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $bom = new Bom($db); $res = $bom->fetch($object->fk_bom); if ($res > 0) { + $bom->calculateCosts(); $bomcost = $bom->unit_cost; } } @@ -696,11 +705,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
    '; print '
    '; - $newlinetext = ''; - if ($object->status != $object::STATUS_PRODUCED && $object->status != $object::STATUS_CANCELED && $action != 'consumeorproduce' && $action != 'consumeandproduceall') { - $newlinetext = ''.$langs->trans("AddNewConsumeLines").''; - } - print load_fiche_titre($langs->trans('Consumption'), '', '', 0, '', '', $newlinetext); + $url = $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addconsumeline&token='.newToken(); + $permissiontoaddaconsumeline = $object->status != $object::STATUS_PRODUCED && $object->status != $object::STATUS_CANCELED && $action != 'consumeorproduce' && $action != 'consumeandproduceall'; + $parameters = array('morecss'=>'reposition'); + $newcardbutton = dolGetButtonTitle($langs->trans('AddNewConsumeLines'), '', 'fa fa-plus-circle size15x', $url, '', $permissiontoaddaconsumeline, $parameters); + + print load_fiche_titre($langs->trans('Consumption'), $newcardbutton, '', 0, '', '', ''); print '
    '; print ''; @@ -721,6 +731,14 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print $langs->trans("Warehouse"); } print ''; + if ($conf->productbatch->enabled) { + // Available + print ''; + } // Lot - serial if ($conf->productbatch->enabled) { print ''; print ''; // Qty print ''; @@ -748,11 +766,14 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; } // Qty already consumed - print ''; + print ''; + if ($conf->stock->enabled) { + print ''; + } // Lot - serial if ($conf->productbatch->enabled) { print ''; @@ -805,6 +826,8 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } } + $bomcost = price2num($bomcost, 'MU'); + $arrayoflines = $object->fetchLinesLinked('consumed', $line->id); $alreadyconsumed = 0; foreach ($arrayoflines as $line2) { @@ -812,9 +835,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } print ''; + // Product print ''; + // Qty print ''; + // Cost price if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) { print ''; } + // Already consumed print ''; - print ''; - if ($conf->productbatch->enabled) { - print ''; // Lot + // Stock + if ($conf->stock->enabled) { + print ''; } + // Lot + if ($conf->productbatch->enabled) { + print ''; + } + // Action delete line if ($permissiontodelete) { - $href = $_SERVER["PHP_SELF"]; - $href .= '?id='.$object->id; - $href .= '&action=deleteline'; - $href .= '&lineid='.$line->id; + $href = $_SERVER["PHP_SELF"].'?id='.((int) $object->id).'&action=deleteline&token='.newToken().'&lineid='.((int) $line->id); print ''; } @@ -883,16 +919,26 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Show detailed of already consumed with js code to collapse foreach ($arrayoflines as $line2) { print ''; + + // Date print ''; + + // Already consumed print ''; + + // Qty print ''; + + // Cost price if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) { print ''; } + + // Warehouse print ''; + + // Stock + if ($conf->stock->enabled) { + print ''; + } + // Lot Batch print ''; + + // Action delete line + if ($permissiontodelete) { + print ''; + } + print ''; } @@ -920,11 +978,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($action == 'consumeorproduce' && !GETPOSTISSET('qty-'.$line->id.'-'.$i)) { $preselected = 0; } - print ''; + + $disable = ''; + if (!empty($conf->global->MRP_NEVER_CONSUME_MORE_THAN_EXPECTED) && ($line->qty - $alreadyconsumed) <= 0) { + $disable = 'disabled'; + } + + // Qty + print ''; + + // Cost if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) { print ''; } + + // Already consumed print ''; + + // Warehouse print ''; + + // Stock + if ($conf->stock->enabled) { + print ''; + } + + // Lot / Batch if ($conf->productbatch->enabled) { - print ''; } + + // Action delete line + if ($permissiontodelete) { + print ''; + } + print ''; } } @@ -962,7 +1046,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
    '; print '
    '; - print load_fiche_titre($langs->trans('Production'), '', ''); + $nblinetoproduce = 0; + foreach ($object->lines as $line) { + if ($line->role == 'toproduce') { + $nblinetoproduce++; + } + } + + $newcardbutton = ''; + $url = $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=addproduceline&token='.newToken(); + $permissiontoaddaproductline = $object->status != $object::STATUS_PRODUCED && $object->status != $object::STATUS_CANCELED && $action != 'consumeorproduce' && $action != 'consumeandproduceall'; + $parameters = array('morecss'=>'reposition'); + if ($nblinetoproduce == 0 || $object->mrptype == 1) { + $newcardbutton = dolGetButtonTitle($langs->trans('AddNewProduceLines'), '', 'fa fa-plus-circle size15x', $url, '', $permissiontoaddaproductline, $parameters); + } + + print load_fiche_titre($langs->trans('Production'), $newcardbutton, '', 0, '', ''); print '
    '; print '
    '; + if ($collapse || in_array($action, array('consumeorproduce', 'consumeandproduceall'))) { + print $langs->trans("Stock"); + } + print ''; @@ -739,7 +757,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''."\n"; print '
    '; - print $form->select_produits('', 'productidtoadd', '', 0, 0, -1, 2, '', 0, array(), 0, '1', 0, 'maxwidth300'); + print $form->select_produits('', 'productidtoadd', '', 0, 0, -1, 2, '', 1, array(), 0, '1', 0, 'maxwidth300'); print ''; // Warehouse - print ''; - print ''; + print ''; + print ''; print '
    '.$tmpproduct->getNomUrl(1); print '
    '.$tmpproduct->label.''; print '
    '; $help = ''; if ($line->qty_frozen) { @@ -826,14 +851,16 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if ($help) { print $form->textwithpicto($line->qty, $help, -1); } else { - print $line->qty; + print price2num($line->qty, 'MS'); } print ''; print price($linecost); print ''; if ($alreadyconsumed) { print ''; } } - print ' '.$alreadyconsumed; + print ' '.price2num($alreadyconsumed, 'MS'); print ''; // Warehouse + // Warehouse + print ''; print ''; + if ($tmpproduct->stock_reel < ($line->qty - $alreadyconsumed)) { + print img_warning($langs->trans('StockTooLow')).' '; + } + print price2num($tmpproduct->stock_reel, 'MS'); // Available + print ''; - print ''; - print img_picto('', "delete"); + print ''; + print img_picto('', 'delete'); print ''; print '
    '; $tmpstockmovement->id = $line2['fk_stock_movement']; print ''.img_picto($langs->trans("StockMovement"), 'movement', 'class="paddingright"').''; print dol_print_date($line2['date'], 'dayhour', 'tzuserrel'); print ''.$line2['qty'].''; if ($line2['fk_warehouse'] > 0) { $result = $tmpwarehouse->fetch($line2['fk_warehouse']); @@ -901,6 +947,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } } print ''; if ($line2['batch'] != '') { @@ -908,6 +960,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print $tmpbatch->getNomUrl(1); } print '
    '; if ($tmpproduct->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { if (empty($line->disable_stock_change)) { @@ -936,16 +1007,29 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } else { print ''.$langs->trans("NoStockChangeOnServices").''; } - // Lot / Batch print ''; + print 'aaa'; if ($tmpproduct->status_batch) { $preselected = (GETPOSTISSET('batch-'.$line->id.'-'.$i) ? GETPOST('batch-'.$line->id.'-'.$i) : ''); - print ''; + print ''; + print $formproduct->selectLotDataList('batch-'.$line->id.'-'.$i, 0, $line->fk_product, '', ''); } print '
    '; @@ -972,9 +1071,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; if ($permissiontoupdatecost) { if (empty($bomcost)) { - print ''; + print ''; } else { - print ''; + print ''; } } print ''; @@ -993,6 +1092,34 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } print ''; + if ($action == 'addproduceline') { + print ''."\n"; + print ''; + print ''; + // Qty + print ''; + // Cost price + print ''; + + // Qty already produced + print ''; + // Lot - serial + if ($conf->productbatch->enabled) { + print ''; + } + // Action + if ($permissiontodelete) { + print ''; + } + print ''; + } + if (!empty($object->lines)) { $nblinetoproduce = 0; foreach ($object->lines as $line) { @@ -1011,10 +1138,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $tmpproduct = new Product($db); $tmpproduct->fetch($line->fk_product); - if (empty($bomcost)) { - $bomcost = $tmpproduct->pmp; - } - $arrayoflines = $object->fetchLinesLinked('produced', $line->id); $alreadyproduced = 0; foreach ($arrayoflines as $line2) { @@ -1033,8 +1156,19 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; print ''; if ($permissiontoupdatecost) { + // Defined $manufacturingcost + $manufacturingcost = $bomcost; + if (empty($manufacturingcost)) { + $manufacturingcost = price2num($tmpproduct->cost_price, 'MU'); + } + if (empty($manufacturingcost)) { + $manufacturingcost = price2num($tmpproduct->pmp, 'MU'); + } + print ''; } print ''; if ($conf->productbatch->enabled) { print ''; // Lot - print ''; + } + + if ($permissiontodelete && $line->origin_type == 'free') { + $href = $_SERVER["PHP_SELF"]; + $href .= '?id='.$object->id; + $href .= '&action=deleteline'; + $href .= '&lineid='.$line->id; + print ''; } print ''; @@ -1115,11 +1260,20 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } print ''; if ($permissiontoupdatecost) { + // Defined $manufacturingcost + $manufacturingcost = $bomcost; + if (empty($manufacturingcost)) { + $manufacturingcost = price2num($tmpproduct->cost_price, 'MU'); + } + if (empty($manufacturingcost)) { + $manufacturingcost = price2num($tmpproduct->pmp, 'MU'); + } + if ($tmpproduct->type == Product::TYPE_PRODUCT || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { - $preselected = (GETPOSTISSET('pricetoproduce-'.$line->id.'-'.$i) ? GETPOST('pricetoproduce-'.$line->id.'-'.$i) : price($bomcost)); + $preselected = (GETPOSTISSET('pricetoproduce-'.$line->id.'-'.$i) ? GETPOST('pricetoproduce-'.$line->id.'-'.$i) : price($manufacturingcost)); print ''; } else { - print ''; + print ''; } } print ''; diff --git a/htdocs/mrp/tpl/linkedobjectblock.tpl.php b/htdocs/mrp/tpl/linkedobjectblock.tpl.php new file mode 100644 index 00000000000..5dbe583fd21 --- /dev/null +++ b/htdocs/mrp/tpl/linkedobjectblock.tpl.php @@ -0,0 +1,82 @@ + + * Copyright (C) 2013 Juanjo Menent + * Copyright (C) 2014 Marcos García + * Copyright (C) 2013-2020 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 + * 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, $db; +global $noMoreLinkedObjectBlockAfter; + +$langs = $GLOBALS['langs']; +$linkedObjectBlock = $GLOBALS['linkedObjectBlock']; + +// Load translation files required by the page +$langs->load("bom"); + +$linkedObjectBlock = dol_sort_array($linkedObjectBlock, 'date', 'desc', 0, 0, 1); + +$total = 0; +$ilink = 0; +foreach ($linkedObjectBlock as $key => $objectlink) { + $ilink++; + $product_static = new Product($db); + $trclass = 'oddeven'; + if ($ilink == count($linkedObjectBlock) && empty($noMoreLinkedObjectBlockAfter) && count($linkedObjectBlock) <= 1) { + $trclass .= ' liste_sub_total'; + } + echo ''; + echo ''; + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo "\n"; +} + +echo "\n"; diff --git a/htdocs/multicurrency/class/multicurrency.class.php b/htdocs/multicurrency/class/multicurrency.class.php index a811a396811..0dc9f7ce63a 100644 --- a/htdocs/multicurrency/class/multicurrency.class.php +++ b/htdocs/multicurrency/class/multicurrency.class.php @@ -133,7 +133,7 @@ class MultiCurrency extends CommonObject $now = dol_now(); // Insert request - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'('; + $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element."("; $sql .= ' code,'; $sql .= ' name,'; $sql .= ' entity,'; @@ -194,7 +194,7 @@ class MultiCurrency extends CommonObject global $conf; - $sql = 'SELECT'; + $sql = "SELECT"; $sql .= ' c.rowid, c.name, c.code, c.entity, c.date_create, c.fk_user'; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' AS c'; if (!empty($code)) { @@ -243,7 +243,7 @@ class MultiCurrency extends CommonObject */ public function fetchAllCurrencyRate() { - $sql = 'SELECT cr.rowid'; + $sql = "SELECT cr.rowid"; $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as cr'; $sql .= ' WHERE cr.fk_multicurrency = '.((int) $this->id); $sql .= ' ORDER BY cr.date_sync DESC'; @@ -298,10 +298,10 @@ class MultiCurrency extends CommonObject } // Update request - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET'; - $sql .= ' name=\''.$this->db->escape($this->name).'\''; - $sql .= ' code=\''.$this->db->escape($this->code).'\''; - $sql .= ' WHERE rowid='.((int) $this->id); + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; + $sql .= " name = '".$this->db->escape($this->name)."'"; + $sql .= " code = '".$this->db->escape($this->code)."'"; + $sql .= " WHERE rowid = ".((int) $this->id); $this->db->begin(); @@ -362,8 +362,8 @@ class MultiCurrency extends CommonObject dol_syslog('Currency::delete '.join(',', $this->errors), LOG_ERR); } - $sql = 'DELETE FROM '.MAIN_DB_PREFIX.$this->table_element; - $sql .= ' WHERE rowid='.((int) $this->id); + $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element; + $sql .= " WHERE rowid = ".((int) $this->id); dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); @@ -432,17 +432,17 @@ class MultiCurrency extends CommonObject */ public function addRateFromDolibarr($code, $rate) { - global $db, $user; + global $user; $currency = new MultiCurrency($this->db); $currency->code = $code; $currency->name = $code; - $sql = 'SELECT label FROM '.MAIN_DB_PREFIX."c_currencies WHERE code_iso = '".$this->db->escape($code)."'"; + $sql = "SELECT label FROM ".MAIN_DB_PREFIX."c_currencies WHERE code_iso = '".$this->db->escape($code)."'"; dol_syslog(__METHOD__, LOG_DEBUG); - $resql = $db->query($sql); - if ($resql && ($line = $db->fetch_object($resql))) { + $resql = $this->db->query($sql); + if ($resql && ($line = $this->db->fetch_object($resql))) { $currency->name = $line->label; } @@ -477,8 +477,8 @@ class MultiCurrency extends CommonObject */ public function getRate() { - $sql = 'SELECT cr.rowid'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line.' as cr'; + $sql = "SELECT cr.rowid"; + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element_line." as cr"; $sql .= " WHERE cr.fk_multicurrency = ".((int) $this->id); $sql .= " AND cr.date_sync = (SELECT MAX(cr2.date_sync) FROM ".MAIN_DB_PREFIX.$this->table_element_line." AS cr2 WHERE cr2.fk_multicurrency = ".((int) $this->id).")"; @@ -502,7 +502,7 @@ class MultiCurrency extends CommonObject { global $conf; - $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX."multicurrency WHERE code = '".$db->escape($code)."' AND entity = ".$conf->entity; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."multicurrency WHERE code = '".$db->escape($code)."' AND entity = ".$conf->entity; dol_syslog(__METHOD__, LOG_DEBUG); $resql = $db->query($sql); @@ -521,13 +521,13 @@ class MultiCurrency extends CommonObject * @param integer $date_document Date from document (propal, order, invoice, ...) * * @return array [0] => id currency - * [1] => rate + * [1] => rate */ public static function getIdAndTxFromCode($db, $code, $date_document = '') { global $conf; - $sql1 = 'SELECT m.rowid, mc.rate FROM '.MAIN_DB_PREFIX.'multicurrency m'; + $sql1 = "SELECT m.rowid, mc.rate FROM ".MAIN_DB_PREFIX."multicurrency m"; $sql1 .= ' LEFT JOIN '.MAIN_DB_PREFIX.'multicurrency_rate mc ON (m.rowid = mc.fk_multicurrency)'; $sql1 .= " WHERE m.code = '".$db->escape($code)."'"; @@ -537,7 +537,7 @@ class MultiCurrency extends CommonObject $tmparray = dol_getdate($date_document); $sql2 .= " AND mc.date_sync <= '".$db->idate(dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year'], true))."'"; } - $sql3 = ' ORDER BY mc.date_sync DESC LIMIT 1'; + $sql3 = " ORDER BY mc.date_sync DESC LIMIT 1"; dol_syslog(__METHOD__, LOG_DEBUG); $resql = $db->query($sql1.$sql2.$sql3); @@ -591,7 +591,7 @@ class MultiCurrency extends CommonObject { global $db; - $sql = 'SELECT multicurrency_tx FROM '.MAIN_DB_PREFIX.$table.' WHERE rowid = '.((int) $fk_facture); + $sql = "SELECT multicurrency_tx FROM ".MAIN_DB_PREFIX.$table." WHERE rowid = ".((int) $fk_facture); dol_syslog(__METHOD__, LOG_DEBUG); $resql = $db->query($sql); @@ -643,13 +643,12 @@ class MultiCurrency extends CommonObject include_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; - $urlendpoint = 'http://apilayer.net/api/live?access_key='.$key; - //$urlendpoint.='&format=1'; - $urlendpoint .= (empty($conf->global->MULTICURRENCY_APP_SOURCE) ? '' : '&source='.$conf->global->MULTICURRENCY_APP_SOURCE); + $urlendpoint = 'http://api.currencylayer.com/live?access_key='.$key; + $urlendpoint .= '&source=' . (empty($conf->global->MULTICURRENCY_APP_SOURCE) ? 'USD' : $conf->global->MULTICURRENCY_APP_SOURCE); dol_syslog("Call url endpoint ".$urlendpoint); - $resget = getURLContent($urlendpoint, 'GET', '', 1, array(), array('http', 'https'), 1); + $resget = getURLContent($urlendpoint); if ($resget['content']) { $response = $resget['content']; @@ -687,12 +686,10 @@ class MultiCurrency extends CommonObject * @param string $code current code to search * @return boolean True if exists, false if not exists */ - public static function checkCodeAlreadyExists($code) + public function checkCodeAlreadyExists($code) { - global $db; - - $currency = new MultiCurrency($db); - if ($currency->fetch('', $code) > 0) { + $currencytmp = new MultiCurrency($this->db); + if ($currencytmp->fetch('', $code) > 0) { return true; } else { return false; @@ -775,7 +772,7 @@ class CurrencyRate extends CommonObjectLine $now = empty($this->date_sync) ? dol_now() : $this->date_sync; // Insert request - $sql = 'INSERT INTO '.MAIN_DB_PREFIX.$this->table_element.'('; + $sql = "INSERT INTO ".MAIN_DB_PREFIX.$this->table_element."("; $sql .= ' rate,'; $sql .= ' date_sync,'; $sql .= ' fk_multicurrency,'; @@ -831,9 +828,9 @@ class CurrencyRate extends CommonObjectLine { dol_syslog('CurrencyRate::fetch', LOG_DEBUG); - $sql = 'SELECT cr.rowid, cr.rate, cr.date_sync, cr.fk_multicurrency, cr.entity'; - $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' AS cr'; - $sql .= ' WHERE cr.rowid = '.((int) $id); + $sql = "SELECT cr.rowid, cr.rate, cr.date_sync, cr.fk_multicurrency, cr.entity"; + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." AS cr"; + $sql .= " WHERE cr.rowid = ".((int) $id); dol_syslog(__METHOD__, LOG_DEBUG); $resql = $this->db->query($sql); @@ -880,15 +877,15 @@ class CurrencyRate extends CommonObjectLine $this->rate = price2num($this->rate); // Update request - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= "SET rate =".((float) $this->rate); + $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; + $sql .= "SET rate = ".((float) $this->rate); if (!empty($this->date_sync)) { - $sql .= ", date_sync='".$this->db->idate($this->date_sync)."'"; + $sql .= ", date_sync = '".$this->db->idate($this->date_sync)."'"; } if (!empty($this->fk_multicurrency)) { - $sql .= ', fk_multicurrency='.((int) $this->fk_multicurrency); + $sql .= ', fk_multicurrency = '.((int) $this->fk_multicurrency); } - $sql .= ' WHERE rowid='.((int) $this->id); + $sql .= " WHERE rowid =".((int) $this->id); $this->db->begin(); diff --git a/htdocs/multicurrency/multicurrency_rate.php b/htdocs/multicurrency/multicurrency_rate.php index 35b7544ccbc..36a6af12750 100644 --- a/htdocs/multicurrency/multicurrency_rate.php +++ b/htdocs/multicurrency/multicurrency_rate.php @@ -479,7 +479,7 @@ if ($resql) { // var_dump($obj); print ' '; print ''; - print ' '; + print ' '; print ''; diff --git a/htdocs/opensurvey/card.php b/htdocs/opensurvey/card.php index db3f54901b9..773571b7b1c 100644 --- a/htdocs/opensurvey/card.php +++ b/htdocs/opensurvey/card.php @@ -156,14 +156,16 @@ if (empty($reshook)) { } // Delete comment - $idcomment = GETPOST('deletecomment', 'int'); - if ($idcomment) { - // Security check - if (!$user->rights->opensurvey->write) { - accessforbidden(); - } + if ($action == 'deletecomment') { + $idcomment = GETPOST('idcomment', 'int'); + if ($idcomment > 0) { + // Security check + if (!$user->rights->opensurvey->write) { + accessforbidden(); + } - $resql = $object->deleteComment($idcomment); + $resql = $object->deleteComment($idcomment); + } } if ($action == 'edit') { @@ -220,20 +222,21 @@ dol_banner_tab($object, 'id', $linkback, 1, 'id_sondage', 'id_sondage', $morehtm print '
    '; -print '
    '; +print '
    '; +print '
    '; print '
    '.$langs->trans("Qty").''.$langs->trans("PMPValue").''.$form->textwithpicto($langs->trans("UnitCost"), $langs->trans("AmountUsedToUpdateWAP")).''.$langs->trans("UnitCost").''.$form->textwithpicto($langs->trans("ManufacturingPrice"), $langs->trans("AmountUsedToUpdateWAP")).''.$langs->trans("QtyAlreadyProduced").'
    '; + print $form->select_produits('', 'productidtoadd', '', 0, 0, -1, 2, '', 1, array(), 0, '1', 0, 'maxwidth300'); + print ''; + // Warehouse + print ''; + print ''; + print '
    '.$line->qty.''; - print price($bomcost); + if ($manufacturingcost) { + print price($manufacturingcost); + } print ''; @@ -1065,7 +1199,18 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print ''; + print ''; + print img_picto('', "delete"); + print ''; + print '
    '.$langs->trans("ManufacturingOrder"); + if (!empty($showImportButton) && $conf->global->MAIN_ENABLE_IMPORT_LINKED_OBJECT_LINES) { + print ' '; + echo ''.$objectlink->getNomUrl(1).''; + $result = $product_static->fetch($objectlink->fk_product); + if ($result < 0) { + setEventMessage($product_static->error, 'errors'); + } elseif ($result > 0) { + $product_static->getNomUrl(1); + } + print ''.dol_print_date($objectlink->date_creation, 'day').''; + if ($user->rights->commande->lire) { + $total = $total + $objectlink->total_ht; + echo price($objectlink->total_ht); + } + echo ''.$objectlink->getLibStatut(3).''; + // For now, shipments must stay linked to order, so link is not deletable + if ($object->element != 'shipping') { + echo ''.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').''; + } + echo '
    ' . $form->selectMultiCurrency($obj->code, 'multicurrency_code', 1, " code != '".$conf->currency."'", true) . ''; print ''; @@ -526,8 +526,8 @@ if ($resql) { if (in_array($obj->rowid, $arrayofselected)) { $selected = 1; } - print 'rowid.'">'.img_picto('edit', 'edit').''; - print 'rowid.'">'.img_picto('delete', 'delete').''; + print 'rowid.'">'.img_picto('edit', 'edit').''; + print 'rowid.'">'.img_picto('delete', 'delete').''; print ''; } print '
    '; // Type $type = ($object->format == "A") ? 'classic' : 'date'; -print ''; // Title print ''; // Description -print ''; -// EMail -//If linked user, then emails are going to be sent to users' email -if (!$object->fk_user_creat) { - print ''; -} - // Receive an email with each vote -print ''; // Users can comment -print ''; // Users can see others vote -print ''; +print '
    '.$langs->trans("Type").''; +print '
    '.$langs->trans("Type").''; print img_picto('', dol_buildpath('/opensurvey/img/'.($type == 'classic' ? 'chart-32.png' : 'calendar-32.png'), 1), 'width="16"', 1); print ' '.$langs->trans($type == 'classic' ? "TypeClassic" : "TypeDate").'
    '; $adresseadmin = $object->mail_admin; -print $langs->trans("Title").''; +print $langs->trans("Title").''; if ($action == 'edit') { print ''; } else { @@ -242,7 +245,7 @@ if ($action == 'edit') { print '
    '.$langs->trans("Description").''; +print '
    '.$langs->trans("Description").''; if ($action == 'edit') { $doleditor = new DolEditor('nouveauxcommentaires', $object->description, '', 120, 'dolibarr_notes', 'In', 1, 1, 1, ROWS_7, '90%'); $doleditor->Create(0, ''); @@ -251,20 +254,8 @@ if ($action == 'edit') { } print '
    '.$langs->trans("EMail").''; - if ($action == 'edit') { - print ''; - } else { - print dol_print_email($object->mail_admin, 0, 0, 1); - } - print '
    '.$langs->trans('ToReceiveEMailForEachVote').''; +print '
    '.$langs->trans('ToReceiveEMailForEachVote').''; if ($action == 'edit') { print 'mailsonde ? 'checked="checked"' : '').'">'; } else { @@ -280,7 +271,7 @@ if ($action == 'edit') { print '
    '.$langs->trans('CanComment').''; +print '
    '.$langs->trans('CanComment').''; if ($action == 'edit') { print 'allow_comments ? 'checked="checked"' : '').'">'; } else { @@ -289,7 +280,7 @@ if ($action == 'edit') { print '
    '.$langs->trans('CanSeeOthersVote').''; +print '
    '.$langs->trans('CanSeeOthersVote').''; if ($action == 'edit') { print 'allow_spy ? 'checked="checked"' : '').'">'; } else { @@ -297,8 +288,16 @@ if ($action == 'edit') { } print '
    '; + +print '
    '; +print '
    '; +print '
    '; + +print ''; + // Expire date -print ''; // Author print ''; // Link -print ''; print '
    '.$langs->trans('ExpireDate').''; +print '
    '.$langs->trans('ExpireDate').''; if ($action == 'edit') { print $form->selectDate($expiredate ? $expiredate : $object->date_fin, 'expire', 0, 0, 0, '', 1, 0); } else { @@ -311,16 +310,20 @@ print '
    '; -print $langs->trans("Author").''; -if ($object->fk_user_creat) { +print $langs->trans("Author").''; +if ($object->fk_user_creat > 0) { print $userstatic->getLoginUrl(1); } else { - print dol_htmlentities($object->nom_admin); + if ($action == 'edit') { + print ''; + } else { + print dol_print_email($object->mail_admin, 0, 0, 1, 0, 1, 1); + } } print '
    '.img_picto('', 'globe').' '.$langs->trans("UrlForSurvey", '').''; +print '
    '.$langs->trans("UrlForSurvey", '').''; // Define $urlwithroot $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); @@ -328,16 +331,18 @@ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domai //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current $url = $urlwithroot.'/public/opensurvey/studs.php?sondage='.$object->id_sondage; -print ''; +print ''; if ($action != 'edit') { - print ajax_autoselect("opensurveyurl", $url); + print ajax_autoselect("opensurveyurl", $url, 'image'); } print '
    '; +print '
    '; print '
    '; +print '
    '; print dol_get_fiche_end(); @@ -356,32 +361,35 @@ print '
    '; if ($action != 'edit' && $user->rights->opensurvey->write) { //Modify button - print ''.$langs->trans("Modify").''; + print ''.$langs->trans("Modify").''; if ($object->status == Opensurveysondage::STATUS_VALIDATED) { //Close button - print ''.$langs->trans("Close").''; + print ''.$langs->trans("Close").''; } if ($object->status == Opensurveysondage::STATUS_CLOSED) { //Opened button - print ''.$langs->trans("ReOpen").''; + print ''.$langs->trans("ReOpen").''; } //Delete button - print ''.$langs->trans('Delete').''; + print ''.$langs->trans('Delete').''; } print '
    '; if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?&id='.$numsondage, $langs->trans("RemovePoll"), $langs->trans("ConfirmRemovalOfPoll", $id), 'delete_confirm', '', '', 1); + print $form->formconfirm($_SERVER["PHP_SELF"].'?&id='.urlencode($numsondage), $langs->trans("RemovePoll"), $langs->trans("ConfirmRemovalOfPoll", $id), 'delete_confirm', '', '', 1); } -print ''."\n"; +print ''."\n"; print ''; +print ''; +print ''; +print ''; print load_fiche_titre($langs->trans("CommentsOfVoters"), '', ''); @@ -391,7 +399,7 @@ $comments = $object->getComments(); if ($comments) { foreach ($comments as $comment) { if ($user->rights->opensurvey->write) { - print ' '.img_picto('', 'delete.png', '', false, 0, 0, '', '', 0).' '; + print ' '.img_picto('', 'delete.png', '', false, 0, 0, '', '', 0).' '; } print dol_htmlentities($comment->usercomment).': '.dol_nl2br(dol_htmlentities($comment->comment))."
    "; @@ -407,10 +415,7 @@ if ($object->allow_comments) { print $langs->trans("AddACommentForPoll").'
    '; print '
    '."\n"; print $langs->trans("Name").': '."\n"; - print '
    '."\n"; - if (isset($erreur_commentaire_vide) && $erreur_commentaire_vide == "yes") { - print "".$langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Name")).""; - } + print '
    '."\n"; } print ''; diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php index e35abff84bb..5888ddf3ec8 100644 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -652,12 +652,12 @@ class Opensurveysondage extends CommonObject if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("mymodule"); - $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Opened'); - $this->labelStatus[self::STATUS_CLOSED] = $langs->trans('Closed'); - $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Opened'); - $this->labelStatusShort[self::STATUS_CLOSED] = $langs->trans('Closed'); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Opened'); + $this->labelStatus[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Closed'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Opened'); + $this->labelStatusShort[self::STATUS_CLOSED] = $langs->transnoentitiesnoconv('Closed'); } $statusType = 'status'.$status; diff --git a/htdocs/opensurvey/css/style.css b/htdocs/opensurvey/css/style.css index 409b64dddf5..e7f0d279a14 100644 --- a/htdocs/opensurvey/css/style.css +++ b/htdocs/opensurvey/css/style.css @@ -342,6 +342,13 @@ div.cadre table.resultats { td.nom { min-width: 160px; } +@media only screen and (max-width: 767px) +{ + td.nom { + min-width: 100px; + } +} + td.vide { min-width: 60px; } diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php index 3dc42def482..b05abe3fd40 100644 --- a/htdocs/opensurvey/list.php +++ b/htdocs/opensurvey/list.php @@ -107,7 +107,8 @@ $arrayfields = dol_sort_array($arrayfields, 'position'); $permissiontoread = $user->rights->opensurvey->read; $permissiontoadd = $user->rights->opensurvey->write; -$permissiontodelete = $user->rights->opensurvey->delete; +// permission delete doesn't exists +$permissiontodelete = $user->rights->opensurvey->write; /* diff --git a/htdocs/opensurvey/results.php b/htdocs/opensurvey/results.php index ff5198c006a..e37f9bf3de5 100644 --- a/htdocs/opensurvey/results.php +++ b/htdocs/opensurvey/results.php @@ -455,20 +455,21 @@ dol_banner_tab($object, 'id', $linkback, 1, 'id_sondage', 'id_sondage', $morehtm print '
    '; -print '
    '; +print '
    '; +print '
    '; print ''; // Type $type = ($object->format == "A") ? 'classic' : 'date'; -print ''; // Title print ''; +// Description +print ''; + +// EMail +//If linked user, then emails are going to be sent to users' email +if (!$object->fk_user_creat) { + print ''; +} + +print '
    '.$langs->trans("Type").''; +print '
    '.$langs->trans("Type").''; print img_picto('', dol_buildpath('/opensurvey/img/'.($type == 'classic' ? 'chart-32.png' : 'calendar-32.png'), 1), 'width="16"', 1); print ' '.$langs->trans($type == 'classic' ? "TypeClassic" : "TypeDate").'
    '; $adresseadmin = $object->mail_admin; -print $langs->trans("Title").''; +print $langs->trans("Title").''; if ($action == 'edit') { print ''; } else { @@ -476,8 +477,39 @@ if ($action == 'edit') { } print '
    '.$langs->trans("Description").''; +if ($action == 'edit') { + $doleditor = new DolEditor('nouveauxcommentaires', $object->description, '', 120, 'dolibarr_notes', 'In', 1, 1, 1, ROWS_7, '90%'); + $doleditor->Create(0, ''); +} else { + print (dol_textishtml($object->description) ? $object->description : dol_nl2br($object->description, 1, true)); +} +print '
    '.$langs->trans("EMail").''; + if ($action == 'edit') { + print ''; + } else { + print dol_print_email($object->mail_admin, 0, 0, 1, 0, 1, 1); + } + print '
    '; + +print '
    '; +print '
    '; +print '
    '; + +print ''; + + // Expire date -print ''; // Author print ''; // Link -print ''; print '
    '.$langs->trans('ExpireDate').''; +print '
    '.$langs->trans('ExpireDate').''; if ($action == 'edit') { print $form->selectDate($expiredate ? $expiredate : $object->date_fin, 'expire', 0, 0, 0, '', 1, 0); } else { @@ -490,7 +522,7 @@ print '
    '; -print $langs->trans("Author").''; +print $langs->trans("Author").''; if ($object->fk_user_creat) { print $userstatic->getLoginUrl(1); } else { @@ -499,7 +531,7 @@ if ($object->fk_user_creat) { print '
    '.img_picto('', 'globe').' '.$langs->trans("UrlForSurvey", '').''; +print '
    '.$langs->trans("UrlForSurvey", '').''; // Define $urlwithroot $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); @@ -507,22 +539,19 @@ $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domai //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current $url = $urlwithouturlroot.dol_buildpath('/public/opensurvey/studs.php', 1).'?sondage='.$object->id_sondage; -$urllink = ''; +$urllink = ''; print $urllink; if ($action != 'edit') { - print ''; - print ' '.$langs->trans("Link").''; + print ajax_autoselect("opensurveyurl", $url, 'image'); } print '
    '; +print '
    '; print '
    '; +print '
    '; print dol_get_fiche_end(); @@ -635,7 +664,7 @@ $nbcolonnes = substr_count($object->sujet, ',') + 1; print '
    '."\n"; print ''; -print '
    '."\n"; +print '
    '."\n"; // Start to show survey result print ''."\n"; @@ -1007,7 +1036,7 @@ if (empty($testligneamodifier)) { print ''."\n"; print ''."\n"; print ''."\n"; for ($i = 0; $i < $nbcolonnes; $i++) { diff --git a/htdocs/opensurvey/wizard/create_survey.php b/htdocs/opensurvey/wizard/create_survey.php index 30e662be7ea..6ed1f2073d2 100644 --- a/htdocs/opensurvey/wizard/create_survey.php +++ b/htdocs/opensurvey/wizard/create_survey.php @@ -170,7 +170,7 @@ if ($_SESSION["mailsonde"]) { $cochemail = "checked"; } -print ' '.$langs->trans("ToReceiveEMailForEachVote").'
    '."\n"; +print '
    '."\n"; if ($_SESSION['allow_comments']) { $allow_comments = 'checked'; @@ -178,7 +178,7 @@ if ($_SESSION['allow_comments']) { if (GETPOSTISSET('allow_comments')) { $allow_comments = GETPOST('allow_comments') ? 'checked' : ''; } -print ' '.$langs->trans('CanComment').'
    '."\n"; +print '
    '."\n"; if ($_SESSION['allow_spy']) { $allow_spy = 'checked'; @@ -186,7 +186,7 @@ if ($_SESSION['allow_spy']) { if (GETPOSTISSET('allow_spy')) { $allow_spy = GETPOST('allow_spy') ? 'checked' : ''; } -print ' '.$langs->trans('CanSeeOthersVote').'
    '."\n"; +print '
    '."\n"; if (GETPOST('choix_sondage')) { if (GETPOST('choix_sondage') == 'date') { diff --git a/htdocs/partnership/admin/website.php b/htdocs/partnership/admin/website.php new file mode 100644 index 00000000000..96ebb4ba6e9 --- /dev/null +++ b/htdocs/partnership/admin/website.php @@ -0,0 +1,258 @@ + + * Copyright (C) 2006-2015 Laurent Destailleur + * Copyright (C) 2006-2012 Regis Houssin + * Copyright (C) 2011 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 + * 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/partnership/admin/website.php + * \ingroup partnership + * \brief File of main public page for partnership module + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/member.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/partnership/lib/partnership.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php'; + +// Load translation files required by the page +$langs->loadLangs(array("admin", "partnership")); + +$action = GETPOST('action', 'aZ09'); + +if (!$user->admin) { + accessforbidden(); +} + +$error = 0; + + +/* + * Actions + */ + +if ($action == 'setPARTNERSHIP_ENABLE_PUBLIC') { + if (GETPOST('value')) { + dolibarr_set_const($db, 'PARTNERSHIP_ENABLE_PUBLIC', 1, 'chaine', 0, '', $conf->entity); + } else { + dolibarr_set_const($db, 'PARTNERSHIP_ENABLE_PUBLIC', 0, 'chaine', 0, '', $conf->entity); + } +} + +if ($action == 'update') { + $public = GETPOST('PARTNERSHIP_ENABLE_PUBLIC'); + + $res = dolibarr_set_const($db, "PARTNERSHIP_ENABLE_PUBLIC", $public, 'chaine', 0, '', $conf->entity); + + if (!($res > 0)) { + $error++; + } + + if (!$error) { + setEventMessages($langs->trans("SetupSaved"), null, 'mesgs'); + } else { + setEventMessages($langs->trans("Error"), null, 'errors'); + } +} + + +/* + * View + */ + +$form = new Form($db); + +//$help_url = 'EN:Module_Partnership|FR:Module_Adhérents|ES:Módulo_Miembros'; +llxHeader('', $langs->trans("PartnershipsSetup"), $help_url); + + +$linkback = ''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("PartnershipsSetup"), $linkback, 'title_setup'); + +$head = partnershipAdminPrepareHead(); + + + +print ''; +print ''; +print ''; + +print dol_get_fiche_head($head, 'website', $langs->trans("Partnerships"), -1, 'user'); + +if ($conf->use_javascript_ajax) { + print "\n".''."\n"; +} + + +print ''.$langs->trans("BlankSubscriptionFormDesc").'

    '; + +$param = ''; + +$enabledisablehtml = $langs->trans("EnablePublicSubscriptionForm").' '; +if (empty($conf->global->PARTNERSHIP_ENABLE_PUBLIC)) { + // Button off, click to enable + $enabledisablehtml .= ''; + $enabledisablehtml .= img_picto($langs->trans("Disabled"), 'switch_off'); + $enabledisablehtml .= ''; +} else { + // Button on, click to disable + $enabledisablehtml .= ''; + $enabledisablehtml .= img_picto($langs->trans("Activated"), 'switch_on'); + $enabledisablehtml .= ''; +} +print $enabledisablehtml; +print ''; + + +print '
    '; + +if (!empty($conf->global->PARTNERSHIP_ENABLE_PUBLIC)) { + print '
    '; + + print '
    '; + print '
    '."\n"; - print ''."\n"; + print ''."\n"; print '
    '; + + print ''; + print ''; + print ''; + print "\n"; + + // Force Type + $adht = new AdherentType($db); + print '\n"; + + // Force nature of member (mor/phy) + $morphys["phy"] = $langs->trans("Physical"); + $morphys["mor"] = $langs->trans("Moral"); + print '\n"; + + // Amount + print '\n"; + + // Can edit + print '\n"; + + // Jump to an online payment page + print '\n"; + + print '
    '.$langs->trans("Parameter").''.$langs->trans("Value").'
    '; + print $langs->trans("ForceMemberType"); + print ''; + $listofval = array(); + $listofval += $adht->liste_array(1); + $forcetype = empty($conf->global->PARTNERSHIP_NEWFORM_FORCETYPE) ? -1 : $conf->global->PARTNERSHIP_NEWFORM_FORCETYPE; + print $form->selectarray("PARTNERSHIP_NEWFORM_FORCETYPE", $listofval, $forcetype, count($listofval) > 1 ? 1 : 0); + print "
    '; + print $langs->trans("ForceMemberNature"); + print ''; + $forcenature = empty($conf->global->PARTNERSHIP_NEWFORM_FORCEMORPHY) ? 0 : $conf->global->PARTNERSHIP_NEWFORM_FORCEMORPHY; + print $form->selectarray("PARTNERSHIP_NEWFORM_FORCEMORPHY", $morphys, $forcenature, 1); + print "
    '; + print $langs->trans("DefaultAmount"); + print ''; + print ''; + print "
    '; + print $langs->trans("CanEditAmount"); + print ''; + print $form->selectyesno("PARTNERSHIP_NEWFORM_EDITAMOUNT", (!empty($conf->global->PARTNERSHIP_NEWFORM_EDITAMOUNT) ? $conf->global->PARTNERSHIP_NEWFORM_EDITAMOUNT : 0), 1); + print "
    '; + print $langs->trans("PARTNERSHIP_NEWFORM_PAYONLINE"); + print ''; + $listofval = array(); + $listofval['-1'] = $langs->trans('No'); + $listofval['all'] = $langs->trans('Yes').' ('.$langs->trans("VisitorCanChooseItsPaymentMode").')'; + if (!empty($conf->paybox->enabled)) { + $listofval['paybox'] = 'Paybox'; + } + if (!empty($conf->paypal->enabled)) { + $listofval['paypal'] = 'PayPal'; + } + if (!empty($conf->stripe->enabled)) { + $listofval['stripe'] = 'Stripe'; + } + print $form->selectarray("PARTNERSHIP_NEWFORM_PAYONLINE", $listofval, (!empty($conf->global->PARTNERSHIP_NEWFORM_PAYONLINE) ? $conf->global->PARTNERSHIP_NEWFORM_PAYONLINE : ''), 0); + print "
    '; + print '
    '; + + print '
    '; + print ''; + print '
    '; +} + + +print dol_get_fiche_end(); + +print ''; + + +if (!empty($conf->global->PARTNERSHIP_ENABLE_PUBLIC)) { + print '
    '; + //print $langs->trans('FollowingLinksArePublic').'
    '; + print img_picto('', 'globe').' '.$langs->trans('BlankSubscriptionForm').'
    '; + if (!empty($conf->multicompany->enabled)) { + $entity_qr = '?entity='.$conf->entity; + } else { + $entity_qr = ''; + } + + // Define $urlwithroot + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + print ''; + print ajax_autoselect('publicurlmember'); +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/partnership/class/partnership.class.php b/htdocs/partnership/class/partnership.class.php index 82a5ee65171..4981dde2b45 100644 --- a/htdocs/partnership/class/partnership.class.php +++ b/htdocs/partnership/class/partnership.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2021 NextGestion +/* Copyright (C) 2017 Laurent Destailleur + * Copyright (C) 2021 NextGestion * * 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 @@ -27,6 +27,7 @@ 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 Partnership */ @@ -66,7 +67,7 @@ class Partnership extends CommonObject const STATUS_DRAFT = 0; const STATUS_VALIDATED = 1; // Validate (no more draft) - const STATUS_ACCEPTED = 2; // Approved + const STATUS_APPROVED = 2; // Approved const STATUS_REFUSED = 3; // Refused const STATUS_CANCELED = 9; @@ -105,7 +106,7 @@ class Partnership extends CommonObject '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'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), 'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => 1, 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 15, 'index' => 1), - //'fk_type' => array('type' => 'integer:PartnershipType:partnership/class/partnershiptype.class.php', 'label' => 'Type', 'default' => 1, 'enabled' => 1, 'visible' => 1, 'position' => 20), + 'fk_type' => array('type' => 'integer:PartnershipType:partnership/class/partnership_type.class.php', 'label' => 'Type', 'enabled' => 1, 'visible' => 1, 'position' => 20), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), @@ -121,6 +122,7 @@ class Partnership extends CommonObject 'count_last_url_check_error' => array('type'=>'integer', 'label'=>'CountLastUrlCheckError', 'enabled'=>'1', 'position'=>63, 'notnull'=>0, 'visible'=>-2, 'default'=>'0',), 'last_check_backlink' => array('type'=>'datetime', 'label'=>'LastCheckBacklink', 'enabled'=>'1', 'position'=>65, 'notnull'=>0, 'visible'=>-2,), 'reason_decline_or_cancel' => array('type'=>'text', 'label'=>'ReasonDeclineOrCancel', 'enabled'=>'1', 'position'=>64, 'notnull'=>0, 'visible'=>-2,), + // fk_member and fk_soc are added into constructor ); /** @@ -130,14 +132,14 @@ class Partnership extends CommonObject */ public $rowid; - public $fk_soc; + public $fk_soc; // Link to thirdparty + public $fk_member; // Link to member public $tms; public $fk_user_creat; public $fk_user_modif; public $status; - public $fk_member; public $date_partnership_start; public $date_partnership_end; public $count_last_url_check_error; @@ -197,9 +199,9 @@ class Partnership extends CommonObject $this->db = $db; if (!empty($conf->global->PARTNERSHIP_IS_MANAGED_FOR) && $conf->global->PARTNERSHIP_IS_MANAGED_FOR == 'member') { - $this->fields['fk_member'] = array('type'=>'integer:Adherent:adherents/class/adherent.class.php:1', 'label'=>'Member', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'member'); + $this->fields['fk_member'] = array('type'=>'integer:Adherent:adherents/class/adherent.class.php:1', 'label'=>'Member', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'member', 'csslist'=>'tdoverflowmax150'); } else { - $this->fields['fk_soc'] = array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'company'); + $this->fields['fk_soc'] = array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'company', 'csslist'=>'tdoverflowmax150'); } if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) { @@ -365,14 +367,15 @@ class Partnership extends CommonObject return -1; } - $sql = 'SELECT p.rowid, p.ref, p.fk_soc, p.fk_member, p.status'; + $sql = 'SELECT p.rowid, p.ref, p.fk_type, p.fk_soc, p.fk_member, p.status'; $sql .= ', p.entity, p.date_partnership_start, p.date_partnership_end, p.date_creation'; $sql .= ', p.fk_user_creat, p.tms, p.fk_user_modif, p.fk_user_modif'; $sql .= ', p.note_private, p.note_public'; $sql .= ', p.last_main_doc, p.count_last_url_check_error, p.last_check_backlink, p.reason_decline_or_cancel'; $sql .= ', p.import_key, p.model_pdf'; - + $sql .= ', pt.code as type_code, pt.label as type_label'; $sql .= ' FROM '.MAIN_DB_PREFIX.'partnership as p'; + $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_partnership_type as pt ON p.fk_type = pt.rowid'; if ($id) { $sql .= " WHERE p.rowid=".((int) $id); @@ -399,8 +402,12 @@ class Partnership extends CommonObject if ($obj) { $this->id = $obj->rowid; $this->entity = $obj->entity; - $this->rowid = $obj->rowid; $this->ref = $obj->ref; + + $this->fk_type = $obj->fk_type; + $this->type_code = $obj->type_code; + $this->type_label = $obj->type_label; + $this->fk_soc = $obj->fk_soc; $this->fk_member = $obj->fk_member; $this->status = $obj->status; @@ -700,13 +707,13 @@ class Partnership extends CommonObject } /** - * Accept object + * Approve 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 accept($user, $notrigger = 0) + public function approve($user, $notrigger = 0) { global $conf, $langs; @@ -715,7 +722,7 @@ class Partnership extends CommonObject $error = 0; // Protection - if ($this->status == self::STATUS_ACCEPTED) { + if ($this->status == self::STATUS_APPROVED) { dol_syslog(get_class($this)."::accept action abandonned: already acceptd", LOG_WARNING); return 0; } @@ -744,7 +751,7 @@ class Partnership extends CommonObject // Accept $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element; $sql .= " SET ref = '".$this->db->escape($num)."',"; - $sql .= " status = ".self::STATUS_ACCEPTED; + $sql .= " status = ".self::STATUS_APPROVED; // if (!empty($this->fields['date_validation'])) { // $sql .= ", date_validation = '".$this->db->idate($now)."'"; // } @@ -811,7 +818,7 @@ class Partnership extends CommonObject // Set new ref and current status if (!$error) { $this->ref = $num; - $this->status = self::STATUS_ACCEPTED; + $this->status = self::STATUS_APPROVED; } if (!$error) { @@ -886,7 +893,7 @@ class Partnership extends CommonObject public function cancel($user, $notrigger = 0) { // Protection - if ($this->status != self::STATUS_ACCEPTED) { + if ($this->status != self::STATUS_APPROVED) { return 0; } @@ -921,7 +928,7 @@ class Partnership extends CommonObject return -1; }*/ - return $this->setStatusCommon($user, self::STATUS_ACCEPTED, $notrigger, 'PARTNERSHIP_REOPEN'); + return $this->setStatusCommon($user, self::STATUS_APPROVED, $notrigger, 'PARTNERSHIP_REOPEN'); } /** @@ -951,7 +958,7 @@ class Partnership extends CommonObject $label .= '
    '; $label .= ''.$langs->trans('Ref').': '.$this->ref; - $url = dol_buildpath('/partnership/partnership_card.php', 1).'?id='.$this->id; + $url = DOL_URL_ROOT.'/partnership/partnership_card.php?id='.$this->id; if ($option != 'nolink') { // Add param to save lastsearch_values or not @@ -1064,20 +1071,20 @@ class Partnership extends CommonObject if (empty($this->labelStatus) || empty($this->labelStatusShort)) { global $langs; //$langs->load("partnership"); - $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated'); - $this->labelStatus[self::STATUS_ACCEPTED] = $langs->trans('Accepted'); - $this->labelStatus[self::STATUS_REFUSED] = $langs->trans('Refused'); - $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Canceled'); - $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated'); - $this->labelStatusShort[self::STATUS_ACCEPTED] = $langs->trans('Accepted'); - $this->labelStatusShort[self::STATUS_REFUSED] = $langs->trans('Refused'); - $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Canceled'); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated'); + $this->labelStatus[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('Approved'); + $this->labelStatus[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated'); + $this->labelStatusShort[self::STATUS_APPROVED] = $langs->transnoentitiesnoconv('Approved'); + $this->labelStatusShort[self::STATUS_REFUSED] = $langs->transnoentitiesnoconv('Refused'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Canceled'); } $statusType = 'status'.$status; - if ($status == self::STATUS_ACCEPTED) { + if ($status == self::STATUS_APPROVED) { $statusType = 'status4'; } if ($status == self::STATUS_REFUSED) { @@ -1157,7 +1164,7 @@ class Partnership extends CommonObject $this->lines = array(); $objectline = new PartnershipLine($this->db); - $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_partnership = '.$this->id)); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_partnership = '.((int) $this->id))); if (is_numeric($result)) { $this->error = $this->error; diff --git a/htdocs/partnership/class/partnership_type.class.php b/htdocs/partnership/class/partnership_type.class.php new file mode 100644 index 00000000000..6916d95e4f3 --- /dev/null +++ b/htdocs/partnership/class/partnership_type.class.php @@ -0,0 +1,562 @@ + + * Copyright (C) 2004-2008 Laurent Destailleur + * Copyright (C) 2009-2017 Regis Houssin + * Copyright (C) 2016 Charlie Benke + * Copyright (C) 2018-2019 Thibault Foucart + * Copyright (C) 2021 Waël Almoman + * + * 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/partnership/class/partnership_type.class.php + * \ingroup partnership + * \brief File of class to manage partnership types + */ + +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; + + +/** + * Class to manage partnership type + */ +class PartnershipType extends CommonObject +{ + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'c_partnership_type'; + + /** + * @var string ID to identify managed object + */ + public $element = 'partnership_type'; + + /** + * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png + */ + public $picto = 'generic'; + + /** + * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + * @var int + */ + public $ismultientitymanaged = 1; + + /** + * @var string Partnership code + */ + public $code; + + /** + * @var string Partnership type label + */ + public $label; + + + 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), + 'code' =>array('type'=>'varchar(32)', 'label'=>'Code', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>20, 'showoncombobox'=>1), + 'label' =>array('type'=>'varchar(64)', 'label'=>'Label', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25, 'showoncombobox'=>1), + 'active' =>array('type'=>'integer', 'label'=>'Active', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>30), + ); + + + + /** + * 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; + } + + // Example to show how to set values of fields definition dynamically + /*if ($user->rights->mymodule->myobject->read) { + $this->fields['myfield']['visible'] = 1; + $this->fields['myfield']['noteditable'] = 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); + + //$resultvalidate = $this->validate($user, $notrigger); + + return $resultcreate; + } + + /** + * 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 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); + } + + /** + * 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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->mymodule->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->mymodule->mymodule_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'PARTNERSHIPTYPE_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->mymodule->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->mymodule->mymodule_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'PARTNERSHIPTYPE_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; + } + + /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->mymodule->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->mymodule->mymodule_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'PARTNERSHIPTYPE_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("PartnershipType").''; + if (isset($this->status)) { + $label .= ' '.$this->getLibStatut(5); + } + $label .= '
    '; + $label .= ''.$langs->trans('Code').': '.$this->code; + $label .= '
    '.$langs->trans('Label').': '.$this->label; + + //$url = dol_buildpath('/partnership/partnership_card.php', 1).'?id='.$this->id; + $url = ''; + + 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 ($url && $add_save_lastsearch_values) { + $url .= '&save_lastsearch_values=1'; + } + } + + $linkclose = ''; + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { + $label = $langs->trans("ShowMyObject"); + $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' || empty($url)) { + $linkstart = ''; + if ($option == 'nolink' || empty($url)) { + $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('myobjectdao')); + $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("mymodule@mymodule"); + $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(); + } +} diff --git a/htdocs/partnership/class/partnershiputils.class.php b/htdocs/partnership/class/partnershiputils.class.php index 0588b9e5df2..35b8a3b01e5 100644 --- a/htdocs/partnership/class/partnershiputils.class.php +++ b/htdocs/partnership/class/partnershiputils.class.php @@ -101,7 +101,7 @@ class PartnershipUtils $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent_type as dty on (dty.rowid = d.fk_adherent_type)"; $sql .= " WHERE fk_member > 0"; $sql .= " AND (d.datefin < '".$this->db->idate($datetotest)."' AND dty.subscription = 1)"; - $sql .= " AND p.status = ".((int) $partnership::STATUS_ACCEPTED); // Only accepted not yet canceled + $sql .= " AND p.status = ".((int) $partnership::STATUS_APPROVED); // Only accepted not yet canceled $sql .= $this->db->order('d.rowid', 'ASC'); // Limit is managed into loop later @@ -262,7 +262,7 @@ class PartnershipUtils $sql .= " WHERE 1 = 1"; $sql .= " AND p.".$fk_partner." > 0"; - $sql .= " AND p.status = ".((int) $partnership::STATUS_ACCEPTED); // Only accepted not yet canceled + $sql .= " AND p.status = ".((int) $partnership::STATUS_APPROVED); // Only accepted not yet canceled $sql .= " AND (p.last_check_backlink IS NULL OR p.last_check_backlink <= '".$this->db->idate($now - 7 * 24 * 3600)."')"; // Every week, check that website contains a link to dolibarr. $sql .= $this->db->order('p.rowid', 'ASC'); // Limit is managed into loop later diff --git a/htdocs/partnership/core/modules/partnership/mod_partnership_standard.php b/htdocs/partnership/core/modules/partnership/mod_partnership_standard.php index fefcafa2350..d5a2bb326b2 100644 --- a/htdocs/partnership/core/modules/partnership/mod_partnership_standard.php +++ b/htdocs/partnership/core/modules/partnership/mod_partnership_standard.php @@ -36,7 +36,7 @@ class mod_partnership_standard extends ModeleNumRefPartnership */ public $version = 'dolibarr'; // 'development', 'experimental', 'dolibarr' - public $prefix = 'PARTNERSHIP'; + public $prefix = 'PSHIP'; /** * @var string Error code (or message) diff --git a/htdocs/partnership/lib/partnership.lib.php b/htdocs/partnership/lib/partnership.lib.php index 5305f86132e..23b5a2901fb 100644 --- a/htdocs/partnership/lib/partnership.lib.php +++ b/htdocs/partnership/lib/partnership.lib.php @@ -46,6 +46,11 @@ function partnershipAdminPrepareHead() $head[$h][2] = 'partnership_extrafields'; $h++; + $head[$h][0] = dol_buildpath("/partnership/admin/website.php", 1); + $head[$h][1] = $langs->trans("BlankSubscriptionForm"); + $head[$h][2] = 'website'; + $h++; + /* $head[$h][0] = dol_buildpath("/partnership/admin/about.php", 1); $head[$h][1] = $langs->trans("About"); diff --git a/htdocs/partnership/partnership_agenda.php b/htdocs/partnership/partnership_agenda.php index 799aadd24cd..f154e1b9f5b 100644 --- a/htdocs/partnership/partnership_agenda.php +++ b/htdocs/partnership/partnership_agenda.php @@ -154,7 +154,7 @@ if ($object->id > 0) { $morehtmlref.='
    '.$langs->trans('Project') . ' '; if ($permissiontoadd) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; } $morehtmlref.=' : '; if ($action == 'classify') { diff --git a/htdocs/partnership/partnership_card.php b/htdocs/partnership/partnership_card.php index bf980ab9cda..0f32eb94580 100644 --- a/htdocs/partnership/partnership_card.php +++ b/htdocs/partnership/partnership_card.php @@ -153,7 +153,7 @@ if (empty($reshook)) { setEventMessages($object->error, $object->errors, 'errors'); } } elseif ($action == 'confirm_accept' && $confirm == 'yes' && $permissiontoadd) { - $result = $object->accept($user); + $result = $object->approve($user); if ($result >= 0) { // Define output language if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { @@ -232,7 +232,7 @@ if (empty($reshook)) { // Actions to send emails $triggersendname = 'PARTNERSHIP_SENTBYMAIL'; $autocopy = 'MAIN_MAIL_AUTOCOPY_PARTNERSHIP_TO'; - $trackid = 'partnership'.$object->id; + $trackid = 'pship'.$object->id; include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; if (!empty($id) && !empty(GETPOST('confirm'))) { @@ -412,7 +412,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $langs->load("projects"); $morehtmlref .= '
    '.$langs->trans('Project') . ' '; if ($permissiontoadd) { - //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; + //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); @@ -556,7 +556,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (empty($reshook)) { // Send if (empty($user->socid)) { - print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&mode=init&token='.newToken().'#formmailbeforetitle'); + print dolGetButtonAction($langs->trans('SendMail'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=presend&token='.newToken().'&mode=init#formmailbeforetitle'); } if ($object->status == $object::STATUS_DRAFT) { @@ -590,9 +590,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Cancel if ($permissiontoadd) { - if ($object->status == $object::STATUS_ACCEPTED) { + if ($object->status == $object::STATUS_APPROVED) { print dolGetButtonAction($langs->trans('Cancel'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=close&token='.newToken(), '', $permissiontoadd); - } elseif ($object->status > $object::STATUS_ACCEPTED) { + } elseif ($object->status > $object::STATUS_APPROVED) { // print ''.$langs->trans("Re-Open").''."\n"; print dolGetButtonAction($langs->trans('Re-Open'), '', 'default', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_reopen&confirm=yes&token='.newToken(), '', $permissiontoadd); } @@ -600,7 +600,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea // Refuse if ($permissiontoadd) { - if ($object->status != $object::STATUS_DRAFT && $object->status != $object::STATUS_ACCEPTED && $object->status != $object::STATUS_CANCELED && $object->status != $object::STATUS_REFUSED) { + if ($object->status != $object::STATUS_DRAFT && $object->status != $object::STATUS_APPROVED && $object->status != $object::STATUS_CANCELED && $object->status != $object::STATUS_REFUSED) { print dolGetButtonAction($langs->trans('Refuse'), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.'&action=refuse&token='.newToken(), '', $permissiontoadd); } } @@ -639,20 +639,20 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - print '
    '; + print '
    '; $MAXEVENT = 10; - $morehtmlright = ''; + $morehtmlright = ''; $morehtmlright .= $langs->trans("SeeAll"); $morehtmlright .= ''; // 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, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); + $somethingshown = $formactions->showactions($object, $object->element, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); - print '
    '; + print ''; } //Select mail models is same action as presend @@ -664,7 +664,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $modelmail = 'partnership_send'; $defaulttopic = 'InformationMessage'; $diroutput = $conf->partnership->dir_output; - $trackid = 'partnership'.$object->id; + $trackid = 'pship'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php'; } diff --git a/htdocs/partnership/partnership_contact.php b/htdocs/partnership/partnership_contact.php index 1c416cf690c..a4a61c6e907 100644 --- a/htdocs/partnership/partnership_contact.php +++ b/htdocs/partnership/partnership_contact.php @@ -140,7 +140,7 @@ if ($object->id) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/partnership/partnership_document.php b/htdocs/partnership/partnership_document.php index e7fae7ee7ff..79b7be0057a 100644 --- a/htdocs/partnership/partnership_document.php +++ b/htdocs/partnership/partnership_document.php @@ -137,7 +137,7 @@ if ($object->id) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/partnership/partnership_list.php b/htdocs/partnership/partnership_list.php index e9c577213d6..2703d431e1a 100644 --- a/htdocs/partnership/partnership_list.php +++ b/htdocs/partnership/partnership_list.php @@ -29,8 +29,6 @@ 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.'/adherents/class/adherent.class.php'; - -// load partnership libraries require_once DOL_DOCUMENT_ROOT.'/partnership/class/partnership.class.php'; // for other modules @@ -158,6 +156,8 @@ if ($user->socid > 0) { // Protection if external user * Actions */ +$error = 0; + if (GETPOST('cancel', 'alpha')) { $action = 'list'; $massaction = ''; @@ -200,6 +200,43 @@ if (empty($reshook)) { $uploaddir = $conf->partnership->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + // Validate and approve + if (!$error && $massaction == 'approve' && $permissiontoadd) { + $objecttmp = new Partnership($db); + + $db->begin(); + $error = 0; + $result = 0; + + foreach ($toselect as $checked) { + if ($objecttmp->fetch($checked)) { + if ($objecttmp->status == $objecttmp::STATUS_DRAFT) { + //$objecttmp->date = dol_now(); + $result = $objecttmp->validate($user); + } + + if ($result >= 0 && $objecttmp->status == $objecttmp::STATUS_VALIDATED) { + $result = $objecttmp->approve($user); + if ($result > 0) { + setEventMessages($langs->trans("PartnershipRefApproved", $objecttmp->ref), null); + } else { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + } + } else { + setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); + $error++; + } + } + } + + if (!$error) { + $db->commit(); + } else { + $db->rollback(); + } + } + // Cancel partnership if ($massaction == 'cancel' && $permissiontoadd) { $db->begin(); @@ -208,9 +245,14 @@ if (empty($reshook)) { $nbok = 0; foreach ($toselect as $toselectid) { $result = $objecttmp->fetch($toselectid); + var_dump($objecttmp->status); if ($result > 0) { - $result = $objecttmp->cancel($user, 3); - if ($result <= 0) { + $result = $objecttmp->cancel($user, 0); + var_dump($result); + if ($result == 0) { + setEventMessages($langs->trans('StatusOfRefMustBe', $objecttmp->ref, $objecttmp->LibStatut($objecttmp::STATUS_APPROVED)), null, 'warnings'); + $error++; + } elseif ($result <= 0) { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); $error++; break; @@ -432,7 +474,9 @@ $param .= $hookmanager->resPrint; // List of mass actions available $arrayofmassactions = array( -'cancel'=>img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Cancel"), + //'validate'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"), + 'approve'=>img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("ValidateAndApprove"), + 'cancel'=>img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Cancel"), //'generate_doc'=>img_picto('', 'pdf').$langs->trans("ReGeneratePDF"), //'builddoc'=>img_picto('', 'pdf').$langs->trans("PDFMerge"), 'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendMail"), @@ -440,7 +484,7 @@ $arrayofmassactions = array( if ($permissiontodelete) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } -if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('prevalidate', 'presend', 'predelete'))) { $arrayofmassactions = array(); } $massactionbutton = $form->selectMassAction('', $arrayofmassactions); @@ -464,7 +508,7 @@ print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sort $topicmail = "SendPartnershipRef"; $modelmail = "partnership_send"; $objecttmp = new Partnership($db); -$trackid = 'partnership'.$object->id; +$trackid = 'pship'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; if ($search_all) { @@ -652,7 +696,7 @@ while ($i < ($limit ? min($num, $limit) : $num)) { if (!$i) { $totalarray['nbfield']++; } - if (!empty($val['isameasure'])) { + if (!empty($val['isameasure']) && $val['isameasure'] == 1) { if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = 't.'.$key; } diff --git a/htdocs/partnership/partnership_note.php b/htdocs/partnership/partnership_note.php index cc97eac5515..67f963b155e 100644 --- a/htdocs/partnership/partnership_note.php +++ b/htdocs/partnership/partnership_note.php @@ -110,7 +110,7 @@ if ($id > 0 || !empty($ref)) { if ($permissiontoadd) { if ($action != 'classify') - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$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); diff --git a/htdocs/partnership/partnershipindex.php b/htdocs/partnership/partnershipindex.php index f1a9f8c507b..0b8a6cd33c9 100644 --- a/htdocs/partnership/partnershipindex.php +++ b/htdocs/partnership/partnershipindex.php @@ -133,7 +133,7 @@ if (! empty($conf->partnership->enabled) && $user->rights->partnership->read) { END MODULEBUILDER DRAFT MYOBJECT */ -print '
    '; +print '
    '; $NBMAX = $conf->global->MAIN_SIZE_SHORTLIST_LIMIT; @@ -190,7 +190,7 @@ if (! empty($conf->partnership->enabled) && $user->rights->partnership->read) { } */ -print '
    '; +print ''; // End of page llxFooter(); diff --git a/htdocs/paypal/lib/paypal.lib.php b/htdocs/paypal/lib/paypal.lib.php index dee6476f773..16e728512f6 100644 --- a/htdocs/paypal/lib/paypal.lib.php +++ b/htdocs/paypal/lib/paypal.lib.php @@ -282,7 +282,7 @@ function callSetExpressCheckout($paymentAmount, $currencyCodeType, $paymentType, $_SESSION["FinalPaymentAmt"] = $paymentAmount; $_SESSION["currencyCodeType"] = $currencyCodeType; $_SESSION["PaymentType"] = $paymentType; // 'Mark', 'Sole' - $_SESSION['ipaddress'] = getUserRemoteIP(); // Payer ip + $_SESSION['ipaddress'] = getUserRemoteIP(); // Payer ip //'--------------------------------------------------------------------------------------------------------------- //' Make the API call to PayPal diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php index 2b86efa507c..a0849f082e8 100644 --- a/htdocs/printing/admin/printing.php +++ b/htdocs/printing/admin/printing.php @@ -274,13 +274,13 @@ if ($mode == 'config' && $user->admin) { print ajax_constantonoff($printer->active); } else { if (empty($conf->global->{$printer->conf})) { - print ''.img_picto($langs->trans("Disabled"), 'off').''; + print ''.img_picto($langs->trans("Disabled"), 'off').''; } else { - print ''.img_picto($langs->trans("Enabled"), 'on').''; + print ''.img_picto($langs->trans("Enabled"), 'on').''; } } - print ''.img_picto('', 'setup').''; - print ''.img_picto('', 'setup').''; + print ''.img_picto('', 'setup').''; + print ''.img_picto('', 'setup').''; print ''."\n"; } diff --git a/htdocs/product/admin/dynamic_prices.php b/htdocs/product/admin/dynamic_prices.php index 9a354a8dcdb..e1e23feac86 100644 --- a/htdocs/product/admin/dynamic_prices.php +++ b/htdocs/product/admin/dynamic_prices.php @@ -182,9 +182,9 @@ if ($action != 'create_updater' && $action != 'edit_updater') { print ''; } } else { - print ''; + print ''; print $langs->trans("None"); - print ''; + print ''; } print ''; diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index fa75a20277f..4f6094e1787 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -346,7 +346,7 @@ foreach ($dirproduct as $dirroot) { } print ''; if (!$disabled) { - print ''; + print ''; } print img_picto($langs->trans("Disabled"), 'switch_off'); if (!$disabled) { @@ -448,13 +448,13 @@ foreach ($dirmodels as $reldir) { // Active if (in_array($name, $def)) { print ''."\n"; - print ''; + print ''; print img_picto($langs->trans("Enabled"), 'switch_on'); print ''; print ''; } else { print ''."\n"; - print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print 'scandir).'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print ""; } @@ -463,7 +463,7 @@ foreach ($dirmodels as $reldir) { if ($conf->global->PRODUCT_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).'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print ''; @@ -762,10 +762,10 @@ if (!empty($conf->global->PRODUCT_CANVAS_ABILITY)) { if ($conf->global->$const) { print img_picto($langs->trans("Active"), 'tick'); print ''; - print ''.$langs->trans("Disable").''; + print ''.$langs->trans("Disable").''; } else { print ' '; - print ''.$langs->trans("Activate").''; + print ''.$langs->trans("Activate").''; } print ''; diff --git a/htdocs/product/admin/product_lot.php b/htdocs/product/admin/product_lot.php index 3f4fd636de4..24f515fa0bc 100644 --- a/htdocs/product/admin/product_lot.php +++ b/htdocs/product/admin/product_lot.php @@ -161,7 +161,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL < 2) { if ($conf->global->PRODUCTBATCH_LOT_ADDON == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { - print ''; + print ''; print img_picto($langs->trans("Disabled"), 'switch_off'); print ''; } @@ -253,7 +253,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL < 2) { if ($conf->global->PRODUCTBATCH_SN_ADDON == $file) { print img_picto($langs->trans("Activated"), 'switch_on'); } else { - print ''; + print ''; print img_picto($langs->trans("Disabled"), 'switch_off'); print ''; } diff --git a/htdocs/product/ajax/products.php b/htdocs/product/ajax/products.php index 77acafbbd55..84562bf95a4 100644 --- a/htdocs/product/ajax/products.php +++ b/htdocs/product/ajax/products.php @@ -91,7 +91,7 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) { $outtype = $object->type; $outqty = 1; $outdiscount = 0; - + $mandatory_period = $object->mandatory_period; $found = false; $price_level = 1; @@ -144,7 +144,7 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) { if (!$found && isset($price_level) && $price_level >= 1 && (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES))) { // If we need a particular price level (from 1 to 6) $sql = "SELECT price, price_ttc, price_base_type, tva_tx"; $sql .= " FROM ".MAIN_DB_PREFIX."product_price "; - $sql .= " WHERE fk_product = '".$id."'"; + $sql .= " WHERE fk_product = ".((int) $id); $sql .= " AND entity IN (".getEntity('productprice').")"; $sql .= " AND price_level = ".((int) $price_level); $sql .= " ORDER BY date_price"; @@ -203,6 +203,7 @@ if (!empty($action) && $action == 'fetch' && !empty($id)) { 'tva_tx' => $outtva_tx, 'qty' => $outqty, 'discount' => $outdiscount, + 'mandatory_period' => $mandatory_period, 'array_options'=>$object->array_options); } diff --git a/htdocs/product/canvas/product/tpl/card_create.tpl.php b/htdocs/product/canvas/product/tpl/card_create.tpl.php index 5d39b55ff76..8813e4a8d7e 100644 --- a/htdocs/product/canvas/product/tpl/card_create.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_create.tpl.php @@ -27,7 +27,7 @@ $object = $GLOBALS['object']; $statutarray = array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSell")); ?> - + trans("NewProduct"), '', 'product'); diff --git a/htdocs/product/canvas/product/tpl/card_edit.tpl.php b/htdocs/product/canvas/product/tpl/card_edit.tpl.php index 2e04f660084..b21355c1c21 100644 --- a/htdocs/product/canvas/product/tpl/card_edit.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_edit.tpl.php @@ -27,7 +27,7 @@ $object = $GLOBALS['object']; $statutarray = array('1' => $langs->trans("OnSell"), '0' => $langs->trans("NotOnSell")); ?> - + - + trans("CardProduct".$object->type); diff --git a/htdocs/product/card.php b/htdocs/product/card.php index b4625d5602d..b14d4a4efca 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -105,6 +105,7 @@ $accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); $accountancy_code_buy_intra = GETPOST('accountancy_code_buy_intra', 'alpha'); $accountancy_code_buy_export = GETPOST('accountancy_code_buy_export', 'alpha'); +$checkmandatory = GETPOST('accountancy_code_buy_export', 'alpha'); // by default 'alphanohtml' (better security); hidden conf MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML allows basic html $label_security_check = empty($conf->global->MAIN_SECURITY_ALLOW_UNSECURED_LABELS_WITH_HTML) ? 'alphanohtml' : 'restricthtml'; @@ -131,7 +132,9 @@ $extrafields->fetch_name_optionals_label($object->table_element); if ($id > 0 || !empty($ref)) { $result = $object->fetch($id, $ref); - + if ($result < 0) { + dol_print_error($db, $object->error, $object->errors); + } if (!empty($conf->product->enabled)) { $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 0, $object, 'product').dol_sanitizeFileName($object->ref); } elseif (!empty($conf->service->enabled)) { @@ -176,6 +179,9 @@ if ($object->id > 0) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('productcard', 'globalcard')); +$usercanread = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->lire) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->lire)); +$usercancreate = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->creer) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->creer)); +$usercandelete = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->supprimer) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->supprimer)); /* @@ -186,9 +192,6 @@ if ($cancel) { $action = ''; } -$usercanread = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->lire) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->lire)); -$usercancreate = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->creer) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->creer)); -$usercandelete = (($object->type == Product::TYPE_PRODUCT && $user->rights->produit->supprimer) || ($object->type == Product::TYPE_SERVICE && $user->rights->service->supprimer)); $createbarcode = empty($conf->barcode->enabled) ? 0 : 1; if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->creer_advance)) { $createbarcode = 0; @@ -201,7 +204,7 @@ if ($reshook < 0) { } if (empty($reshook)) { - $backurlforlist = DOL_URL_ROOT.'/product/list.php'; + $backurlforlist = DOL_URL_ROOT.'/product/list.php?type='.$type; if (empty($backtopage) || ($cancel && empty($id))) { if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) { @@ -298,7 +301,7 @@ if (empty($reshook)) { $object->ref = $ref; $object->label = GETPOST('label', $label_security_check); $object->price_base_type = GETPOST('price_base_type', 'aZ09'); - + $object->mandatory_period = !empty(GETPOST("mandatoryperiod", 'alpha')) ? 1 : 0; if ($object->price_base_type == 'TTC') { $object->price_ttc = GETPOST('price'); } else { @@ -481,7 +484,7 @@ if (empty($reshook)) { $object->setCategories($categories); if (!empty($backtopage)) { - $backtopage = preg_replace('/--IDFORBACKTOPAGE--/', $object->id, $backtopage); // New method to autoselect project after a New on another form object creation + $backtopage = preg_replace('/__ID__/', $object->id, $backtopage); // New method to autoselect project after a New on another form object creation if (preg_match('/\?/', $backtopage)) { $backtopage .= '&socid='.$object->id; // Old method } @@ -599,7 +602,7 @@ if (empty($reshook)) { $accountancy_code_buy = GETPOST('accountancy_code_buy', 'alpha'); $accountancy_code_buy_intra = GETPOST('accountancy_code_buy_intra', 'alpha'); $accountancy_code_buy_export = GETPOST('accountancy_code_buy_export', 'alpha'); - + $checkmandatory = GETPOST('mandatoryperiod', 'alpha'); if (empty($accountancy_code_sell) || $accountancy_code_sell == '-1') { $object->accountancy_code_sell = ''; } else { @@ -630,9 +633,14 @@ if (empty($reshook)) { } else { $object->accountancy_code_buy_export = $accountancy_code_buy_export; } + if ($object->isService()) { + $object->mandatory_period = (!empty($checkmandatory)) ? 1 : 0 ; + } + + // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost(null, $object); + $ret = $extrafields->setOptionalsFromPost(null, $object, '@GETPOSTISSET'); if ($ret < 0) { $error++; } @@ -1164,8 +1172,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $tooltip .= '
    '.$langs->trans("GenericMaskCodes3"); $tooltip .= '
    '.$langs->trans("GenericMaskCodes4a", $langs->transnoentities("Batch"), $langs->transnoentities("Batch")); $tooltip .= '
    '.$langs->trans("GenericMaskCodes5"); - if (($conf->global->PRODUCTBATCH_LOT_USE_PRODUCT_MASKS && $conf->global->PRODUCTBATCH_LOT_ADDON == 'mod_lot_advanced') - || ($conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS && $conf->global->PRODUCTBATCH_SN_ADDON == 'mod_sn_advanced')) { + if ((!empty($conf->global->PRODUCTBATCH_LOT_USE_PRODUCT_MASKS) && $conf->global->PRODUCTBATCH_LOT_ADDON == 'mod_lot_advanced') + || (!empty($conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS) && $conf->global->PRODUCTBATCH_SN_ADDON == 'mod_sn_advanced')) { print ''.$langs->trans("ManageLotMask").''; $inherited_mask_lot = $conf->global->LOT_ADVANCED_MASK; $inherited_mask_sn = $conf->global->SN_ADVANCED_MASK; @@ -1213,10 +1221,12 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { if ($showbarcode) { print ''.$langs->trans('BarcodeType').''; if (GETPOSTISSET('fk_barcode_type')) { - $fk_barcode_type = GETPOST('fk_barcode_type'); + $fk_barcode_type = GETPOST('fk_barcode_type')?GETPOST('fk_barcode_type'):0; } else { if (empty($fk_barcode_type) && !empty($conf->global->PRODUIT_DEFAULT_BARCODE_TYPE)) { - $fk_barcode_type = $conf->global->PRODUIT_DEFAULT_BARCODE_TYPE; + $fk_barcode_type = getDolGlobalInt("PRODUIT_DEFAULT_BARCODE_TYPE"); + } else { + $fk_barcode_type=0; } } require_once DOL_DOCUMENT_ROOT.'/core/class/html.formbarcode.class.php'; @@ -1254,7 +1264,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''.$langs->trans("DefaultWarehouse").''; print img_picto($langs->trans("DefaultWarehouse"), 'stock', 'class="pictofixedwidth"'); print $formproduct->selectWarehouses(GETPOST('fk_default_warehouse', 'int'), 'fk_default_warehouse', 'warehouseopen', 1, 0, 0, '', 0, 0, array(), 'minwidth300 widthcentpercentminusxx maxwidth500'); - print ' '; + print ' '; print ''; print ''; print ''; @@ -1284,6 +1294,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''.$langs->trans("Duration").''; print ''; print $formproduct->selectMeasuringUnits("duration_unit", "time", (GETPOSTISSET('duration_value') ? GETPOSTISSET('duration_value', 'alpha') : 'h'), 0, 1); + + // Mandatory period + print '       '; + print 'mandatory_period == 1 ? ' checked="checked"' : '').'>'; + print ''; + print ''; } @@ -1386,7 +1405,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $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, 'edit', $parameters); + print $object->showOptionals($extrafields, 'create', $parameters); } // Note (private, no output on invoices, propales...) @@ -1423,6 +1442,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { $defaultva = get_default_tva($mysoc, $mysoc); print $form->load_tva("tva_tx", $defaultva, $mysoc, $mysoc, 0, 0, '', false, 1); print ''; + print ''; print '
    '; @@ -1820,6 +1840,15 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''.$langs->trans("Duration").''; print ' '; print $formproduct->selectMeasuringUnits("duration_unit", "time", $object->duration_unit, 0, 1); + + // Mandatory period + print '       '; + print 'mandatory_period == 1 ? ' checked="checked"' : '').'>'; + print ''; + print ''; } else { if (empty($conf->global->PRODUCT_DISABLE_NATURE)) { @@ -1893,11 +1922,12 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''.$langs->trans("CountryOrigin").''; print ''; print img_picto('', 'globe-americas', 'class="paddingrightonly"'); - print $form->select_country($object->country_id, 'country_id', '', 0, 'minwidth100 maxwidthonsmartphone'); + print $form->select_country(GETPOSTISSET('country_id') ? GETPOST('country_id', 'int') : $object->country_id, 'country_id', '', 0, 'minwidth100 maxwidthonsmartphone'); if ($user->admin) { print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); } print ''; + // State if (empty($conf->global->PRODUCT_DISABLE_STATE)) { print ''; @@ -1908,7 +1938,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } print img_picto('', 'state', 'class="pictofixedwidth"'); - print $formcompany->select_state($object->state_id, $object->country_code); + print $formcompany->select_state(GETPOSTISSET('state_id') ? GETPOST('state_id', 'int') : $object->state_id, $object->country_code); print ''; print ''; } @@ -2148,8 +2178,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''.$langs->trans("ManageLotSerial").''; print $object->getLibStatut(0, 2); print ''; - if ((($object->status_batch == '1' && $conf->global->PRODUCTBATCH_LOT_USE_PRODUCT_MASKS && $conf->global->PRODUCTBATCH_LOT_ADDON == 'mod_lot_advanced') - || ($object->status_batch == '2' && $conf->global->PRODUCTBATCH_SN_ADDON == 'mod_sn_advanced' && $conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS))) { + if ((($object->status_batch == '1' && !empty($conf->global->PRODUCTBATCH_LOT_USE_PRODUCT_MASKS) && $conf->global->PRODUCTBATCH_LOT_ADDON == 'mod_lot_advanced') + || ($object->status_batch == '2' && $conf->global->PRODUCTBATCH_SN_ADDON == 'mod_sn_advanced' && !empty($conf->global->PRODUCTBATCH_SN_USE_PRODUCT_MASKS)))) { print ''.$langs->trans("ManageLotMask").''; print $object->batch_mask; print ''; @@ -2294,20 +2324,29 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print ''; print ''; - print '
    '; + print '
    '; print '
    '; print ''; if ($object->isService()) { // Duration - print ''; } else { @@ -2441,7 +2480,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { print "
    '.$langs->trans("Duration").''.$object->duration_value.' '; + print '
    '.$langs->trans("Duration").''; + print $object->duration_value; if ($object->duration_value > 1) { $dur = array("i"=>$langs->trans("Minute"), "h"=>$langs->trans("Hours"), "d"=>$langs->trans("Days"), "w"=>$langs->trans("Weeks"), "m"=>$langs->trans("Months"), "y"=>$langs->trans("Years")); } elseif ($object->duration_value > 0) { $dur = array("i"=>$langs->trans("Minute"), "h"=>$langs->trans("Hour"), "d"=>$langs->trans("Day"), "w"=>$langs->trans("Week"), "m"=>$langs->trans("Month"), "y"=>$langs->trans("Year")); } - print (!empty($object->duration_unit) && isset($dur[$object->duration_unit]) ? $langs->trans($dur[$object->duration_unit]) : '')." "; + print (!empty($object->duration_unit) && isset($dur[$object->duration_unit]) ? " ".$langs->trans($dur[$object->duration_unit])." " : ''); + + // Mandatory period + if ($object->duration_value > 0) { + print '       '; + } + $htmltooltip = $langs->trans("mandatoryHelper"); + print 'mandatory_period == 1 ? ' checked="checked"' : '').' disabled>'; + print $form->textwithpicto($langs->trans("mandatoryperiod"), $htmltooltip, 1, 0); print '
    \n"; print '
    '; - print '
    '; + print ''; print '
    '; print dol_get_fiche_end(); @@ -2507,14 +2546,14 @@ if ($action != 'create' && $action != 'edit') { if (empty($reshook)) { if ($usercancreate) { if (!isset($object->no_button_edit) || $object->no_button_edit <> 1) { - print 'id.'">'.$langs->trans("Modify").''; + print 'id.'">'.$langs->trans("Modify").''; } if (!isset($object->no_button_copy) || $object->no_button_copy <> 1) { if (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile)) { print ''.$langs->trans('ToClone').''."\n"; } else { - print 'id.'">'.$langs->trans("ToClone").''; + print 'id.'">'.$langs->trans("ToClone").''; } } } @@ -2525,7 +2564,7 @@ if ($action != 'create' && $action != 'edit') { if (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile)) { print ''.$langs->trans('Delete').''."\n"; } else { - print 'id.'">'.$langs->trans("Delete").''; + print 'id.'">'.$langs->trans("Delete").''; } } else { print ''.$langs->trans("Delete").''; @@ -2538,8 +2577,9 @@ if ($action != 'create' && $action != 'edit') { print "\n\n"; } + /* - * All the "Add to" areas + * All the "Add to" areas if PRODUCT_ADD_FORM_ADD_TO is set */ if (!empty($conf->global->PRODUCT_ADD_FORM_ADD_TO) && $object->id && ($action == '' || $action == 'view') && $object->status) { @@ -2649,7 +2689,6 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete') { // Documents $objectref = dol_sanitizeFileName($object->ref); - $relativepath = $comref.'/'.$objectref.'.pdf'; if (!empty($conf->product->multidir_output[$object->entity])) { $filedir = $conf->product->multidir_output[$object->entity].'/'.$objectref; //Check repertories of current entities } else { @@ -2659,10 +2698,10 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete') { $genallowed = $usercanread; $delallowed = $usercancreate; - print $formfile->showdocuments($modulepart, $object->ref, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', 0, '', $object->default_lang, '', $object); + print $formfile->showdocuments($modulepart, $object->ref, $filedir, $urlsource, $genallowed, $delallowed, '', 0, 0, 0, 28, 0, '', 0, '', $langs->getDefaultLang(), '', $object); $somethingshown = $formfile->numoffiles; - print '
    '; + print '
    '; $MAXEVENT = 10; @@ -2675,7 +2714,7 @@ if ($action != 'create' && $action != 'edit' && $action != 'delete') { $formactions = new FormActions($db); $somethingshown = $formactions->showactions($object, 'product', 0, 1, '', $MAXEVENT, '', $morehtmlright); // Show all action for product - print '
    '; + print ''; } // End of page diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 9804daf1bba..6283b692a28 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -462,7 +462,7 @@ class Products extends DolibarrApi $childsArbo = $this->product->getChildsArbo($id, 1); - $keys = array('rowid', 'qty', 'fk_product_type', 'label', 'incdec'); + $keys = array('rowid', 'qty', 'fk_product_type', 'label', 'incdec', 'ref'); $childs = array(); foreach ($childsArbo as $values) { $childs[] = array_combine($keys, $values); @@ -1617,7 +1617,7 @@ class Products extends DolibarrApi $combinations[$key]->attributes = $prodc2vp->fetchByFkCombination((int) $combination->id); $combinations[$key] = $this->_cleanObjectDatas($combinations[$key]); - if ($includestock==1) { + if ($includestock==1 && DolibarrApiAccess::$user->rights->stock->lire) { $productModel = new Product($this->db); $productModel->fetch((int) $combination->fk_product_child); $productModel->load_stock(); @@ -1859,7 +1859,7 @@ class Products extends DolibarrApi public function getStock($id, $selected_warehouse_id = null) { - if (!DolibarrApiAccess::$user->rights->produit->lire) { + if (!DolibarrApiAccess::$user->rights->produit->lire || !DolibarrApiAccess::$user->rights->stock->lire) { throw new RestException(401); } @@ -1945,6 +1945,10 @@ class Products extends DolibarrApi unset($object->supplierprices); // Mut use another API to get them + if (empty(DolibarrApiAccess::$user->rights->stock->lire)) { + unset($object->stock_reel); + unset($object->stock_theorique); + } return $object; } @@ -2008,7 +2012,7 @@ class Products extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - if ($includestockdata) { + if ($includestockdata && DolibarrApiAccess::$user->rights->stock->lire) { $this->product->load_stock(); if (is_array($this->product->stock_warehouse)) { diff --git a/htdocs/product/class/html.formproduct.class.php b/htdocs/product/class/html.formproduct.class.php index 64517c25443..da10faa4f34 100644 --- a/htdocs/product/class/html.formproduct.class.php +++ b/htdocs/product/class/html.formproduct.class.php @@ -543,7 +543,7 @@ class FormProduct { global $conf, $langs; - dol_syslog(get_class($this)."::selectLot $selected, $htmlname, $filterstatus, $empty, $disabled, $fk_product, $fk_entrepot, $empty_label, $forcecombo, $morecss", LOG_DEBUG); + dol_syslog(get_class($this)."::selectLotStock $selected, $htmlname, $filterstatus, $empty, $disabled, $fk_product, $fk_entrepot, $empty_label, $forcecombo, $morecss", LOG_DEBUG); $out = ''; $productIdArray = array(); @@ -591,6 +591,7 @@ class FormProduct } $out .= ''; } } diff --git a/htdocs/resource/contact.php b/htdocs/resource/contact.php index 811bb476430..aca47d49743 100644 --- a/htdocs/resource/contact.php +++ b/htdocs/resource/contact.php @@ -38,14 +38,21 @@ $id = GETPOST('id', 'int'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); +$object = new DolResource($db); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + // Security check if ($user->socid) { $socid = $user->socid; } -$result = restrictedArea($user, 'resource', $id, 'resource'); +$result = restrictedArea($user, 'resource', $object->id, 'resource'); -$object = new DolResource($db); -$result = $object->fetch($id, $ref); +// Security check +if (!$user->rights->resource->read) { + accessforbidden(); +} /* diff --git a/htdocs/resource/document.php b/htdocs/resource/document.php index fec869d5620..001598d2023 100644 --- a/htdocs/resource/document.php +++ b/htdocs/resource/document.php @@ -70,11 +70,17 @@ if (!$sortfield) { $object = new DolResource($db); -$object->fetch($id, $ref); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. $upload_dir = $conf->resource->dir_output.'/'.dol_sanitizeFileName($object->ref); $modulepart = 'resource'; +$result = restrictedArea($user, 'resource', $object->id, 'resource'); + +$permissiontoadd = $user->rights->resource->write; // Used by the include of actions_addupdatedelete.inc.php and actions_linkedfiles + /* * Actions diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index 4d0736c5f64..7b74283d90a 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -76,6 +76,19 @@ if ($socid > 0) { // Special for thirdparty $element = 'societe'; } +// Permission is not permission on resources. We just make link here on objects. +if ($element == 'action') { + $result = restrictedArea($user, 'agenda', $element_id, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id'); +} +if ($element == 'fichinter') { + $result = restrictedArea($user, 'ficheinter', $element_id, 'fichinter'); +} +if ($element == 'product' || $element == 'service') { // When RESOURCE_ON_PRODUCTS or RESOURCE_ON_SERVICES is set + $tmpobject = new Product($db); + $tmpobject->fetch($element_id); + $fieldtype = $tmpobject->type; + $result = restrictedArea($user, 'produit|service', $element_id, 'product&product', '', '', $fieldtype); +} /* @@ -336,9 +349,7 @@ if (!$ret) { if (!empty($act->fk_project)) { $proj = new Project($db); $proj->fetch($act->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); if ($proj->title) { $morehtmlref .= ' - '.$proj->title; } @@ -370,9 +381,9 @@ if (!$ret) { // Date start print ''.$langs->trans("DateActionStart").''; if (!$act->fulldayevent) { - print dol_print_date($act->datep, 'dayhour'); + print dol_print_date($act->datep, 'dayhour', 'tzuser'); } else { - print dol_print_date($act->datep, 'day'); + print dol_print_date($act->datep, 'day', 'tzuser'); } if ($act->percentage == 0 && $act->datep && $act->datep < ($now - $delay_warning)) { print img_warning($langs->trans("Late")); @@ -383,9 +394,9 @@ if (!$ret) { // Date end print ''.$langs->trans("DateActionEnd").''; if (!$act->fulldayevent) { - print dol_print_date($act->datef, 'dayhour'); + print dol_print_date($act->datef, 'dayhour', 'tzuser'); } else { - print dol_print_date($act->datef, 'day'); + print dol_print_date($act->datef, 'day', 'tzuser'); } if ($act->percentage > 0 && $act->percentage < 100 && $act->datef && $act->datef < ($now - $delay_warning)) { print img_warning($langs->trans("Late")); @@ -502,7 +513,7 @@ if (!$ret) { $morehtmlref .= '
    '.$langs->trans('Project').' '; if ($user->rights->commande->creer) { if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; + //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; $morehtmlref .= ' : '; } if ($action == 'classify') { @@ -520,9 +531,10 @@ if (!$ret) { if (!empty($fichinter->fk_project)) { $proj = new Project($db); $proj->fetch($fichinter->fk_project); - $morehtmlref .= ''; - $morehtmlref .= $proj->ref; - $morehtmlref .= ''; + $morehtmlref .= ' : '.$proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.$proj->title; + } } else { $morehtmlref .= ''; } diff --git a/htdocs/resource/list.php b/htdocs/resource/list.php index 356df3a746e..025ec2fbf70 100644 --- a/htdocs/resource/list.php +++ b/htdocs/resource/list.php @@ -61,50 +61,8 @@ $search_type = GETPOST("search_type", 'alpha'); // Load variable for pagination $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; - $filter = array(); -$param = ''; -if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { - $param .= '&contextpage='.urlencode($contextpage); -} -if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); -} - -if ($search_ref != '') { - $param .= '&search_ref='.urlencode($search_ref); - $filter['t.ref'] = $search_ref; -} -if ($search_type != '') { - $param .= '&search_type='.urlencode($search_type); - $filter['ty.label'] = $search_type; -} - -// Add $param from extra fields -foreach ($search_array_options as $key => $val) { - $crit = $val; - $tmpkey = preg_replace('/search_options_/', '', $key); - $typ = $extrafields->attributes[$object->table_element]['type'][$tmpkey]; - if ($val != '') { - $param .= '&search_options_'.$tmpkey.'='.urlencode($val); - } - $mode_search = 0; - if (in_array($typ, array('int', 'double', 'real'))) { - $mode_search = 1; // Search on a numeric - } - if (in_array($typ, array('sellist', 'link')) && $crit != '0' && $crit != '-1') { - $mode_search = 2; // Search on a foreign key int - } - if ($crit != '' && (!in_array($typ, array('select', 'sellist')) || $crit != '0') && (!in_array($typ, array('link')) || $crit != '-1')) { - $filter['ef.'.$tmpkey] = natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} -if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { - $param .= '&contextpage='.urlencode($contextpage); -} - - $hookmanager->initHooks(array('resourcelist')); if (empty($sortorder)) { @@ -126,9 +84,6 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; -if (!$user->rights->resource->read) { - accessforbidden(); -} $arrayfields = array( 't.ref' => array( 'label' => $langs->trans("Ref"), @@ -156,11 +111,23 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $filter = array(); } +if (empty($user->rights->resource->read)) { + accessforbidden(); +} + /* - * Action + * 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) { @@ -174,8 +141,42 @@ if ($reshook < 0) { $form = new Form($db); +//$help_url="EN:Module_MyObject|FR:Module_MyObject_FR|ES:Módulo_MyObject"; +$help_url = ''; $pagetitle = $langs->trans('ResourcePageIndex'); -llxHeader('', $pagetitle, ''); +llxHeader('', $pagetitle, $help_url); + + +$sql = ''; +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; + +$param = ''; +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage='.urlencode($contextpage); +} +if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.urlencode($limit); +} + +if ($search_ref != '') { + $param .= '&search_ref='.urlencode($search_ref); + $filter['t.ref'] = $search_ref; +} +if ($search_type != '') { + $param .= '&search_type='.urlencode($search_type); + $filter['ty.label'] = $search_type; +} + +// Including the previous script generate the correct SQL filter for all the extrafields +// we are playing with the behaviour of the Dolresource::fetch_all() by generating a fake +// extrafields filter key to make it works +$filter['ef.resource'] = $sql; + +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param .= '&contextpage='.urlencode($contextpage); + +// Add $param from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; + // Confirmation suppression resource line if ($action == 'delete_resource') { @@ -185,6 +186,7 @@ if ($action == 'delete_resource') { $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); + print '
    '; if ($optioncss != '') { print ''; diff --git a/htdocs/resource/note.php b/htdocs/resource/note.php index b43c9f8cb37..98efb72d55b 100644 --- a/htdocs/resource/note.php +++ b/htdocs/resource/note.php @@ -43,10 +43,12 @@ if ($user->socid) { // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('resourcenote')); -$result = restrictedArea($user, 'resource', $id, 'resource'); - $object = new DolResource($db); -$object->fetch($id, $ref); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once. + +$result = restrictedArea($user, 'resource', $object->id, 'resource'); $permissionnote = $user->rights->resource->write; // Used by the include of actions_setnotes.inc.php diff --git a/htdocs/salaries/admin/salaries.php b/htdocs/salaries/admin/salaries.php index f8ed3f3f7ce..1c9eeec6464 100644 --- a/htdocs/salaries/admin/salaries.php +++ b/htdocs/salaries/admin/salaries.php @@ -120,7 +120,7 @@ foreach ($list as $key) { // Value print ''; if (!empty($conf->accounting->enabled)) { - print $formaccounting->select_account($conf->global->$key, $key, 1, '', 1, 1); + print $formaccounting->select_account(getDolGlobalString($key), $key, 1, '', 1, 1); } else { print ''; } diff --git a/htdocs/salaries/admin/salaries_extrafields.php b/htdocs/salaries/admin/salaries_extrafields.php index 38303518ac4..2354da8048a 100644 --- a/htdocs/salaries/admin/salaries_extrafields.php +++ b/htdocs/salaries/admin/salaries_extrafields.php @@ -42,7 +42,7 @@ foreach ($tmptype2label as $key => $val) { $action = GETPOST('action', 'aZ09'); $attrname = GETPOST('attrname', 'alpha'); -$elementtype = 'payment_salary'; //Must be the $table_element of the class that manage extrafield +$elementtype = 'salary'; //Must be the $table_element of the class that manage extrafield if (!$user->admin) { accessforbidden(); diff --git a/htdocs/salaries/ajax/ajaxsalaries.php b/htdocs/salaries/ajax/ajaxsalaries.php new file mode 100644 index 00000000000..dc7715ff6ba --- /dev/null +++ b/htdocs/salaries/ajax/ajaxsalaries.php @@ -0,0 +1,73 @@ + + * 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/salaries/ajax/ajaxsalaries.php + * \brief File to return Ajax response on salary 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'; +require_once DOL_DOCUMENT_ROOT.'/salaries/class/salary.class.php'; + +restrictedArea($user, 'salaries'); + +$fk_user = GETPOST('fk_user', 'int'); +$return_arr = array(); +if (!empty(GETPOST('fk_user', 'int'))) { + $sql = "SELECT s.amount, s.rowid FROM ".MAIN_DB_PREFIX."salary as s"; + $sql .= " WHERE s.fk_user = ".((int) $fk_user); + $sql .= " AND s.paye = 1"; + $sql .= $db->order("s.dateep", "DESC"); + + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + $label = "Salary amount"; + $row_array['label'] = $label; + $row_array['value'] = $obj->amount; + $row_array['key'] = "Amount"; + + 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/salaries/card.php b/htdocs/salaries/card.php index ca111adf4d1..3caf2afa7bd 100755 --- a/htdocs/salaries/card.php +++ b/htdocs/salaries/card.php @@ -48,9 +48,13 @@ $id = GETPOSTINT('id'); $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'aZ09'); -$accountid = GETPOST('accountid', 'int') > 0 ? GETPOST('accountid', 'int') : 0; -$projectid = (GETPOST('projectid', 'int') ? GETPOST('projectid', 'int') : GETPOST('fk_project', 'int')); +$backtopage = GETPOST('backtopage', 'alpha'); +$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); $confirm = GETPOST('confirm'); + +$label = GETPOST('label', 'alphanohtml'); +$projectid = (GETPOST('projectid', 'int') ? GETPOST('projectid', 'int') : GETPOST('fk_project', 'int')); +$accountid = GETPOST('accountid', 'int') > 0 ? GETPOST('accountid', 'int') : 0; if (GETPOSTISSET('auto_create_paiement') || $action === 'add') { $auto_create_paiement = GETPOST("auto_create_paiement", "int"); } else { @@ -61,21 +65,33 @@ $datep = dol_mktime(12, 0, 0, GETPOST("datepmonth", 'int'), GETPOST("datepday", $datev = dol_mktime(12, 0, 0, GETPOST("datevmonth", 'int'), GETPOST("datevday", 'int'), GETPOST("datevyear", 'int')); $datesp = dol_mktime(12, 0, 0, GETPOST("datespmonth", 'int'), GETPOST("datespday", 'int'), GETPOST("datespyear", 'int')); $dateep = dol_mktime(12, 0, 0, GETPOST("dateepmonth", 'int'), GETPOST("dateepday", 'int'), GETPOST("dateepyear", 'int')); -$label = GETPOST('label', 'alphanohtml'); $fk_user = GETPOSTINT('userid'); $object = new Salary($db); $extrafields = new ExtraFields($db); +$childids = $user->getAllChildIds(1); + // fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('salarycard', 'globalcard')); -$object = new Salary($db); if ($id > 0 || !empty($ref)) { $object->fetch($id, $ref); + + // Check current user can read this salary + $canread = 0; + if (!empty($user->rights->salaries->readall)) { + $canread = 1; + } + if (!empty($user->rights->salaries->read) && $object->fk_user > 0 && in_array($object->fk_user, $childids)) { + $canread = 1; + } + if (!$canread) { + accessforbidden(); + } } // Security check @@ -83,6 +99,7 @@ $socid = GETPOSTINT('socid'); if ($user->socid) { $socid = $user->socid; } + restrictedArea($user, 'salaries', $object->id, 'salary', ''); @@ -90,9 +107,39 @@ restrictedArea($user, 'salaries', $object->id, 'salary', ''); * Actions */ -if ($cancel) { - header("Location: list.php"); - exit; +$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_buildpath('/salaries/list.php', 1); + + 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_buildpath('/salaries/card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + } + } + } + + if ($cancel) { + /*var_dump($cancel); + var_dump($backtopage);exit;*/ + if (!empty($backtopageforcancel)) { + header("Location: ".$backtopageforcancel); + exit; + } elseif (!empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + $action = ''; + } } // Link to a project @@ -354,6 +401,30 @@ if ($action == 'confirm_clone' && $confirm == 'yes' && ($user->rights->salaries- } } +// Action to update one extrafield +if ($action == "update_extras" && !empty($user->rights->salaries->read)) { + $object->fetch(GETPOST('id', 'int')); + + $attributekey = GETPOST('attribute', 'alpha'); + $attributekeylong = 'options_'.$attributekey; + + if (GETPOSTISSET($attributekeylong.'day') && GETPOSTISSET($attributekeylong.'month') && GETPOSTISSET($attributekeylong.'year')) { + // This is properties of a date + $object->array_options['options_'.$attributekey] = dol_mktime(GETPOST($attributekeylong.'hour', 'int'), GETPOST($attributekeylong.'min', 'int'), GETPOST($attributekeylong.'sec', 'int'), GETPOST($attributekeylong.'month', 'int'), GETPOST($attributekeylong.'day', 'int'), GETPOST($attributekeylong.'year', 'int')); + //var_dump(dol_print_date($object->array_options['options_'.$attributekey]));exit; + } else { + $object->array_options['options_'.$attributekey] = GETPOST($attributekeylong, 'alpha'); + } + + $result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user); + if ($result > 0) { + setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); + $action = 'view'; + } else { + setEventMessages($object->error, $object->errors, 'errors'); + $action = 'edit_extras'; + } +} /* * View @@ -366,8 +437,7 @@ llxHeader("", $title, $help_url); $form = new Form($db); if (!empty($conf->projet->enabled)) $formproject = new FormProjets($db); -if ($id) { - $object = new Salary($db); +if ($id > 0) { $result = $object->fetch($id); if ($result <= 0) { dol_print_error($db); @@ -401,6 +471,12 @@ if ($action == 'create') { print ''; print ''; print ''; + if ($backtopage) { + print ''; + } + if ($backtopageforcancel) { + print ''; + } print load_fiche_titre($langs->trans("NewSalary"), '', 'salary'); @@ -466,8 +542,10 @@ if ($action == 'create') { // Amount print ''; print $form->editfieldkey('Amount', 'amount', '', $object, 0, 'string', '', 1).''; - print ''; - print ''; + print ' '; + print '