diff --git a/ChangeLog b/ChangeLog index fadc6d705bb..2a72296477c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,54 +2,255 @@ English Dolibarr ChangeLog -------------------------------------------------------------- -***** ChangeLog for 6.0.5 compared to 6.0.4 ***** -FIX: security vulnerability reported by ADLab of Venustech - CVE-2017-17897, CVE-2017-17898, CVE-2017-17899, CVE-2017-17900 -FIX: #7379: Compatibility with PRODUCT_USE_OLD_PATH_FOR_PHOTO variable -FIX: #7903 -FIX: #7933 -FIX: #8029 Unable to make leave request in holyday module -FIX: Edit accountancy account and warning message on loan -FIX: $accounts[$bid] is a label ! -FIX: $oldvatrateclean & $newvatrateclean must be set if preg_match === false -FIX: product best price on product list -FIX: search on contact list -FIX: stats trad for customerinvoice -FIX: translate unactivate on contractline - -***** ChangeLog for 6.0.4 compared to 6.0.3 ***** -FIX: #7737 -FIX: #7751 -FIX: #7756 Add better error message -FIX: #7786 -FIX: #7806 -FIX: #7824 -FIX: add line bad price and ref -FIX: A lot of several fix on local taxes and NPR tax -FIX: createfromorder -FIX: CSS for IE10 -FIX: external user cannot be set as internal -FIX: Filter type on actioncomm with multiselect doesn't work -FIX: list of donation not filtered on multicompany -FIX: list of module not complete when module mb_strlen not available -FIX: Locatax were not propagated when cloning order or proposal -FIX: Searching translation should not be case sensitive -FIX: Search into language is ok for file into external modules two. -FIX: test for filter fk_status -FIX: too much users on holiday list -FIX: Wrong alias sql - - -***** ChangeLog for 7.0.0 compared to 6.0.* ***** +***** ChangeLog for 7.0.0 compared to 6.0.5 ***** For users: +NEW: #5711 Add shipment line deleting and editing for draft shipments. +NEW: Accept substitution key __[ABC]__ replaced with value of const ABC +NEW: Accountancy Add variant on sell account for intracommunity sales & export sales +NEW: Add a button "Activate all services" on contracts +NEW: Add a confirmation for all mass action 'delete' +NEW: Add a group task line for tasks on same level on gantt diagram +NEW: Add and edit country for chart of accounts systems +NEW: add a new notification for the signed closed event of a proposal. +NEW: Add a parameter to specify char used as separator for variant product label +NEW: Add a profile to import product translations +NEW: Add a protection so we can't journalize non balanced transactions +NEW: Add a status enabled/disabled on recurring invoices +NEW: add burger menu to list action comm +NEW: Add button cancel on shipment creation +NEW: Add chart of account for england +NEW: Add Chile accounting plan +NEW: Add class in societe/card.php +NEW: add company alias name when create company from member +NEW: Add date of birth on user card. +NEW: Add date_valid and date_pointoftax on supplier invoices. +NEW: Added Region name to state/province form field +NEW: Added regions to third party/societe lists, can be filtered +NEW: Add error message +NEW: Add expense report rules and ik +NEW: Add filter on event code on automatic filling setup page +NEW: Add filters on month/year on the accountancy binding tools +NEW: add fk_unit field into product/service import/export +NEW: add 'formObjectOptions' hook to the form setting the product selling price +NEW: Add hidden option PROJECT_DISABLE_UNLINK_FROM_OVERVIEW +NEW: add image object_phoning_mobile.png +NEW: Adding Field "First date of expire" + filter on contract list +NEW: add ldap_rename for avoid password if ldap key changed +NEW: Add mass action "validate" on supplier invoices. +NEW: add members types ldap group management +NEW: Add new property visible dy default on lists on extrafields +NEW: Add Next/Previous button on operation date of bank line +NEW: Add option EXPENSEREPORT_ALLOW_OVERLAPPING_PERIODS +NEW: Add option PROPOSAL/ORDER/INVOICE_ALLOW_EXTERNAL_DOWNLOAD +NEW: Add product unit fields for ODT substitution +NEW: Add project on a various payment +NEW: Add project related fields to ODT +NEW: Add protection to avoid to send to much emails using builk actions +NEW: Add search field for date on supplier payment page +NEW: Add search on date and accounting account in various payment list +NEW: add specific translation for title of documents (Invoice, Order, Proposal) +NEW: Adds the payment reference to the return of the function getListOfPayements +NEW: Add supplier proposals into stats of product page. +NEW: Add tab "Expense report" on user card +NEW: add the ability to regenerate a pdf for the order module +NEW: Add The accountancy Switzerland chart of accounts +NEW: Add The developed French chart of accounts 2014 +NEW: Add The Luxembourg chart of accounts +NEW: Add The Moroccan chart of accounts +NEW: Add The Switzerland chart of accounts +NEW: Add The SYSCOHADA chart of accounts +NEW: Add the total in the perday view of the time spent form. +NEW: Add The Tunisia chart of accounts +NEW: Add toolkit for StockLimit and DesiredStock +NEW: add translation and possibility to change month and year +NEW: Add view of status of template invoice +NEW: All search boxes are available on smartphone +NEW: All setup of accountancy can be done from menu "Accountancy-Setup" +NEW: Attaching doc automatically in email is now a parameter of template. +NEW: automatic activation of external module on country set +NEW: Better autoselect customer or supplier fields to save clicks +NEW: Better behaviour when using a text browser +NEW: Break lines per project on the new timesheet page +NEW: Bulk action validate on customer invoices +NEW: Bulk delete actions available on leave requests +NEW: burger menu and hooks on list action +NEW: Can add html content on right of tabs +NEW: Can add link to other element on a donation +NEW: Can create intervention from a proposal +NEW: Can create thirdparty from card proposal, order or invoice +NEW: Can download PDF document from the payment page +NEW: Can edit the language into the email templates editor. +NEW: Can edit with delete/insert a forced translation +NEW: Can export list of stock movements +NEW: Can filter on date on the page showing existing bindings +NEW: Can filter on document name in ECM module for automatic tree +NEW: can filter on status of template invoices +NEW: Can filter on the "other" column on emailing target list +NEW: Can filter on type of email template +NEW: Can filter on user on unalterable log +NEW: Can import local tax rates in prices +NEW: Can include extrafields into member card templates +NEW: Can include tag {uuu} into some numbering masks to replace with user +NEW: Can make a specific setup for SMTP sending for emailing module +NEW: Can rename (so reorder) bank receipts +NEW: Can send email from contract card +NEW: Can send email from the member card using email templates. +NEW: Can set a dedicated message on payment forms +NEW: Can set email of thirdparty as unique and/or mandatory +NEW: Can setup csv accounting export from admin config +NEW: Can show currency in list of bank accounts +NEW: Can show stock in alert even if alter is set to 0 +NEW: Can sort joined files on thirdparty and user card. +NEW: Can transfer from bank account to bank account with different currencies +NEW: Can use an url like $conf->global>-MYPARAM for menu urls +NEW: change description on click +NEW: Chart of account is loaded when selected into accounting setup +NEW: Classify the order as invoiced in the REST API +NEW: comments system on task +NEW: comment system working with all objects +NEW: Compatibility with PHP 7.2 +NEW: confirm form style to accept or reject proposal +NEW: Create an invoice using an existing order +NEW: Create an order using an existing proposal +NEW: customizable meteo in value or percentage +NEW: Days where user is on vacation use different colors in timesheet. +NEW: Deduct an available credit to an existing invoice +NEW: Default filter and sort order can use partial list of query +NEW: Deposit invoice more explicit in invoice line description +NEW: deposits can be converted even if unpaid +NEW: detection of edge browser +NEW: Each user can edit its own email template (menu tools) +NEW: Enabled sending email in bulk actions for supplier orders +NEW: Enhance the anti XSS filter +NEW: extrafield on facture_rec +NEW: Extrafields "link to object" now use a combo selection and getNomUrl +NEW: filter date for blockedlog +NEW: filter on extrafield on product list (as in company list) +NEW: General ledger : Add field date_creation and selected field +NEW: generate also document when invoice is build from recurring template +NEW: Generated files are now indexed in database +NEW: generate invoice PDF on disount application or payment +NEW: Get a list of payments terms +NEW: hrm details output on user +NEW: If max nb of generation is reached, date for next gen is striked +NEW: improvements of invoices, orders and proposals in the REST API +NEW: Include a color syntaxed HTML editor for emailing edition. +NEW: Introduce code syntax coloration with mode 'ace' for DolEditor. +NEW: Introduce experimental feature to search dolistore from application +NEW: jquery date selector become default date selector +NEW: langs +NEW: link project from other company conf +NEW: manageme extrafields with multientity +NEW: Mass PDF Merging is available on contracts +NEW: merge categories while merging thirdparties +NEW: Merge resource/add.php to resource/card.php +NEW: Module "Product variants" is moved as stable. +NEW: More picto for phone +NEW: Move accountancy features into a dedicated menu +NEW: Move contacts of a thirdparty on tab Contacts/Addresses +NEW: Move the upload input on top right in ECM module +NEW: new columns into extrafields table to get update create information +NEW: new param on load_board() function in ActionComm class to avoid duplicate code +NEW: On bulk email from a list, can uncheck "Join main document". +NEW: On reconciliation, show balance including all reconciliated fields +NEW: Option "one email per recipient" when using bulk actions emails. +NEW: Option STOCK_SUPPORTS_SERVICES become visible. +NEW: option to avoid countries to disable there blockedlog +NEW: option to fix top menu with eldy theme (hidden conf) +NEW: Popup for preview of image add a button "Original size" +NEW: post lines of an invoice using the REST API +NEW: preload comments in task +NEW: Provide a way to download a file from a public URL for files in ECM +NEW: Reduce size of HTML page by removing duplicate tooltips +NEW: Remove background on agenda view when event is a not busy event. +NEW: Retrieves available discounts and payments details from a specific invoice +NEW: Revenue stamp can be a percent +NEW: Search filters in lists are restored when using "back to list" +NEW: Send by email available in bulk for expense report +NEW: Set a proposal to draft +NEW: Show badge with nbr of shipment on shimpen tab of order +NEW: Show country and vat number into company tooltip +NEW: Show direct preview link on contract +NEW: Show expected worked hours on the timesheet form. +NEW: Show line "other filtered task" when using filter on timesheet. +NEW: Show list of tracked events into the module config page. +NEW: Show the supplier ref into supplier cards +NEW: Show user id of web process in system info - web server +NEW: Summary of last events on a card are sorted on decreasing date. +NEW: Support Italian addresses format. Fixes #7785 +NEW: Support visibility on extrafields +NEW: Template invoices are visible on the customer tab +NEW: template invoices support substition key +NEW: The bank account is visible on payment of taxes +NEW: The comment when closing a proposal is added to commercial proposal +NEW: The gantt diagram is now sensitive to hours +NEW: The lot of a product uses the link and picto when shown into list. +NEW: The "Show detail by account" accepts 3 values: yes, no, if non zero +NEW: The unalterable log can be browse by any user with he permission +NEW: Tooltip for substitutions variables on tooltips on admin pages +NEW: unexistant function load_state_board() on several objects +NEW: Update availability +NEW: Update bank account when updating an invoice +NEW: Update bank account when updating an order +NEW: Use autocompletion on selection of chart of account +NEW: view company name if different of fullname in dol_banner +NEW: warning on module blocked log reset if country code is FR For developers: +NEW: Add 2 new automatic classification in workflow module +NEW: Add API for contracts +NEW: Add API to activate/unactivate a contract +NEW: Add api validate and close on contracts +NEW: add doActions hook in admin ihm +NEW: add doActions hook in company admin +NEW: Added functionality to get order customer contact as contact_xx tags NEW: Add hook addAdminLdapOptions and doAction in ldap admin page +NEW: Add method executeCLI and a phpunit +NEW: add '$moreatt' parameter in picto_from_langcode function +NEW: Add non intrusive js library to make syntaxic coloring of textarea +NEW: Add payment line to a specific invoice using the REST API +NEW: add possibility to disabled the LDAP trigger +NEW: add possibility to hide LDAP tab for non admin +NEW: Add possibility to propose last num releve in conciliation +NEW: add possibility to remove address field +NEW: Add REST API for supplier proposals +NEW: Add REST API to add payment line to a specific invoice +NEW: Add the attribute accept to the input form for file upload +NEW: add translation column for extrafields list +NEW: Add performances indexes on calendar events +NEW: A module can change order of element in the quick search combo +NEW: Can test signature of a version from API NEW: complete_head_from_modules() in ldap_prepare_head() +NEW: Consolidates REST dictionary APIs into a single tree and a single file +NEW: Delete a line of invoice using the REST API +NEW: documents REST API return list of documents by element +NEW: Download a document using the REST API +NEW: Enhance framework so we can use html/icons into SELECT options. +NEW: External module can interact with the customer summary page +NEW: Generates the document before downloading using REST API +NEW: get and post lines of an invoice using the REST API +NEW: Get a payment list of a given invoice using the REST API +NEW: Get available assets of an invoice using the REST API +NEW: Get credit notes or deposits of a thirdparty +NEW: GET lines of an invoice in the REST API +NEW: get payment types using the REST API + consolidates REST dictionary APIs +NEW: Get the list of payments terms. +NEW: hook formObjectOptions in the form setting product selling price +NEW: hook to enrich homepage open elements dashboard +NEW: Insert a discount in a specific invoice using the REST API +NEW: Remove js library fileupload that was not used by core code. +NEW: Remove tooltip tipTip library replaced with standatd jquery tooltip +NEW: Set invoices as draft using the REST API +NEW: Sets an invoice as paid using the REST API +NEW: Tag the order as validated (opened) in the REST API +NEW: Update end of validity date of proposal using the API +NEW: Update in the order REST API +NEW: Upgrade jquery select2 to 4.0.4 -WARNING: -If you enabled (for test) the experimental BlockedLog module before 7.0, you must purge the table llx_blockedlog because +WARNING: + +If you enabled (for test) the experimental BlockedLog module before 7.0, you must purge the table llx_blockedlog because way to save data for final version has changed. Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: @@ -76,6 +277,51 @@ Following changes may create regressions for some external modules, but were nec * IE8 and earlier and Firefox 12 and earlier (< 2012) are no more supported. +***** ChangeLog for 6.0.5 compared to 6.0.4 ***** +FIX: security vulnerability reported by ADLab of Venustech + CVE-2017-17897, CVE-2017-17898, CVE-2017-17899, CVE-2017-17900 +FIX: #7379: Compatibility with PRODUCT_USE_OLD_PATH_FOR_PHOTO variable +FIX: #7903 +FIX: #7933 +FIX: #8029 Unable to make leave request in holyday module +FIX: #8093 +FIX: Bad name alias showing in name of third column +FIX: Cashdesk should not sell to inactive third parties +FIX: Edit accountancy account and warning message on loan +FIX: $accounts[$bid] is a label ! +FIX: $oldvatrateclean & $newvatrateclean must be set if preg_match === false +FIX: product best price on product list +FIX: search on contact list +FIX: stats trad for customerinvoice +FIX: translate unactivate on contractline +FIX: email sent was not in HTML +FIX: missing hook invoice index +FIX: subject mail sepa + + +***** ChangeLog for 6.0.4 compared to 6.0.3 ***** +FIX: #7737 +FIX: #7751 +FIX: #7756 Add better error message +FIX: #7786 +FIX: #7806 +FIX: #7824 +FIX: add line bad price and ref +FIX: A lot of several fix on local taxes and NPR tax +FIX: createfromorder +FIX: CSS for IE10 +FIX: external user cannot be set as internal +FIX: Filter type on actioncomm with multiselect doesn't work +FIX: list of donation not filtered on multicompany +FIX: list of module not complete when module mb_strlen not available +FIX: Locatax were not propagated when cloning order or proposal +FIX: Searching translation should not be case sensitive +FIX: Search into language is ok for file into external modules two. +FIX: test for filter fk_status +FIX: too much users on holiday list +FIX: Wrong alias sql + + ***** ChangeLog for 6.0.3 compared to 6.0.2 ***** FIX: #7211 Update qty dispatched on qty change FIX: #7458 diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index bc755ef52a3..7da6d180dcb 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -19,7 +19,7 @@ use Term::ANSIColor; # Change this to defined target for option 98 and 99 $PROJECT="dolibarr"; $PUBLISHSTABLE="eldy,dolibarr\@frs.sourceforge.net:/home/frs/project/dolibarr"; -$PUBLISHBETARC="ldestailleur\@vmprod.dolibarr.org:/home/dolibarr/dolibarr.org/httpdocs/files"; +$PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/dolibarr.org/httpdocs/files"; #@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","APS","EXEDOLIWAMP","SNAPSHOT"); # Possible packages diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index a1fc7c87d68..438c7cd5227 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -187,7 +187,7 @@ $tabsql[9] = "SELECT c.code_iso as code, c.label, c.unicode, c.active FROM ".MAI $tabsql[10]= "SELECT t.rowid, t.code, t.taux, t.localtax1_type, t.localtax1, t.localtax2_type, t.localtax2, c.label as country, c.code as country_code, t.fk_pays as country_id, t.recuperableonly, t.note, t.active, t.accountancy_code_sell, t.accountancy_code_buy FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c WHERE t.fk_pays=c.rowid"; $tabsql[11]= "SELECT t.rowid as rowid, t.element, t.source, t.code, t.libelle, t.position, t.active FROM ".MAIN_DB_PREFIX."c_type_contact AS t"; $tabsql[12]= "SELECT c.rowid as rowid, c.code, c.libelle, c.libelle_facture, c.nbjour, c.type_cdr, c.decalage, c.active, c.sortorder, c.entity FROM ".MAIN_DB_PREFIX."c_payment_term AS c WHERE c.entity = " . getEntity($tabname[12]); -$tabsql[13]= "SELECT c.id as rowid, c.code, c.libelle, c.type, c.active, c.accountancy_code, c.entity FROM ".MAIN_DB_PREFIX."c_paiement AS c WHERE c.entity = " . getEntity($tabname[13]); +$tabsql[13]= "SELECT c.id as rowid, c.code, c.libelle, c.type, c.active, c.entity FROM ".MAIN_DB_PREFIX."c_paiement AS c WHERE c.entity = " . getEntity($tabname[13]); $tabsql[14]= "SELECT e.rowid as rowid, e.code as code, e.libelle, e.price, e.organization, e.fk_pays as country_id, c.code as country_code, c.label as country, e.active FROM ".MAIN_DB_PREFIX."c_ecotaxe AS e, ".MAIN_DB_PREFIX."c_country as c WHERE e.fk_pays=c.rowid and c.active=1"; $tabsql[15]= "SELECT rowid as rowid, code, label as libelle, width, height, unit, active FROM ".MAIN_DB_PREFIX."c_paper_format"; $tabsql[16]= "SELECT code, label as libelle, sortorder, active FROM ".MAIN_DB_PREFIX."c_prospectlevel"; @@ -265,7 +265,7 @@ $tabfield[9] = "code,label,unicode"; $tabfield[10]= "country_id,country,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfield[11]= "element,source,code,libelle,position"; $tabfield[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder,entity"; -$tabfield[13]= "code,libelle,type,accountancy_code,entity"; +$tabfield[13]= "code,libelle,type,entity"; $tabfield[14]= "code,libelle,price,organization,country_id,country"; $tabfield[15]= "code,libelle,width,height,unit"; $tabfield[16]= "code,libelle,sortorder"; @@ -304,7 +304,7 @@ $tabfieldvalue[9] = "code,label,unicode"; $tabfieldvalue[10]= "country,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldvalue[11]= "element,source,code,libelle,position"; $tabfieldvalue[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder"; -$tabfieldvalue[13]= "code,libelle,type,accountancy_code"; +$tabfieldvalue[13]= "code,libelle,type"; $tabfieldvalue[14]= "code,libelle,price,organization,country"; $tabfieldvalue[15]= "code,libelle,width,height,unit"; $tabfieldvalue[16]= "code,libelle,sortorder"; @@ -343,7 +343,7 @@ $tabfieldinsert[9] = "code_iso,label,unicode"; $tabfieldinsert[10]= "fk_pays,code,taux,localtax1_type,localtax1,localtax2_type,localtax2,recuperableonly,accountancy_code_sell,accountancy_code_buy,note"; $tabfieldinsert[11]= "element,source,code,libelle,position"; $tabfieldinsert[12]= "code,libelle,libelle_facture,nbjour,type_cdr,decalage,sortorder,entity"; -$tabfieldinsert[13]= "code,libelle,type,accountancy_code,entity"; +$tabfieldinsert[13]= "code,libelle,type,entity"; $tabfieldinsert[14]= "code,libelle,price,organization,fk_pays"; $tabfieldinsert[15]= "code,label,width,height,unit"; $tabfieldinsert[16]= "code,label,sortorder"; diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php index 633f84b6582..08b384d7ac5 100644 --- a/htdocs/blockedlog/admin/blockedlog_list.php +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -359,7 +359,8 @@ print ''; // User print ''; -print $form->select_dolusers($search_fk_user, 'search_fk_user', 1); +print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, '', '', 0, 0, 0, '', 0, '', 'maxwidth300'); + print ''; // Actions code diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index b4c0c8e6ef8..2f3c5d60640 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -742,7 +742,9 @@ class BlockedLog } /** - * Return a string for signature + * Return a string for signature. + * Note: rowid of line not included as it is not a business data and this allow to make backup of a year + * and restore it into another database with different id wihtout comprimising checksums * * @return string Key for signature */ diff --git a/htdocs/categories/viewcat.php b/htdocs/categories/viewcat.php index daa5ade05b5..255dc4888aa 100644 --- a/htdocs/categories/viewcat.php +++ b/htdocs/categories/viewcat.php @@ -353,7 +353,7 @@ if ($type == Categorie::TYPE_PRODUCT) print "
"; print "\n"; - print '\n"; + print '\n"; if (count($prods) > 0) { @@ -402,7 +402,7 @@ if ($type == Categorie::TYPE_SUPPLIER) { print "
"; print '
'.$langs->trans("ProductsAndServices")."
'.$langs->trans("ProductsAndServices")." (".count($prods).")
'."\n"; - print '\n"; + print '\n"; if (count($socs) > 0) { @@ -451,7 +451,7 @@ if($type == Categorie::TYPE_CUSTOMER) { print "
"; print '
'.$langs->trans("Suppliers")."
'.$langs->trans("Suppliers")." (".count($socs).")
'."\n"; - print '\n"; + print '\n"; if (count($socs) > 0) { @@ -507,7 +507,7 @@ if ($type == Categorie::TYPE_MEMBER) { print "
"; print "
'.$langs->trans("Customers")."
'.$langs->trans("Customers")." (".count($socs).")
\n"; - print '\n"; + print '\n"; if (count($prods) > 0) { @@ -558,7 +558,7 @@ if ($type == Categorie::TYPE_CONTACT) { print "
"; print '
'.$langs->trans("Member")."
'.$langs->trans("Member")." (".count($prods).")
'."\n"; - print '\n"; + print '\n"; if (count($contacts) > 0) { @@ -613,7 +613,7 @@ if ($type == Categorie::TYPE_ACCOUNT) { print "
"; print "
'.$langs->trans("Contact")."
'.$langs->trans("Contact")." (".count($contacts).")
\n"; - print '\n"; + print '\n"; if (count($accounts) > 0) { @@ -666,7 +666,7 @@ if ($type == Categorie::TYPE_PROJECT) { print "
"; print "
'.$langs->trans("Account")."
'.$langs->trans("Account")." (".count($accounts).")
\n"; - print '\n"; + print '\n"; if (count($projects) > 0) { diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 8fb590d61b4..fa2af2dc3eb 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -211,7 +211,7 @@ if ($id > 0 && empty($object->id)) { // Load data of third party $res=$object->fetch($id); - if ($object->id <= 0) dol_print_error($db,$object->error,$object->errors); + if ($object->id < 0) dol_print_error($db, $object->error, $object->errors); } $title=$langs->trans("CustomerCard"); @@ -220,7 +220,7 @@ $help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; llxHeader('',$title,$help_url); -if ($id > 0) +if ($object->id > 0) { $head = societe_prepare_head($object); @@ -1271,7 +1271,8 @@ if ($id > 0) } else { - dol_print_error($db,'Bad value for socid parameter'); + $langs->load("errors"); + print $langs->trans('ErrorRecordNotFound'); } // End of page diff --git a/htdocs/core/actions_fetchobject.inc.php b/htdocs/core/actions_fetchobject.inc.php index e42c2e9a83b..780895e47a9 100644 --- a/htdocs/core/actions_fetchobject.inc.php +++ b/htdocs/core/actions_fetchobject.inc.php @@ -40,7 +40,13 @@ if (($id > 0 || (! empty($ref) && ! in_array($action, array('create', 'createtas } else { - if (empty($object->error) && ! count($object->errors)) setEventMessages('Fetch on object return an error without filling $object->error nor $object->errors', null, 'errors'); + if (empty($object->error) && ! count($object->errors)) + { + if ($ret < 0) // if $ret == 0, it means not found. + { + setEventMessages('Fetch on object (type '.get_class($object).') return an error without filling $object->error nor $object->errors', null, 'errors'); + } + } else setEventMessages($object->error, $object->errors, 'errors'); $action=''; } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index c7b2d394a4b..bc37c428bb6 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -111,6 +111,9 @@ class ExtraFields { $this->db = $db; $this->error = array(); + $this->attributes = array(); + + // For old usage $this->attribute_elementtype = array(); $this->attribute_type = array(); $this->attribute_label = array(); @@ -140,15 +143,15 @@ class ExtraFields * @param array|string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) ) * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check - * @param int $list Visibilty - * @param int $ishidden Deprecated. Use visibility instead. + * @param int $list Visibilty (0=never visible, 1=visible on list+forms, 2=list onyl, 3=form only) + * @param int $notused Deprecated. * @param string $computed Computed value * @param string $entity Entity of extrafields (for multicompany modules) * @param string $langfile Language file * @param string $enabled Condition to have the field enabled or not * @return int <=0 if KO, >0 if OK */ - function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $computed='', $entity='', $langfile='', $enabled='1') + function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=-1, $notused=0, $computed='', $entity='', $langfile='', $enabled='1') { if (empty($attrname)) return -1; if (empty($label)) return -1; @@ -165,7 +168,7 @@ class ExtraFields if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') { // Add declaration of field into table - $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $ishidden, $default, $computed, $entity, $langfile, $enabled); + $result2=$this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $notused, $default, $computed, $entity, $langfile, $enabled); $err2=$this->errno; if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')) { @@ -282,7 +285,7 @@ class ExtraFields * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check * @param int $list Visibily - * @param int $ishidden Deprecated. Use visibility instead. + * @param int $notused Deprecated. * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields @@ -290,7 +293,7 @@ class ExtraFields * @param string $enabled Condition to have the field enabled or not * @return int <=0 if KO, >0 if OK */ - private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $default='', $computed='',$entity='', $langfile='', $enabled='1') + private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=-1, $notused=0, $default='', $computed='',$entity='', $langfile='', $enabled='1') { global $conf,$user; @@ -308,7 +311,7 @@ class ExtraFields { if(is_array($param) && count($param) > 0) { - $params = $this->db->escape(serialize($param)); + $params = serialize($param); } elseif (strlen($param) > 0) { @@ -490,7 +493,7 @@ class ExtraFields * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check * @param int $list Visibility - * @param int $ishidden Deprecated. Use visiblity instead. + * @param int $notused Deprecated. * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields @@ -498,7 +501,7 @@ class ExtraFields * @param string $enabled Condition to have the field enabled or not * @return int >0 if OK, <=0 if KO */ - function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $ishidden=0, $default='', $computed='', $entity='', $langfile='', $enabled='1') + function update($attrname, $label, $type, $length, $elementtype, $unique=0, $required=0, $pos=0, $param='', $alwayseditable=0, $perms='', $list='', $notused=0, $default='', $computed='', $entity='', $langfile='', $enabled='1') { if ($elementtype == 'thirdparty') $elementtype='societe'; if ($elementtype == 'contact') $elementtype='socpeople'; @@ -546,7 +549,7 @@ class ExtraFields { if ($label) { - $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$ishidden,$default,$computed,$entity,$langfile,$enabled); + $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$notused,$default,$computed,$entity,$langfile,$enabled); } if ($result > 0) { @@ -597,7 +600,7 @@ class ExtraFields * @param int $alwayseditable Is attribute always editable regardless of the document status * @param string $perms Permission to check * @param int $list Visiblity - * @param int $ishidden Deprecated. Use visility instead. + * @param int $notused Deprecated. * @param string $default Default value (in database. use the default_value feature for default value on screen). * @param string $computed Computed value * @param string $entity Entity of extrafields @@ -605,10 +608,10 @@ class ExtraFields * @param string $enabled Condition to have the field enabled or not * @return int <=0 if KO, >0 if OK */ - private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0,$ishidden=0,$default='',$computed='',$entity='',$langfile='',$enabled='1') + private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0,$notused=0,$default='',$computed='',$entity='',$langfile='',$enabled='1') { global $conf, $user; - dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$ishidden.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled); + dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$notused.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled); // Clean parameters if ($elementtype == 'thirdparty') $elementtype='societe'; diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 8ee3a8054e9..65cc2965bea 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -618,6 +618,7 @@ function security_prepare_head() // Show permissions lines + $nbPerms=0; $sql = "SELECT COUNT(r.id) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."rights_def as r"; $sql.= " WHERE r.libelle NOT LIKE 'tou%'"; // On ignore droits "tous" diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index fa8dadc4a65..9cbf52c1cc8 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -2188,7 +2188,7 @@ function dol_print_skype($skype,$cid=0,$socid=0,$addlink=0,$max=64) */ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$separ=" ",$withpicto='',$titlealt='',$adddivfloat=0) { - global $conf,$user,$langs,$mysoc; + global $conf, $user, $langs, $mysoc, $hookmanager; // Clean phone parameter $phone = preg_replace("/[\s.-]/","",trim($phone)); @@ -2278,23 +2278,33 @@ function dol_print_phone($phone,$countrycode='',$cid=0,$socid=0,$addlink='',$sep $titlealt=($withpicto=='fax'?$langs->trans("Fax"):$langs->trans("Phone")); } $rep=''; - $picto = ''; - if($withpicto){ - if($withpicto=='fax'){ - $picto = 'phoning_fax'; - }elseif($withpicto=='phone'){ - $picto = 'phoning'; - }elseif($withpicto=='mobile'){ - $picto = 'phoning_mobile'; - }else{ - $picto = ''; + + if ($hookmanager) { + $parameters = array('countrycode' => $countrycode, 'cid' => $cid, 'socid' => $socid,'titlealt' => $titlealt, 'picto' => $withpicto); + $reshook = $hookmanager->executeHooks('printPhone', $parameters, $phone); + $rep.=$hookmanager->resPrint; + } + if (empty($reshook)) + { + $picto = ''; + if($withpicto){ + if($withpicto=='fax'){ + $picto = 'phoning_fax'; + }elseif($withpicto=='phone'){ + $picto = 'phoning'; + }elseif($withpicto=='mobile'){ + $picto = 'phoning_mobile'; + }else{ + $picto = ''; + } } - } - if ($adddivfloat) $rep.='
'; - else $rep.=''; - $rep.=($withpicto?img_picto($titlealt, 'object_'.$picto.'.png').' ':'').$newphone; - if ($adddivfloat) $rep.='
'; - else $rep.=''; + if ($adddivfloat) $rep.='
'; + else $rep.=''; + $rep.=($withpicto?img_picto($titlealt, 'object_'.$picto.'.png').' ':'').$newphone; + if ($adddivfloat) $rep.='
'; + else $rep.=''; + } + return $rep; } @@ -3357,18 +3367,19 @@ function img_searchclear($titlealt = 'default', $other = '') * @param integer $infoonimgalt Info is shown only on alt of star picto, otherwise it is show on output after the star picto * @param int $nodiv No div * @param string $admin '1'=Info for admin users. '0'=Info for standard users (change only the look), 'xxx'=Other + * @param string $morecss More CSS * @return string String with info text */ -function info_admin($text, $infoonimgalt = 0, $nodiv=0, $admin='1') +function info_admin($text, $infoonimgalt = 0, $nodiv=0, $admin='1', $morecss='') { global $conf, $langs; if ($infoonimgalt) { - return img_picto($text, 'info', 'class="hideonsmartphone"'); + return img_picto($text, 'info', 'class="hideonsmartphone'.($morecss?' '.$morecss:'').'"'); } - return ($nodiv?'':'
').' '.$text.($nodiv?'':'
'); + return ($nodiv?'':'
').' '.$text.($nodiv?'':'
'); } @@ -5620,7 +5631,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob '__USER_LASTNAME__' => (string) $user->lastname, '__USER_FIRSTNAME__' => (string) $user->firstname, '__USER_FULLNAME__' => (string) $user->getFullName($outputlangs), - '__USER_SUPERVISOR_ID__' => (string) $user->fk_user + '__USER_SUPERVISOR_ID__' => (string) $user->fk_user, + '__USER_REMOTE_IP__' => (string) $_SERVER['REMOTE_ADDR'] ) ); } @@ -5634,7 +5646,11 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob /** * Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newval). - * Texts like __(TranslationKey|langfile)__ and __[ConstantKey]__ are also replaced + * Texts like __(TranslationKey|langfile)__ and __[ConstantKey]__ are also replaced. + * Example of usage: + * $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $thirdparty); + * complete_substitutions_array($substitutionarray, $langs, $thirdparty); + * $mesg = make_substitutions($mesg, $substitutionarray, $langs); * * @param string $text Source string in which we must do substitution * @param array $substitutionarray Array with key->val to substitute. Example: array('__MYKEY__' => 'MyVal', ...) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 03612250b85..c55282dc3d0 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -82,6 +82,10 @@ function dol_hash($chain, $type='0') { global $conf; + // No need to add salt for password_hash + if ($type == '0' && ! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_hash')) + return password_hash($chain, PASSWORD_DEFAULT); + // Salt value if (! empty($conf->global->MAIN_SECURITY_SALT)) $chain=$conf->global->MAIN_SECURITY_SALT.$chain; @@ -97,6 +101,32 @@ function dol_hash($chain, $type='0') return md5($chain); } +/** + * Compute a hash and compare it to the given one + * For backward compatibility reasons, if the hash is not in the password_hash format, we will try to match against md5 and sha1md5 + * If constant MAIN_SECURITY_HASH_ALGO is defined, we use this function as hashing function. + * If constant MAIN_SECURITY_SALT is defined, we use it as a salt. + * + * @param string $chain String to hash + * @param string $hash hash to compare + * @param string $type Type of hash ('0':auto, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. + * @return bool True if the computed hash is the same as the given one + */ +function dol_verifyHash($chain, $hash, $type='0') +{ + global $conf; + + if ($type == '0' && ! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_verify')) { + if ($hash[0] == '$') return password_verify($chain, $hash); + else if(strlen($hash) == 32) return dol_verifyHash($chain, $hash, '3'); // md5 + else if(strlen($hash) == 40) return dol_verifyHash($chain, $hash, '2'); // sha1md5 + + return false; + } + + return dol_hash($chain, $type) == $hash; +} + /** * Check permissions of a user to show a page and an object. Check read permission. @@ -607,4 +637,3 @@ function accessforbidden($message='',$printheader=1,$printfooter=1,$showonlymess if ($printfooter && function_exists("llxFooter")) llxFooter(); exit(0); } - diff --git a/htdocs/core/login/functions_dolibarr.php b/htdocs/core/login/functions_dolibarr.php index d8cf78747b8..25d5f2dc30c 100644 --- a/htdocs/core/login/functions_dolibarr.php +++ b/htdocs/core/login/functions_dolibarr.php @@ -84,7 +84,7 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest= // Check crypted password according to crypt algorithm if ($cryptType == 'md5') { - if (dol_hash($passtyped) == $passcrypted) + if (dol_verifyHash($passtyped, $passcrypted)) { $passok=true; dol_syslog("functions_dolibarr::check_user_password_dolibarr Authentification ok - ".$cryptType." of pass is ok"); @@ -152,5 +152,3 @@ function check_user_password_dolibarr($usertotest,$passwordtotest,$entitytotest= return $login; } - - diff --git a/htdocs/core/modules/modBlockedLog.class.php b/htdocs/core/modules/modBlockedLog.class.php index eece7323c68..9b3f4e16e9b 100644 --- a/htdocs/core/modules/modBlockedLog.class.php +++ b/htdocs/core/modules/modBlockedLog.class.php @@ -46,6 +46,8 @@ class modBlockedLog extends DolibarrModules // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' // It is used to group modules in module setup page $this->family = "base"; + // Module position in the family on 2 digits ('01', '10', '20', ...) + $this->module_position = '90'; // 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 = "Enable a log on some business events into a non reversible log. This module may be mandatory for some countries."; diff --git a/htdocs/core/modules/modSyslog.class.php b/htdocs/core/modules/modSyslog.class.php index 6ef7648531a..5f7ad0f387f 100644 --- a/htdocs/core/modules/modSyslog.class.php +++ b/htdocs/core/modules/modSyslog.class.php @@ -45,6 +45,8 @@ class modSyslog extends DolibarrModules // Family can be 'crm','financial','hr','projects','products','ecm','technic','other' // It is used to group modules in module setup page $this->family = "base"; + // Module position in the family on 2 digits ('01', '10', '20', ...) + $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)); // Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module) diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index 6eeff6cea11..3933a30a54b 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -140,7 +140,7 @@ if ($action == 'confirm_execute' && $confirm == "yes" && $user->rights->cron->ex $action=''; } - header("Location: ".DOL_URL_ROOT.'/cron/list.php?status=-2'); // Make a call to avoid to run twice job when using back + header("Location: ".DOL_URL_ROOT.'/cron/list.php?status=-2'); // Make a redirect to avoid to run twice the job when using back exit; } } @@ -270,7 +270,7 @@ else $buttontoshow.=''.$langs->trans("CronCreateJob").''; } -print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $buttontoshow, $num, $nbtotalofrecords, 'title_setup', 0, '', '', $limit); +print_barre_liste($pagetitle, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_setup', 0, $buttontoshow, '', $limit); print $langs->trans('CronInfo').'
'; diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index c270e2f44fa..a38376e8294 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','7.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','8.0.0-alpha'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 1c6363644f9..74da470c04c 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -468,9 +468,11 @@ class ProductFournisseur extends Product * @param int $prodid Id of product * @param string $sortfield Sort field * @param string $sortorder Sort order + * @param int $limit Limit + * @param int $offset Offset * @return array Array of Products with new properties to define supplier price */ - function list_product_fournisseur_price($prodid, $sortfield='', $sortorder='') + function list_product_fournisseur_price($prodid, $sortfield='', $sortorder='', $limit=0, $offset=0) { global $conf; @@ -484,7 +486,8 @@ class ProductFournisseur extends Product $sql.= " AND s.status=1"; // only enabled company selected $sql.= " AND pfp.fk_product = ".$prodid; if (empty($sortfield)) $sql.= " ORDER BY s.nom, pfp.quantity, pfp.price"; - else $sql.= $this->db->order($sortfield,$sortorder); + else $sql.= $this->db->order($sortfield, $sortorder); + $sql.=$this->db->plimit($limit, $offset); dol_syslog(get_class($this)."::list_product_fournisseur_price", LOG_DEBUG); $resql = $this->db->query($sql); @@ -516,7 +519,7 @@ class ProductFournisseur extends Product $prodfourn->id = $prodid; $prodfourn->fourn_tva_npr = $record["info_bits"]; $prodfourn->fk_supplier_price_expression = $record["fk_supplier_price_expression"]; - $prodfourn->supplier_reputation = $record["supplier_reputation"]; + $prodfourn->supplier_reputation = $record["supplier_reputation"]; if (!empty($conf->dynamicprices->enabled) && !empty($prodfourn->fk_supplier_price_expression)) { $priceparser = new PriceParser($this->db); diff --git a/htdocs/index.php b/htdocs/index.php index 867f305a680..b01e37927c4 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -656,7 +656,7 @@ if ($user->admin && empty($conf->global->MAIN_REMOVE_INSTALL_WARNING)) { $langs->load("errors"); //if (! empty($message)) $message.='
'; - $message.=info_admin($langs->trans("WarningLockFileDoesNotExists",DOL_DATA_ROOT).' '.$langs->trans("WarningUntilDirRemoved",DOL_DOCUMENT_ROOT."/install")); + $message.=info_admin($langs->trans("WarningLockFileDoesNotExists",DOL_DATA_ROOT).' '.$langs->trans("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth'); } // Conf files must be in read only mode @@ -665,7 +665,7 @@ if ($user->admin && empty($conf->global->MAIN_REMOVE_INSTALL_WARNING)) $langs->load("errors"); //$langs->load("other"); //if (! empty($message)) $message.='
'; - $message.=info_admin($langs->transnoentities("WarningConfFileMustBeReadOnly").' '.$langs->trans("WarningUntilDirRemoved",DOL_DOCUMENT_ROOT."/install")); + $message.=info_admin($langs->transnoentities("WarningConfFileMustBeReadOnly").' '.$langs->trans("WarningUntilDirRemoved", DOL_DOCUMENT_ROOT."/install"), 0, 0, '1', 'clearboth'); } if ($message) diff --git a/htdocs/install/check.php b/htdocs/install/check.php index 50409fb55e5..8262a5f05df 100644 --- a/htdocs/install/check.php +++ b/htdocs/install/check.php @@ -421,11 +421,12 @@ else array('from'=>'3.5.0', 'to'=>'3.6.0'), array('from'=>'3.6.0', 'to'=>'3.7.0'), array('from'=>'3.7.0', 'to'=>'3.8.0'), - array('from'=>'3.8.0', 'to'=>'3.9.0'), - array('from'=>'3.9.0', 'to'=>'4.0.0'), - array('from'=>'4.0.0', 'to'=>'5.0.0'), - array('from'=>'5.0.0', 'to'=>'6.0.0'), - array('from'=>'6.0.0', 'to'=>'7.0.0') + array('from'=>'3.8.0', 'to'=>'3.9.0'), + array('from'=>'3.9.0', 'to'=>'4.0.0'), + array('from'=>'4.0.0', 'to'=>'5.0.0'), + array('from'=>'5.0.0', 'to'=>'6.0.0'), + array('from'=>'6.0.0', 'to'=>'7.0.0'), + array('from'=>'7.0.0', 'to'=>'8.0.0') ); $count=0; diff --git a/htdocs/install/mysql/migration/7.0.0-8.0.0.sql b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql new file mode 100644 index 00000000000..1b9375ef1a8 --- /dev/null +++ b/htdocs/install/mysql/migration/7.0.0-8.0.0.sql @@ -0,0 +1,26 @@ +-- +-- Be carefull to requests order. +-- This file must be loaded by calling /install/index.php page +-- when current version is 7.0.0 or higher. +-- +-- To rename a table: ALTER TABLE llx_table RENAME TO llx_table_new; +-- To add a column: ALTER TABLE llx_table ADD COLUMN newcol varchar(60) NOT NULL DEFAULT '0' AFTER existingcol; +-- To rename a column: ALTER TABLE llx_table CHANGE COLUMN oldname newname varchar(60); +-- To drop a column: ALTER TABLE llx_table DROP COLUMN oldname; +-- 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 drop an index: -- VMYSQL4.0 DROP INDEX nomindex on llx_table +-- To drop an index: -- VPGSQL8.0 DROP INDEX nomindex +-- To restrict request to Mysql version x.y minimum use -- VMYSQLx.y +-- To restrict request to Pgsql version x.y minimum use -- VPGSQLx.y +-- To make pk to be auto increment (mysql): -- VMYSQL4.3 ALTER TABLE llx_c_shipment_mode CHANGE COLUMN rowid rowid INTEGER NOT NULL AUTO_INCREMENT; +-- To make pk to be auto increment (postgres): -- VPGSQL8.2 NOT POSSIBLE. MUST DELETE/CREATE TABLE +-- To set a field as NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NULL; +-- To set a field as NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name DROP NOT NULL; +-- To set a field as NOT NULL: -- VMYSQL4.3 ALTER TABLE llx_table MODIFY COLUMN name varchar(60) NOT NULL; +-- To set a field as NOT NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET NOT NULL; +-- To set a field as default NULL: -- VPGSQL8.2 ALTER TABLE llx_table ALTER COLUMN name SET DEFAULT NULL; +-- Note: fields with type BLOB/TEXT can't have default value. + +-- For 8.0 +ALTER TABLE llx_societe ADD COLUMN fk_entrepot integer DEFAULT 0; diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index 4385483209a..2ecb52511d4 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -15,7 +15,6 @@ -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . --- -- =========================================================================== create table llx_user @@ -37,7 +36,7 @@ create table llx_user pass_encoding varchar(24), pass varchar(128), pass_crypted varchar(128), - pass_temp varchar(128), -- temporary password when asked for forget password + pass_temp varchar(128), -- temporary password when asked for forget password or 'hashtoallowreset:YYYMMDDHHMMSS' (where date is max date of validaity) api_key varchar(128), -- key to use REST API by this user gender varchar(10), civility varchar(6), diff --git a/htdocs/install/step5.php b/htdocs/install/step5.php index 8a39faf526a..5181c35f2f9 100644 --- a/htdocs/install/step5.php +++ b/htdocs/install/step5.php @@ -181,7 +181,10 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i',$action)) // Define default setup for password encryption dolibarr_set_const($db, "DATABASE_PWD_ENCRYPTED", "1", 'chaine', 0, '', $conf->entity); dolibarr_set_const($db, "MAIN_SECURITY_SALT", dol_print_date(dol_now(), 'dayhourlog'), 'chaine', 0, '', 0); // All entities - dolibarr_set_const($db, "MAIN_SECURITY_HASH_ALGO", 'sha1md5', 'chaine', 0, '', 0); // All entities + if (function_exists('password_hash')) + dolibarr_set_const($db, "MAIN_SECURITY_HASH_ALGO", 'password_hash', 'chaine', 0, '', 0); // All entities + else + dolibarr_set_const($db, "MAIN_SECURITY_HASH_ALGO", 'sha1md5', 'chaine', 0, '', 0); // All entities } } @@ -342,7 +345,8 @@ if ($action == "set" || empty($action) || preg_match('/upgrade/i',$action)) // Create lock file // If first install -if ($action == "set" && $success) { +if ($action == "set" && $success) +{ if (empty($conf->global->MAIN_VERSION_LAST_UPGRADE) || ($conf->global->MAIN_VERSION_LAST_UPGRADE == DOL_VERSION)) { // Install is finished @@ -350,14 +354,14 @@ if ($action == "set" && $success) { $createlock=0; - if (! empty($force_install_lockinstall)) + if (! empty($force_install_lockinstall) || ! empty($conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE)) { // Install is finished, we create the lock file $lockfile=DOL_DATA_ROOT.'/install.lock'; $fp = @fopen($lockfile, "w"); if ($fp) { - if ($force_install_lockinstall == 1) $force_install_lockinstall=444; // For backward compatibility + if (empty($force_install_lockinstall) || $force_install_lockinstall == 1) $force_install_lockinstall=444; // For backward compatibility fwrite($fp, "This is a lock file to prevent use of install pages (set with permission ".$force_install_lockinstall.")"); fclose($fp); @chmod($lockfile, octdec($force_install_lockinstall)); @@ -400,14 +404,14 @@ elseif (empty($action) || preg_match('/upgrade/i',$action)) $createlock=0; - if (! empty($force_install_lockinstall)) + if (! empty($force_install_lockinstall) || ! empty($conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE)) { // Upgrade is finished, we create the lock file $lockfile=DOL_DATA_ROOT.'/install.lock'; $fp = @fopen($lockfile, "w"); if ($fp) { - if ($force_install_lockinstall == 1) $force_install_lockinstall=444; // For backward compatibility + if (empty($force_install_lockinstall) || $force_install_lockinstall == 1) $force_install_lockinstall=444; // For backward compatibility fwrite($fp, "This is a lock file to prevent use of install pages (set with permission ".$force_install_lockinstall.")"); fclose($fp); @chmod($lockfile, octdec($force_install_lockinstall)); diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 6d38cf87a99..cae43a9e3b5 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -488,7 +488,7 @@ Module30Name=Invoices Module30Desc=Invoice and credit note management for customers. Invoice management for suppliers Module40Name=Suppliers Module40Desc=Supplier management and buying (orders and invoices) -Module42Name=Logs +Module42Name=Debug Logs Module42Desc=Logging facilities (file, syslog, ...). Such logs are for technical/debug purposes. Module49Name=Editors Module49Desc=Editor management @@ -573,8 +573,8 @@ Module2300Name=Scheduled jobs Module2300Desc=Scheduled jobs management (alias cron or chrono table) Module2400Name=Events/Agenda Module2400Desc=Follow done and upcoming events. Let application logs automatic events for tracking purposes or record manual events or rendez-vous. -Module2500Name=Electronic Content Management -Module2500Desc=Save and share documents +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) @@ -588,8 +588,8 @@ Module2900Name=GeoIPMaxmind Module2900Desc=GeoIP Maxmind conversions capabilities Module3100Name=Skype Module3100Desc=Add a Skype button into users / third parties / contacts / members cards -Module3200Name=Non Reversible Logs -Module3200Desc=Activate log of some business events into a non reversible log. Events are archived in real-time. The log is a table of chained event that can be then read and exported. This module may be mandatory for some countries. +Module3200Name=Unalterable Archives +Module3200Desc=Activate log of some business events into an unalterable log. Events are archived in real-time. The log is a table of chained events that can be read only and exported. This module may be mandatory for some countries. Module4000Name=HRM Module4000Desc=Human resources management (management of department, employee contracts and feelings) Module5000Name=Multi-company diff --git a/htdocs/langs/en_US/ecm.lang b/htdocs/langs/en_US/ecm.lang index 7428d226008..95318155813 100644 --- a/htdocs/langs/en_US/ecm.lang +++ b/htdocs/langs/en_US/ecm.lang @@ -14,8 +14,8 @@ ECMNbOfFilesInDir=Number of files in directory ECMNbOfSubDir=Number of sub-directories ECMNbOfFilesInSubDir=Number of files in sub-directories ECMCreationUser=Creator -ECMArea=EDM area -ECMAreaDesc=The EDM (Electronic Document Management) area allows you to save, share and search quickly all kind of documents in Dolibarr. +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. diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 132a200ab2e..1585504479e 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -227,7 +227,9 @@ 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 ##### Export ##### ExportsArea=Exports area AvailableFormats=Available formats diff --git a/htdocs/langs/en_US/users.lang b/htdocs/langs/en_US/users.lang index 3c1a8644bf0..c149e9d6a53 100644 --- a/htdocs/langs/en_US/users.lang +++ b/htdocs/langs/en_US/users.lang @@ -44,7 +44,9 @@ 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. +ConfirmPasswordReset=Confirm password reset MenuUsersAndGroups=Users & Groups LastGroupsCreated=Latest %s created groups LastUsersCreated=Latest %s users created diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 6124bc9161a..f70dd2b78d9 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -65,6 +65,17 @@ $fieldtype = (! empty($ref) ? 'ref' : 'rowid'); if ($user->societe_id) $socid=$user->societe_id; $result=restrictedArea($user,'produit|service&fournisseur',$fieldvalue,'product&product','','',$fieldtype); +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST("sortfield",'alpha'); +$sortorder = GETPOST("sortorder",'alpha'); +$page = (GETPOST("page",'int')?GETPOST("page", 'int'):0); +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="s.nom"; +if (! $sortorder) $sortorder="ASC"; + // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('pricesuppliercard','globalcard')); @@ -589,13 +600,21 @@ if ($id > 0 || $ref) print "\n\n"; print '
'; - if ($user->rights->fournisseur->lire) { + $param=''; + if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage); + if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit); + $param.='&ref='.urlencode($object->ref); + $product_fourn = new ProductFournisseur($db); - $product_fourn_list = $product_fourn->list_product_fournisseur_price($object->id, $sortfield, $sortorder); - $nbtotalofrecords = count($product_fourn_list); - print_barre_liste($langs->trans('SupplierPrices'), $page, $_SERVEUR ['PHP_SELF'], $option, $sortfield, $sortorder, '', count($product_fourn_list), $nbtotalofrecords, 'title_accountancy.png'); + $product_fourn_list = $product_fourn->list_product_fournisseur_price($object->id, $sortfield, $sortorder, $limit, $offset); + $product_fourn_list_all = $product_fourn->list_product_fournisseur_price($object->id, $sortfield, $sortorder, 0, 0); + $nbtotalofrecords = count($product_fourn_list_all); + $num = count($product_fourn_list); + if (($num + ($offset * $limit)) < $nbtotalofrecords) $num++; + + print_barre_liste($langs->trans('SupplierPrices'), $page, $_SERVEUR ['PHP_SELF'], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy.png', 0, '', '', $limit, 1); // Suppliers list title print '
'; @@ -606,7 +625,7 @@ if ($id > 0 || $ref) $param="&id=".$object->id; print '
'; print_liste_field_titre("Suppliers",$_SERVER["PHP_SELF"],"s.nom","",$param,"",$sortfield,$sortorder); - print_liste_field_titre("SupplierRef"); + print_liste_field_titre("SupplierRef",$_SERVER["PHP_SELF"],"","",$param,"",$sortfield,$sortorder); if (!empty($conf->global->FOURN_PRODUCT_AVAILABILITY)) print_liste_field_titre("Availability",$_SERVER["PHP_SELF"],"pfp.fk_availability","",$param,"",$sortfield,$sortorder); print_liste_field_titre("QtyMin",$_SERVER["PHP_SELF"],"pfp.quantity","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre("VATRate",$_SERVER["PHP_SELF"],'','',$param,'align="right"',$sortfield,$sortorder); diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 710ccb37500..38a6c8e8c7c 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -302,7 +302,7 @@ $listofreferent=array( 'class'=>'CommandeFournisseur', 'table'=>'commande_fournisseur', 'datefieldname'=>'date_commande', - 'urlnew'=>DOL_URL_ROOT.'/fourn/commande/card.php?action=create&projectid='.$id.'&socid='.$socid, + 'urlnew'=>DOL_URL_ROOT.'/fourn/commande/card.php?action=create&projectid='.$id, // No socid parameter here, the socid is often the customer and we create a supplier object 'lang'=>'suppliers', 'buttonnew'=>'AddSupplierOrder', 'testnew'=>$user->rights->fournisseur->commande->creer, @@ -314,7 +314,7 @@ $listofreferent=array( 'margin'=>'minus', 'table'=>'facture_fourn', 'datefieldname'=>'datef', - 'urlnew'=>DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$id, + 'urlnew'=>DOL_URL_ROOT.'/fourn/facture/card.php?action=create&projectid='.$id, // No socid parameter here, the socid is often the customer and we create a supplier object 'lang'=>'suppliers', 'buttonnew'=>'AddSupplierInvoice', 'testnew'=>$user->rights->fournisseur->facture->creer, diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index c9c26326426..ffb4cac77fa 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -268,7 +268,7 @@ if ($type_element == 'supplier_order') $thirdTypeSelect='supplier'; } if ($type_element == 'contract') -{ // Supplier : Show products from orders. +{ // Order require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $documentstatic=new Contrat($db); $documentstaticline=new ContratLigne($db); diff --git a/htdocs/user/passwordforgotten.php b/htdocs/user/passwordforgotten.php index 6d2661a2344..cde5c5199e0 100644 --- a/htdocs/user/passwordforgotten.php +++ b/htdocs/user/passwordforgotten.php @@ -78,7 +78,7 @@ if ($action == 'validatenewpassword' && $username && $passwordhash) } else { - if (dol_hash($edituser->pass_temp) == $passwordhash) + if (dol_verifyHash($edituser->pass_temp, $passwordhash)) { $newpassword=$edituser->setPassword($user,$edituser->pass_temp,0); dol_syslog("passwordforgotten.php new password for user->id=".$edituser->id." validated in database"); @@ -218,4 +218,3 @@ $reshook = $hookmanager->executeHooks('getPasswordForgottenPageExtraOptions',$pa $moreloginextracontent = $hookmanager->resPrint; include $template_dir.'passwordforgotten.tpl.php'; // To use native PHP -
'.$langs->trans("Project")."
'.$langs->trans("Project")." (".count($projects).")