diff --git a/.travis.yml b/.travis.yml index f7903361b02..ca9641ce63e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ # We use dist: xenial to have php 5.6+ available os: linux dist: xenial +#dist: bionic sudo: required language: php diff --git a/ChangeLog b/ChangeLog index c74f30755c6..58513986a1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 13.0.0 compared to 12.0.0 ***** For users: - +NEW: Add module Credit transfer SEPA to manage payment of supplier using bank credit transfer SEPA files WARNING: @@ -14,6 +14,68 @@ Following changes may create regressions for some external modules, but were nec +***** ChangeLog for 12.0.2 compared to 12.0.1 ***** +FIX: computation of the bottom margin of returns NaN because body is not loaded yet +FIX: DebugBar hides content at page bottom +FIX: allow more harmless html tags +FIX: Bad back to link +FIX: Bad param +FIX: Can go on page even when module is disabled +FIX: Change position of line in BOM +FIX: Checkbox "drop table" was not checked when using php method to generate backup dump +FIX: ClickToDial tab of users has disappeared +FIX: CSS +FIX: date in supplier price log tooltip. +FIX: Debug module direct debit order. Solve conflict with credit transfer +FIX: Debug setup of receipt printer module +FIX: dolGetElementUrl and agenda page for external modules +FIX: DO not erase variable $key and $label during output of extrafields +FIX: duration fields size with firefox +FIX: Edit extrafield of type long text loose carriage returns +FIX: Fails to retraive accounting code of social contribution sometimes +FIX: Filter too large for extrafields with type text or html +FIX: If using a rounding step, localtax1+2 not included in total +FIX: input field of extrafields must keep data if form submit fails. +FIX: Label of opportunities in graph with special chars badly encoded +FIX: locataxes lost on lines when cloning a vendor invoice +FIX: Look and feel v12 +FIX: Missing PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE conf support in supplier order +FIX: Navigation in object fails to find the next ref in some cases +FIX: null required +FIX: order by amount ht uses wrong column +FIX: Order by amount in product propal stats must be done on d.total_ht and not p.total +FIX: page for confirmation of payments is empty +FIX: Param of fetch_name_optionals_label must be object->table_element +FIX: Picto of HRM module +FIX: product label and desc were never updated when modifying translation +FIX: redirect on contact card from main search +FIX: Reposition and nav +FIX: search warehouse list +FIX: Setup of clicktodial hang on smartphone +FIX: Setup of currency limit and accuracy +FIX: shipping creation: checks not done on weight and sizes +FIX: Should not be able to edit qty on shipment when no stock available +FIX: Size of image on the help popup of modules +FIX: Sql error on stat by referring entries of a product +FIX: Warning if no bank account defined +FIX: We need to see unit line on PDF even though it's an option +FIX: wrong element var for fetch_name_optionals_label function with expeditions +FIX: wrong link to third invoice templates +FIX: Disable svg as supported image by default (can contains javascript). Set MAIN_ALLOW_SVG_FILES_AS_IMAGES to 1 to have svg accepted +FIX: #14076 +FIX: #14146 +FIX: #14209 +FIX: #14222 +FIX: #14236 +FIX: #14241 Mysql 8 compatibility +FIX: #14253 +FIX: #14256 +FIX: #14259 +FIX: #14279 +FIX: #14291 +FIX: #14292 +FIX: #14336 + ***** ChangeLog for 12.0.1 compared to 12.0.0 ***** FIX: reposition was broken if url end with #anchor FIX: $_POST must be GETPOST diff --git a/dev/resources/sepa/text.txt b/dev/resources/sepa/text.txt index e6c05276be2..dbcfeded5a4 100644 --- a/dev/resources/sepa/text.txt +++ b/dev/resources/sepa/text.txt @@ -1,2 +1,8 @@ +Spec for credit transfer: +https://docs.oracle.com/cd/E39124_01/doc.91/e60210/fields_sepa_pay_file_appx.htm#EOAEL00515 + +To validate a SEPA file: +xmllint --schema pain.001.001.03.xsd T200801.xml --noout + To test a SEPA file: https://www.mesfluxdepaiement.fr/testez-vos-fichiers-sepa diff --git a/htdocs/accountancy/bookkeeping/listbyaccount.php b/htdocs/accountancy/bookkeeping/listbyaccount.php index 1f4ac513806..d9c0c7b399f 100644 --- a/htdocs/accountancy/bookkeeping/listbyaccount.php +++ b/htdocs/accountancy/bookkeeping/listbyaccount.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; // Load translation files required by the page @@ -78,6 +79,7 @@ if ($sortfield == "") $sortfield = "t.doc_date,t.rowid"; // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new BookKeeping($db); +$formfile = new FormFile($db); $hookmanager->initHooks(array('bookkeepingbyaccountlist')); $formaccounting = new FormAccounting($db); @@ -543,7 +545,7 @@ while ($i < min($num, $limit)) // Show the break account print ""; - print ''; + print ''; if ($line->numero_compte != "" && $line->numero_compte != '-1') print length_accountg($line->numero_compte).' : '.$object->get_compte_desc($line->numero_compte); else print ''.$langs->trans("Unknown").''; print ''; diff --git a/htdocs/adherents/admin/adherent_emails.php b/htdocs/adherents/admin/adherent_emails.php index c6eec8b2d83..97411a27abf 100644 --- a/htdocs/adherents/admin/adherent_emails.php +++ b/htdocs/adherents/admin/adherent_emails.php @@ -88,6 +88,7 @@ if ($action == 'update' || $action == 'add') { $constnote = (GETPOSTISSET('constnote_'.$constname) ? GETPOST('constnote_'.$constname, 'none') : GETPOST('constnote')); $typetouse = empty($oldtypetonewone[$consttype]) ? $consttype : $oldtypetonewone[$consttype]; + $constvalue = preg_replace('/:member$/', '', $constvalue); $res = dolibarr_set_const($db, $constname, $constvalue, $typetouse, 0, $constnote, $conf->entity); @@ -100,23 +101,6 @@ if ($action == 'update' || $action == 'add') { } } -// Action to enable a submodule of the adherent module -if ($action == 'set') { - $result = dolibarr_set_const($db, GETPOST('name', 'alpha'), GETPOST('value'), '', 0, '', $conf->entity); - if ($result < 0) { - print $db->error(); - } -} - -// Action to disable a submodule of the adherent module -if ($action == 'unset') { - $result = dolibarr_del_const($db, GETPOST('name', 'alpha'), $conf->entity); - if ($result < 0) { - print $db->error(); - } -} - - /* * View diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 06b8cecf7f3..f2cb8c440c2 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -890,7 +890,10 @@ if ($rowid > 0) { if (empty($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) || $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS != 'defaultforfoundationcountry') print '. '.$langs->trans("NoVatOnSubscription", 0).''; if (!empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) && (!empty($conf->product->enabled) || !empty($conf->service->enabled))) { $prodtmp = new Product($db); - $prodtmp->fetch($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + $result = $prodtmp->fetch($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + if ($result < 0) { + setEventMessage($prodtmp->error, 'errors'); + } print '. '.$langs->transnoentitiesnoconv("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS", $prodtmp->getNomUrl(1)); // must use noentitiesnoconv to avoid to encode html into getNomUrl of product } print '
'; @@ -912,7 +915,10 @@ if ($rowid > 0) { if (empty($conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS) || $conf->global->ADHERENT_VAT_FOR_SUBSCRIPTIONS != 'defaultforfoundationcountry') print '. '.$langs->trans("NoVatOnSubscription", 0).''; if (!empty($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS) && (!empty($conf->product->enabled) || !empty($conf->service->enabled))) { $prodtmp = new Product($db); - $prodtmp->fetch($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + $result = $prodtmp->fetch($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS); + if ($result < 0) { + setEventMessage($prodtmp->error, 'errors'); + } print '. '.$langs->transnoentitiesnoconv("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS", $prodtmp->getNomUrl(1)); // must use noentitiesnoconv to avoid to encode html into getNomUrl of product } print '
'; diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 1138eb44ddc..f2e69f81707 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -109,6 +109,12 @@ if (($action == 'update' && !GETPOST("cancel", 'alpha')) foreach ($arrayofimages as $varforimage) { + if ($_FILES[$varforimage]["name"] && ! preg_match('/(\.jpeg|\.jpg|\.png)$/i', $_FILES[$varforimage]["name"])) { // Logo can be used on a lot of different places. Only jpg and png can be supported. + $langs->load("errors"); + setEventMessages($langs->trans("ErrorBadImageFormat"), null, 'errors'); + break; + } + if ($_FILES[$varforimage]["tmp_name"]) { $reg = array(); @@ -473,10 +479,17 @@ if (!empty($mysoc->logo_mini)) { print ''; } print '
'.img_delete($langs->trans("Delete"), '', 'marginleftonly').'
'; -} else { - print '
'; - print ''; - print '
'; +} elseif (!empty($mysoc->logo)) { + if (file_exists($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) { + print '
'; + print ''; + print '
'; + print '
'.img_delete($langs->trans("Delete"), '', 'marginleftonly').'
'; + } else { + print '
'; + print ''; + print '
'; + } } print ''; print ''; @@ -493,10 +506,18 @@ if (!empty($mysoc->logo_squarred_mini)) { print ''; } print '
'.img_delete($langs->trans("Delete"), '', 'marginleftonly').'
'; -} else { - print '
'; - print ''; - print '
'; +} elseif (!empty($mysoc->logo_squarred)) { + if (file_exists($conf->mycompany->dir_output.'/logos/'.$mysoc->logo_squarred)) { + print '
'; + print ''; + print '
'; + print '
'.img_delete($langs->trans("Delete"), '', 'marginleftonly').'
'; + } + else { + print '
'; + print ''; + print '
'; + } } print ''; print ''; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 7f468cc1f1a..b6d5df3644a 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -12,6 +12,7 @@ * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud * Copyright (C) 2019 Frédéric France + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -90,7 +91,11 @@ $hookmanager->initHooks(array('admin')); // Put here declaration of dictionaries properties // Sort order to show dictionary (0 is space). All other dictionaries (added by modules) will be at end of this. -$taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 27, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0); +if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { + $taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 39, 27, 40, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0); +} else { + $taborder = array(9, 0, 4, 3, 2, 0, 1, 8, 19, 16, 27, 38, 0, 5, 11, 0, 32, 33, 34, 0, 6, 0, 29, 0, 7, 24, 28, 17, 35, 36, 0, 10, 23, 12, 13, 0, 14, 0, 22, 20, 18, 21, 0, 15, 30, 0, 37, 0, 25, 0); +} // Name of SQL tables of dictionaries $tabname = array(); @@ -133,6 +138,8 @@ $tabname[35] = MAIN_DB_PREFIX."c_exp_tax_cat"; $tabname[36] = MAIN_DB_PREFIX."c_exp_tax_range"; $tabname[37] = MAIN_DB_PREFIX."c_units"; $tabname[38] = MAIN_DB_PREFIX."c_socialnetworks"; +$tabname[39] = MAIN_DB_PREFIX."c_prospectcontactlevel"; +$tabname[40] = MAIN_DB_PREFIX."c_stcommcontact"; // Dictionary labels $tablib = array(); @@ -174,6 +181,8 @@ $tablib[35] = "DictionaryExpenseTaxCat"; $tablib[36] = "DictionaryExpenseTaxRange"; $tablib[37] = "DictionaryMeasuringUnits"; $tablib[38] = "DictionarySocialNetworks"; +$tablib[39] = "DictionaryProspectContactLevel"; +$tablib[40] = "DictionaryProspectContactStatus"; // Requests to extract data $tabsql = array(); @@ -203,7 +212,7 @@ $tabsql[23] = "SELECT t.rowid as rowid, t.taux, t.revenuestamp_type, c.label as $tabsql[24] = "SELECT rowid as rowid, code, label, active FROM ".MAIN_DB_PREFIX."c_type_resource"; $tabsql[25] = "SELECT rowid as rowid, code, label, active, module FROM ".MAIN_DB_PREFIX."c_type_container as t WHERE t.entity IN (".getEntity('c_type_container').")"; //$tabsql[26]= "SELECT rowid as rowid, code, label, short_label, active FROM ".MAIN_DB_PREFIX."c_units"; -$tabsql[27] = "SELECT id as rowid, code, libelle, active FROM ".MAIN_DB_PREFIX."c_stcomm"; +$tabsql[27] = "SELECT id as rowid, code, libelle, picto, active FROM ".MAIN_DB_PREFIX."c_stcomm"; $tabsql[28] = "SELECT h.rowid as rowid, h.code, h.label, h.affect, h.delay, h.newbymonth, h.fk_country as country_id, c.code as country_code, c.label as country, h.active FROM ".MAIN_DB_PREFIX."c_holiday_types as h LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON h.fk_country=c.rowid"; $tabsql[29] = "SELECT rowid as rowid, code, label, percent, position, active FROM ".MAIN_DB_PREFIX."c_lead_status"; $tabsql[30] = "SELECT rowid, code, name, paper_size, orientation, metric, leftmargin, topmargin, nx, ny, spacex, spacey, width, height, font_size, custom_x, custom_y, active FROM ".MAIN_DB_PREFIX."c_format_cards"; @@ -215,6 +224,8 @@ $tabsql[35] = "SELECT c.rowid, c.label, c.active, c.entity FROM ".MAIN_DB_PREFIX $tabsql[36] = "SELECT r.rowid, r.fk_c_exp_tax_cat, r.range_ik, r.active, r.entity FROM ".MAIN_DB_PREFIX."c_exp_tax_range r"; $tabsql[37] = "SELECT r.rowid, r.code, r.label, r.short_label, r.unit_type, r.scale, r.active FROM ".MAIN_DB_PREFIX."c_units r"; $tabsql[38] = "SELECT rowid, entity, code, label, url, icon, active FROM ".MAIN_DB_PREFIX."c_socialnetworks"; +$tabsql[39] = "SELECT code, label as libelle, sortorder, active FROM ".MAIN_DB_PREFIX."c_prospectcontactlevel"; +$tabsql[40] = "SELECT id as rowid, code, libelle, picto, active FROM ".MAIN_DB_PREFIX."c_stcommcontact"; // Criteria to sort dictionaries $tabsqlsort = array(); @@ -256,6 +267,8 @@ $tabsqlsort[35] = "c.label ASC"; $tabsqlsort[36] = "r.fk_c_exp_tax_cat ASC, r.range_ik ASC"; $tabsqlsort[37] = "r.unit_type ASC, r.scale ASC, r.code ASC"; $tabsqlsort[38] = "rowid, code ASC"; +$tabsqlsort[39] = "sortorder ASC"; +$tabsqlsort[40] = "code ASC"; // Field names in select result for dictionary display $tabfield = array(); @@ -285,7 +298,7 @@ $tabfield[23] = "country_id,country,taux,revenuestamp_type,accountancy_code_sell $tabfield[24] = "code,label"; $tabfield[25] = "code,label"; //$tabfield[26]= "code,label,short_label"; -$tabfield[27] = "code,libelle"; +$tabfield[27] = "code,libelle,picto"; $tabfield[28] = "code,label,affect,delay,newbymonth,country_id,country"; $tabfield[29] = "code,label,percent,position"; $tabfield[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; @@ -297,6 +310,8 @@ $tabfield[35] = "label"; $tabfield[36] = "range_ik,fk_c_exp_tax_cat"; $tabfield[37] = "code,label,short_label,unit_type,scale"; $tabfield[38] = "code,label,url,icon,entity"; +$tabfield[39] = "code,libelle,sortorder"; +$tabfield[40] = "code,libelle,picto"; // Edit field names for editing a record $tabfieldvalue = array(); @@ -326,7 +341,7 @@ $tabfieldvalue[23] = "country,taux,revenuestamp_type,accountancy_code_sell,accou $tabfieldvalue[24] = "code,label"; $tabfieldvalue[25] = "code,label"; //$tabfieldvalue[26]= "code,label,short_label"; -$tabfieldvalue[27] = "code,libelle"; +$tabfieldvalue[27] = "code,libelle,picto"; $tabfieldvalue[28] = "code,label,affect,delay,newbymonth,country"; $tabfieldvalue[29] = "code,label,percent,position"; $tabfieldvalue[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; @@ -338,6 +353,8 @@ $tabfieldvalue[35] = "label"; $tabfieldvalue[36] = "range_ik,fk_c_exp_tax_cat"; $tabfieldvalue[37] = "code,label,short_label,unit_type,scale"; $tabfieldvalue[38] = "code,label,url,icon"; +$tabfieldvalue[39] = "code,libelle,sortorder"; +$tabfieldvalue[40] = "code,libelle,picto"; // Field names in the table for inserting a record $tabfieldinsert = array(); @@ -367,7 +384,7 @@ $tabfieldinsert[23] = "fk_pays,taux,revenuestamp_type,accountancy_code_sell,acco $tabfieldinsert[24] = "code,label"; $tabfieldinsert[25] = "code,label"; //$tabfieldinsert[26]= "code,label,short_label"; -$tabfieldinsert[27] = "code,libelle"; +$tabfieldinsert[27] = "code,libelle,picto"; $tabfieldinsert[28] = "code,label,affect,delay,newbymonth,fk_country"; $tabfieldinsert[29] = "code,label,percent,position"; $tabfieldinsert[30] = "code,name,paper_size,orientation,metric,leftmargin,topmargin,nx,ny,spacex,spacey,width,height,font_size,custom_x,custom_y"; @@ -380,6 +397,8 @@ $tabfieldinsert[35] = "label"; $tabfieldinsert[36] = "range_ik,fk_c_exp_tax_cat"; $tabfieldinsert[37] = "code,label,short_label,unit_type,scale"; $tabfieldinsert[38] = "code,label,url,icon,entity"; +$tabfieldinsert[39] = "code,label,sortorder"; +$tabfieldinsert[40] = "code,libelle,picto"; // Rowid name of field depending if field is autoincrement on or off.. // Use "" if id field is "rowid" and has autoincrement on @@ -423,6 +442,8 @@ $tabrowid[35] = ""; $tabrowid[36] = ""; $tabrowid[37] = ""; $tabrowid[38] = ""; +$tabrowid[39] = "code"; +$tabrowid[40] = "id"; // Condition to show dictionary in setup page $tabcond = array(); @@ -464,6 +485,8 @@ $tabcond[35] = !empty($conf->expensereport->enabled); $tabcond[36] = !empty($conf->expensereport->enabled); $tabcond[37] = !empty($conf->product->enabled); $tabcond[38] = !empty($conf->socialnetworks->enabled); +$tabcond[39] = (! empty($conf->societe->enabled) && empty($conf->global->SOCIETE_DISABLE_PROSPECTS)); +$tabcond[40] = ! empty($conf->societe->enabled); // List of help for fields $tabhelp = array(); @@ -493,7 +516,7 @@ $tabhelp[23] = array('revenuestamp_type'=>'FixedOrPercent'); $tabhelp[24] = array('code'=>$langs->trans("EnterAnyCode")); $tabhelp[25] = array('code'=>$langs->trans('EnterAnyCode')); //$tabhelp[26] = array('code'=>$langs->trans("EnterAnyCode")); -$tabhelp[27] = array('code'=>$langs->trans("EnterAnyCode")); +$tabhelp[27] = array('code'=>$langs->trans("EnterAnyCode"),'picto'=>$langs->trans("PictoHelp")); $tabhelp[28] = array('affect'=>$langs->trans("FollowedByACounter"), 'delay'=>$langs->trans("MinimumNoticePeriod"), 'newbymonth'=>$langs->trans("NbAddedAutomatically")); $tabhelp[29] = array('code'=>$langs->trans("EnterAnyCode"), 'percent'=>$langs->trans("OpportunityPercent"), 'position'=>$langs->trans("PositionIntoComboList")); $tabhelp[30] = array('code'=>$langs->trans("EnterAnyCode"), 'name'=>$langs->trans("LabelName"), 'paper_size'=>$langs->trans("LabelPaperSize")); @@ -505,6 +528,8 @@ $tabhelp[35] = array(); $tabhelp[36] = array('range_ik'=>$langs->trans('PrevRangeToThisRange')); $tabhelp[37] = array('code'=>$langs->trans("EnterAnyCode"), 'unit_type' => $langs->trans('MeasuringUnitTypeDesc'), 'scale' => $langs->trans('MeasuringScaleDesc')); $tabhelp[38] = array('code'=>$langs->trans("EnterAnyCode"), 'url' => $langs->trans('UrlSocialNetworksDesc'), 'icon' => $langs->trans('FafaIconSocialNetworksDesc')); +$tabhelp[39] = array('code'=>$langs->trans("EnterAnyCode")); +$tabhelp[40] = array('code'=>$langs->trans("EnterAnyCode"),'picto'=>$langs->trans("PictoHelp")); // List of check for fields (NOT USED YET) $tabfieldcheck = array(); @@ -546,6 +571,8 @@ $tabfieldcheck[35] = array(); $tabfieldcheck[36] = array(); $tabfieldcheck[37] = array(); $tabfieldcheck[38] = array(); +$tabfieldcheck[39] = array(); +$tabfieldcheck[40] = array(); // Complete all arrays with entries found into modules complete_dictionary_with_modules($taborder, $tabname, $tablib, $tabsql, $tabsqlsort, $tabfield, $tabfieldvalue, $tabfieldinsert, $tabrowid, $tabcond, $tabhelp, $tabfieldcheck); @@ -647,7 +674,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) if ($value == 'dayrule' && empty($_POST['dayrule'])) continue; if ($value == 'sortorder') continue; // For a column name 'sortorder', we use the field name 'position' if ((!isset($_POST[$value]) || $_POST[$value] == '') - && (!in_array($listfield[$f], array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking')) // Fields that are not mandatory + && (!in_array($listfield[$f], array('decalage', 'module', 'accountancy_code', 'accountancy_code_sell', 'accountancy_code_buy', 'tracking', 'picto')) // Fields that are not mandatory && (!($id == 10 && $listfield[$f] == 'code')) // Code is mandatory fir table 10 ) ) { diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index 4334236f813..0f490bb828a 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -153,20 +153,20 @@ $sourceList = array(); // We save list of template email Dolibarr can manage. This list can found by a grep into code on "->param['models']" $elementList = array(); -if ($conf->propal->enabled) $elementList['propal_send'] = $langs->trans('MailToSendProposal'); -if ($conf->commande->enabled) $elementList['order_send'] = $langs->trans('MailToSendOrder'); -if ($conf->facture->enabled) $elementList['facture_send'] = $langs->trans('MailToSendInvoice'); +if ($conf->propal->enabled && $user->rights->propal->lire) $elementList['propal_send'] = $langs->trans('MailToSendProposal'); +if ($conf->commande->enabled && $user->rights->commande->lire) $elementList['order_send'] = $langs->trans('MailToSendOrder'); +if ($conf->facture->enabled && $user->rights->facture->lire) $elementList['facture_send'] = $langs->trans('MailToSendInvoice'); if ($conf->expedition->enabled) $elementList['shipping_send'] = $langs->trans('MailToSendShipment'); if ($conf->reception->enabled) $elementList['reception_send'] = $langs->trans('MailToSendReception'); if ($conf->ficheinter->enabled) $elementList['fichinter_send'] = $langs->trans('MailToSendIntervention'); if ($conf->supplier_proposal->enabled) $elementList['supplier_proposal_send'] = $langs->trans('MailToSendSupplierRequestForQuotation'); -if ($conf->fournisseur->enabled && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || $conf->supplier_order->enabled) $elementList['order_supplier_send'] = $langs->trans('MailToSendSupplierOrder'); -if ($conf->fournisseur->enabled && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) || $conf->supplier_invoice->enabled) $elementList['invoice_supplier_send'] = $langs->trans('MailToSendSupplierInvoice'); -if ($conf->societe->enabled) $elementList['thirdparty'] = $langs->trans('MailToThirdparty'); -if ($conf->adherent->enabled) $elementList['member'] = $langs->trans('MailToMember'); -if ($conf->contrat->enabled) $elementList['contract'] = $langs->trans('MailToSendContract'); +if (($conf->fournisseur->enabled && $user->rights->fournisseur->commande->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || ($conf->supplier_order->enabled && $user->rights->supplier_order->lire)) $elementList['order_supplier_send'] = $langs->trans('MailToSendSupplierOrder'); +if (($conf->fournisseur->enabled && $user->rights->fournisseur->facture->lire && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || ($conf->supplier_invoice->enabled && $user->rights->supplier_invoice->lire)) $elementList['invoice_supplier_send'] = $langs->trans('MailToSendSupplierInvoice'); +if ($conf->societe->enabled && $user->rights->societe->lire) $elementList['thirdparty'] = $langs->trans('MailToThirdparty'); +if ($conf->adherent->enabled && $user->rights->adherent->lire) $elementList['member'] = $langs->trans('MailToMember'); +if ($conf->contrat->enabled && $user->rights->contrat->lire) $elementList['contract'] = $langs->trans('MailToSendContract'); if ($conf->projet->enabled) $elementList['project'] = $langs->trans('MailToProject'); -if ($conf->ticket->enabled) $elementList['ticket_send'] = $langs->trans('MailToTicket'); +if ($conf->ticket->enabled && $user->rights->ticket->read) $elementList['ticket_send'] = $langs->trans('MailToTicket'); $elementList['user'] = $langs->trans('MailToUser'); $parameters = array('elementList'=>$elementList); @@ -544,6 +544,7 @@ if (!empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) { $fieldsforco foreach ($fieldsforcontent as $tmpfieldlist) { print ''; + // Label if ($tmpfieldlist == 'topic') { @@ -557,6 +558,7 @@ foreach ($fieldsforcontent as $tmpfieldlist) print $form->textwithpicto($langs->trans("Content"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'
'; if ($tmpfieldlist == 'content_lines') print $form->textwithpicto($langs->trans("ContentForLines"), $tabhelp[$id][$tmpfieldlist], 1, 'help', '', 0, 2, $tmpfieldlist).'
'; + // Input field if ($tmpfieldlist == 'topic') { print ''; @@ -633,30 +635,34 @@ if ($resql) // Title line with search boxes print ''; + $filterfound = 0; foreach ($fieldlist as $field => $value) { - if ($value == 'label') print ''; - elseif ($value == 'lang') - { + if ($value == 'label') { + print ''; + } elseif ($value == 'lang') { print ''; print $formadmin->select_language($search_lang, 'search_lang', 0, null, 1, 0, 0, 'maxwidth100'); print ''; - } elseif ($value == 'fk_user') - { + } elseif ($value == 'fk_user') { print ''; $restrictid = array(); if (!$user->admin) $restrictid = array($user->id); //var_dump($restrictid); print $form->select_dolusers($search_fk_user, 'search_fk_user', 1, null, 0, 'hierarchyme', null, 0, 0, 1, '', 0, '', 'maxwidth100'); print ''; - } elseif ($value == 'topic') print ''; - elseif ($value == 'type_template') - { + } elseif ($value == 'topic') { + print ''; + } elseif ($value == 'type_template') { print ''.$form->selectarray('search_type_template', $elementList, $search_type_template, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100 maxwidth100onsmartphone').''; - } elseif (!in_array($value, array('content', 'content_lines'))) print ''; + } elseif (!in_array($value, array('content', 'content_lines'))) { + print ''; + } } + if (empty($conf->global->MAIN_EMAIL_TEMPLATES_FOR_OBJECT_LINES)) print ''; + // Action column print ''; $searchpicto = $form->showFilterButtons(); diff --git a/htdocs/admin/modulehelp.php b/htdocs/admin/modulehelp.php index b082b7eb170..2e256f3c5ad 100644 --- a/htdocs/admin/modulehelp.php +++ b/htdocs/admin/modulehelp.php @@ -262,7 +262,7 @@ print '
'; $picto = 'object_'.$objMod->picto; -print load_fiche_titre(($modulename ? $modulename : $moduledesc), $moreinfo, $picto); +print load_fiche_titre(($modulename ? $modulename : $moduledesc), $moreinfo, $picto, 0, '', 'titlemodulehelp'); print '
'; dol_fiche_head($head, $mode, '', -1); diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index e5e221c529b..bd30d863bdc 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -506,10 +506,10 @@ if ($mode == 'common' || $mode == 'commonkanban') $moreforfilter .= '
'.$moreinfo.'
'.$moreinfo2.'
'; $moreforfilter .= '
'; - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Keyword').': '; $moreforfilter .= '
'; - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Origin').': '.$form->selectarray('search_nature', $arrayofnatures, dol_escape_htmltag($search_nature), 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; if (!empty($conf->global->MAIN_FEATURES_LEVEL)) @@ -518,11 +518,11 @@ if ($mode == 'common' || $mode == 'commonkanban') if ($conf->global->MAIN_FEATURES_LEVEL < 0) $array_version['deprecated'] = $langs->trans("Deprecated"); if ($conf->global->MAIN_FEATURES_LEVEL > 0) $array_version['experimental'] = $langs->trans("Experimental"); if ($conf->global->MAIN_FEATURES_LEVEL > 1) $array_version['development'] = $langs->trans("Development"); - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Version').': '.$form->selectarray('search_version', $array_version, $search_version, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; } - $moreforfilter .= '
'; + $moreforfilter .= '
'; $moreforfilter .= $langs->trans('Status').': '.$form->selectarray('search_status', array('active'=>$langs->transnoentitiesnoconv("Enabled"), 'disabled'=>$langs->transnoentitiesnoconv("Disabled")), $search_status, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100'); $moreforfilter .= '
'; $moreforfilter .= ' '; diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index c76482f4597..4332c4feab0 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -65,13 +65,13 @@ if (!function_exists('gzdecode')) { } } + /* * Action */ if ($action == 'addprinter' && $user->admin) { $error = 0; - $db->begin(); if (empty($printername)) { $error++; setEventMessages($langs->trans("PrinterNameEmpty"), null, 'errors'); @@ -82,7 +82,8 @@ if ($action == 'addprinter' && $user->admin) { } if (!$error) { - $result = $printer->addPrinter($printername, GETPOST('printertypeid', 'int'), GETPOST('printerprofileid', 'int'), $parameter); + $db->begin(); + $result = $printer->addPrinter($printername, GETPOST('printertypeid', 'int'), GETPOST('printerprofileid', 'int'), $parameter); if ($result > 0) $error++; if (!$error) @@ -99,14 +100,14 @@ if ($action == 'addprinter' && $user->admin) { if ($action == 'deleteprinter' && $user->admin) { $error = 0; - $db->begin(); if (empty($printerid)) { $error++; setEventMessages($langs->trans("PrinterIdEmpty"), null, 'errors'); } if (!$error) { - $result = $printer->deletePrinter($printerid); + $db->begin(); + $result = $printer->deletePrinter($printerid); if ($result > 0) $error++; if (!$error) @@ -123,14 +124,14 @@ if ($action == 'deleteprinter' && $user->admin) { if ($action == 'updateprinter' && $user->admin) { $error = 0; - $db->begin(); if (empty($printerid)) { $error++; setEventMessages($langs->trans("PrinterIdEmpty"), null, 'errors'); } if (!$error) { - $result = $printer->updatePrinter($printername, GETPOST('printertypeid', 'int'), GETPOST('printerprofileid', 'int'), $parameter, $printerid); + $db->begin(); + $result = $printer->updatePrinter($printername, GETPOST('printertypeid', 'int'), GETPOST('printerprofileid', 'int'), $parameter, $printerid); if ($result > 0) $error++; if (!$error) { @@ -189,14 +190,14 @@ if ($action == 'testtemplate' && $user->admin) { if ($action == 'updatetemplate' && $user->admin) { $error = 0; - $db->begin(); if (empty($templateid)) { $error++; setEventMessages($langs->trans("TemplateIdEmpty"), null, 'errors'); } if (!$error) { - $result = $printer->updateTemplate($templatename, $template, $templateid); + $db->begin(); + $result = $printer->updateTemplate($templatename, $template, $templateid); if ($result > 0) $error++; if (!$error) { @@ -212,14 +213,14 @@ if ($action == 'updatetemplate' && $user->admin) { if ($action == 'addtemplate' && $user->admin) { $error = 0; - $db->begin(); if (empty($templatename)) { $error++; setEventMessages($langs->trans("TemplateNameEmpty"), null, 'errors'); } if (!$error) { - $result = $printer->addTemplate($templatename, $template); + $db->begin(); + $result = $printer->addTemplate($templatename, $template); if ($result > 0) $error++; if (!$error) { @@ -233,6 +234,29 @@ if ($action == 'addtemplate' && $user->admin) { $action = ''; } +if ($action == 'deletetemplate' && $user->admin) { + $error = 0; + if (empty($templateid)) { + $error++; + setEventMessages($langs->trans("TemplateIdEmpty"), null, 'errors'); + } + + if (!$error) { + $db->begin(); + $result = $printer->deleteTemplate($templateid); + if ($result > 0) $error++; + + if (!$error) { + $db->commit(); + setEventMessages($langs->trans("TemplateDeleted", $templatename), null); + } else { + $db->rollback(); + dol_print_error($db); + } + } + $action = ''; +} + /* * View @@ -247,6 +271,7 @@ print load_fiche_titre($langs->trans("ReceiptPrinterSetup"), $linkback, 'title_s $head = receiptprinteradmin_prepare_head($mode); +// mode = config if ($mode == 'config' && $user->admin) { print '
'; print ''; @@ -259,7 +284,7 @@ if ($mode == 'config' && $user->admin) { dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), -1, 'technic'); - print $langs->trans("ReceiptPrinterDesc")."

\n"; + print ''.$langs->trans("ReceiptPrinterDesc")."

\n"; print ''."\n"; print ''; @@ -272,6 +297,22 @@ if ($mode == 'config' && $user->admin) { $ret = $printer->listprinters(); $nbofprinters = count($printer->listprinters); + if ($action != 'editprinter') { + print ''; + print ''; + $ret = $printer->selectTypePrinter(); + print ''; + $ret = $printer->selectProfilePrinter(); + print ''; + print ''; + print ''; + print ''; + } + if ($ret > 0) { setEventMessages($printer->error, $printer->errors, 'errors'); } else { @@ -285,7 +326,9 @@ if ($mode == 'config' && $user->admin) { $ret = $printer->selectProfilePrinter($printer->listprinters[$line]['fk_profile']); print ''; print ''; - print ''; + print ''; print ''; } else { print ''; @@ -293,15 +336,15 @@ if ($mode == 'config' && $user->admin) { print ''; print ''; // edit icon - print ''; print ''; @@ -309,38 +352,10 @@ if ($mode == 'config' && $user->admin) { } } - if ($action != 'editprinter') { - if ($nbofprinters > 0) { - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print "\n"; - } - - print ''; - print ''; - $ret = $printer->selectTypePrinter(); - print ''; - $ret = $printer->selectProfilePrinter(); - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - } print '
'.$printer->resprint.''.$printer->profileresprint.''; + if ($action != 'editprinter') { + print '
'; + } + print '
'.$printer->profileresprint.''; + print '
'; + print '
'.$printer->listprinters[$line]['name'].''.$langs->trans($printer->listprinters[$line]['fk_profile_name']).''.$printer->listprinters[$line]['parameter'].''; + print ''; print img_picto($langs->trans("Edit"), 'edit'); print ''; // delete icon - print ''; + print ''; print img_picto($langs->trans("Delete"), 'delete'); print ''; // test icon - print ''; + print ''; print img_picto($langs->trans("TestPrinter"), 'printer'); print '
'.$langs->trans("Name").''.$langs->trans("Type").''.$langs->trans("Profile").''.$langs->trans("Parameters").'
'.$printer->resprint.''.$printer->profileresprint.'
'; dol_fiche_end(); - if ($action != 'editprinter') { - print '
'; - } else { - print '
'; - } print '
'; print '
'; @@ -370,8 +385,11 @@ if ($mode == 'config' && $user->admin) { print ''; } +// mode = template if ($mode == 'template' && $user->admin) { - print '
'; + dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), -1, 'technic'); + + print ''; print ''; if ($action != 'edittemplate') { print ''; @@ -379,16 +397,11 @@ if ($mode == 'template' && $user->admin) { print ''; } - - print load_fiche_titre($langs->trans("ReceiptPrinterTemplateDesc"), '', '')."

\n"; - print ''."\n"; print ''; print ''; print ''; print ''; - print ''; - print ''; print "\n"; $ret = $printer->listPrintersTemplates(); //print '
'.print_r($printer->listprinterstemplates, true).'
'; @@ -401,22 +414,23 @@ if ($mode == 'template' && $user->admin) { if ($action == 'edittemplate' && $printer->listprinterstemplates[$line]['rowid'] == $templateid) { print ''; print ''; - print ''; print ''; } else { print ''; print ''; // edit icon - print ''; } @@ -424,20 +438,30 @@ if ($mode == 'template' && $user->admin) { } } - print '
'.$langs->trans("Name").''.$langs->trans("Template").'
'; + print ''; + print ''; print ''.$printer->listprinterstemplates[$line]['name'].''.nl2br(htmlentities($printer->listprinterstemplates[$line]['template'])).''; + print ''; print img_picto($langs->trans("Edit"), 'edit'); print ''; // delete icon - print ''; + print ''; print img_picto($langs->trans("Delete"), 'delete'); print ''; // test icon - print ''; + print ''; print img_picto($langs->trans("TestPrinterTemplate"), 'printer'); print '
'; if ($action != 'edittemplate') { - print ''; + print ''; print ''; - print ''; + print ''; + print ''; print ''; print ''; + print ''; + } - print '
'; + print ''; + + if ($action != 'edittemplate') { + print ''; + print '
'; } else { print '
'; } print '
'; + dol_fiche_end(); + print '
'; print ''."\n"; diff --git a/htdocs/admin/system/database-tables.php b/htdocs/admin/system/database-tables.php index f7ceb13e874..c0a52337a25 100644 --- a/htdocs/admin/system/database-tables.php +++ b/htdocs/admin/system/database-tables.php @@ -28,21 +28,27 @@ require '../../main.inc.php'; $langs->load("admin"); -if (!$user->admin) +if (!$user->admin) { accessforbidden(); +} $action = GETPOST('action', 'alpha'); if ($action == 'convert') { - $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ENGINE=INNODB"; + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ENGINE=INNODB"; $db->query($sql); } if ($action == 'convertutf8') { - $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; - $db->query($sql); + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." CHARACTER SET utf8 COLLATE utf8_unicode_ci"; + $db->query($sql); +} +if ($action == 'convertdynamic') +{ + $sql = "ALTER TABLE ".$db->escape(GETPOST("table", "aZ09"))." ROW_FORMAT=DYNAMIC;"; + $db->query($sql); } @@ -82,8 +88,8 @@ if (!$base) } else { if ($base == 1) { - print '
'; - print '
'; + print '
'; + print '
'; print ''; print ''; print ''; @@ -112,13 +118,17 @@ if (!$base) print ''; print ''; - if (isset($obj->Engine) && $obj->Engine == "MyISAM") - { + if (isset($obj->Engine) && $obj->Engine == "MyISAM") { print ''; } else { print ''; } - print ''; + print ''; print ''; print ''; print ''; @@ -127,9 +137,8 @@ if (!$base) print ''; print ''; print ''; print ''; @@ -142,8 +151,8 @@ if (!$base) if ($base == 2) { - print '
'; - print '
'.$langs->trans("TableName").''.$langs->trans("Type").''.$obj->Name.''.$obj->Engine.''.$langs->trans("Convert").' InnoDb '.$obj->Row_format.''; + print $obj->Row_format; + if (isset($obj->Row_format) && (in_array($obj->Row_format, array("Compact")))) { + print '
'.$langs->trans("Convert").' Dynamic'; + } + print '
'.$obj->Rows.''.$obj->Avg_row_length.''.$obj->Data_length.''.$obj->Auto_increment.''.$obj->Check_time.''.$obj->Collation; - if (isset($obj->Collation) && (in_array($obj->Collation, array("utf8mb4_general_ci", "utf8mb4_unicode_ci", "latin1_swedish_ci")))) - { - print '
'.$langs->trans("Convert").' UTF8'; + if (isset($obj->Collation) && (in_array($obj->Collation, array("utf8mb4_general_ci", "utf8mb4_unicode_ci", "latin1_swedish_ci")))) { + print '
'.$langs->trans("Convert").' UTF8'; } print '
'; + print '
'; + print '
'; print ''; print ''; print ''; @@ -182,8 +191,8 @@ if (!$base) if ($base == 4) { // Sqlite by PDO or by Sqlite3 - print '
'; - print '
'.$langs->trans("TableName").'Nb of tuples
'; + print '
'; + print '
'; print ''; print ''; print ''; diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index ce734aadeb5..69fef80fd6b 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -419,8 +419,10 @@ class Documents extends DolibarrApi $object = new Product($this->db); $result = $object->fetch($id, $ref); - if (!$result) { + if ($result==0) { throw new RestException(404, 'Product not found'); + } elseif ($result<0) { + throw new RestException(500, 'Error while fetching object: '.$object->error); } $upload_dir = $conf->product->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 0, $object, 'product').dol_sanitizeFileName($object->ref); @@ -630,7 +632,7 @@ class Documents extends DolibarrApi } elseif ($result < 0) { - throw new RestException(500, 'Error while fetching object.'); + throw new RestException(500, 'Error while fetching object: '.$object->error); } } diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index f6dea256f6a..1ac908f361a 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -57,9 +57,11 @@ $thirdpartytmp = new Societe($db); if (GETPOST('submitproduct') && GETPOST('submitproduct')) { $action = ''; // We reset because we don't want to build doc - if (GETPOST('productid') > 0) - { - $producttmp->fetch(GETPOST('productid')); + if (GETPOST('productid') > 0) { + $result = $producttmp->fetch(GETPOST('productid')); + if ($result < 0) { + setEventMessage($producttmp->error, 'errors'); + } $forbarcode = $producttmp->barcode; $fk_barcode_type = $producttmp->barcode_type; diff --git a/htdocs/bom/bom_agenda.php b/htdocs/bom/bom_agenda.php index a764a2cd5ae..43f1604e08c 100644 --- a/htdocs/bom/bom_agenda.php +++ b/htdocs/bom/bom_agenda.php @@ -130,7 +130,7 @@ if ($object->id > 0) // 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 4a1c4e2f179..d180c00426f 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -929,6 +929,7 @@ class BOM extends CommonObject global $conf, $langs; $langs->load("mrp"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'standard'; @@ -1004,7 +1005,11 @@ class BOM extends CommonObject foreach ($this->lines as &$line) { $tmpproduct = new Product($this->db); - $tmpproduct->fetch($line->fk_product); + $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) diff --git a/htdocs/bom/tpl/linkedobjectblock.tpl.php b/htdocs/bom/tpl/linkedobjectblock.tpl.php index d6b8ebf9a7c..45340577228 100644 --- a/htdocs/bom/tpl/linkedobjectblock.tpl.php +++ b/htdocs/bom/tpl/linkedobjectblock.tpl.php @@ -52,8 +52,15 @@ foreach ($linkedObjectBlock as $key => $objectlink) } echo ''; echo '
'; - $product_static->fetch($objectlink->fk_product); - echo ''; + + echo ''; echo ''; echo '
'.$langs->trans("TableName").''.$langs->trans("NbOfRecord").''.$objectlink->getNomUrl(1).''.$product_static->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) { diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 69c7207a817..bd6d1fc2cf3 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -145,6 +145,7 @@ if ($action == 'create') print '
'."\n"; print ''; print ''; + print ''; print load_fiche_titre($langs->trans("NewBookmark")); diff --git a/htdocs/bookmarks/list.php b/htdocs/bookmarks/list.php index a132b708c20..a4f0939c054 100644 --- a/htdocs/bookmarks/list.php +++ b/htdocs/bookmarks/list.php @@ -154,7 +154,7 @@ print ''; print ''; $newcardbutton = ''; -$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create', '', !empty($user->rights->bookmark->creer)); +$newcardbutton .= dolGetButtonTitle($langs->trans('New'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/bookmarks/card.php?action=create&backtopage='.urlencode(DOL_URL_ROOT.'/bookmarks/list.php'), '', !empty($user->rights->bookmark->creer)); print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'bookmark', 0, $newcardbutton, '', $limit, 0, 0, 1); diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index d5a2f76ecd5..6128ab5e2df 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -1213,7 +1213,8 @@ class Categorie extends CommonObject //print 'Result for id_categ='.$id_categ.' : '.$this->cats[$id_categ]['fullpath'].'
'."\n"; // We count number of _ to have level - $this->cats[$id_categ]['level'] = dol_strlen(preg_replace('/[^_]/i', '', $this->cats[$id_categ]['fullpath'])); + $nbunderscore = substr_count($this->cats[$id_categ]['fullpath'], '_'); + $this->cats[$id_categ]['level'] = ($nbunderscore ? $nbunderscore : null); return; } @@ -2009,4 +2010,25 @@ class Categorie extends CommonObject return ""; } } + + /** + * Count all categories + * + * @return int Number of categories, -1 on error + */ + public function countNbOfCategories() + { + dol_syslog(get_class($this)."::count_all_categories", LOG_DEBUG); + $sql = "SELECT COUNT(rowid) FROM ".MAIN_DB_PREFIX."categorie"; + $sql .= " WHERE entity IN (".getEntity('category').")"; + + $res = $this->db->query($sql); + if ($res) { + $obj = $this->db->fetch_object($res); + return $obj->count; + } else { + dol_print_error($this->db); + return -1; + } + } } diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 34d7b26bd8e..9ee98aa9f2b 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -9,6 +9,7 @@ * Copyright (C) 2013 Alexandre Spangaro * Copyright (C) 2015-2019 Frédéric France * Copyright (C) 2015 Marcos García + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -526,6 +527,7 @@ if ($object->id > 0) print "
"; + // Prospection level and status if ($object->client == 2 || $object->client == 3) { print '
'; @@ -533,12 +535,12 @@ if ($object->id > 0) print '
'; print ''; - // Level of prospect + // Level of prospection print '"; print ''; - // Status + // Status of prospection $object->loadCacheOfProspStatus(); print ''; print "
'; print ''; + if ($action != 'editlevel' && $user->rights->societe->creer) print ''; print '
'; print $langs->trans('ProspectLevel'); print ''; - if ($action != 'editlevel' && $user->rights->societe->creer) print 'id.'">'.img_edit($langs->trans('Modify'), 1).'id.'">'.img_edit($langs->trans('Modify'), 1).'
'; print '
'; if ($action == 'editlevel') @@ -550,17 +552,17 @@ if ($object->id > 0) print "
'.$langs->trans("StatusProsp").''.$object->getLibProspCommStatut(4, $object->cacheprospectstatus[$object->stcomm_id]['label']); print '     '; print '
'; foreach ($object->cacheprospectstatus as $key => $val) { - $titlealt = 'default'; - if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; - if ($object->stcomm_id != $val['id']) print ''.img_action($titlealt, $val['code']).''; - } + $titlealt = 'default'; + if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; + if ($object->stcomm_id != $val['id']) print ''.img_action($titlealt, $val['code'], $val['picto']).''; + } print '
"; } @@ -1127,7 +1129,7 @@ if ($object->id > 0) } /* - * Last invoices + * Latest invoices */ if (!empty($conf->facture->enabled) && $user->rights->facture->lire) { diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index ccaabcbe765..c6d2ab46ff6 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -3664,6 +3664,7 @@ class Propal extends CommonObject global $conf, $langs; $langs->load("propale"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'azur'; diff --git a/htdocs/comm/prospect/index.php b/htdocs/comm/prospect/index.php index b49f334dadd..d99b3509b26 100644 --- a/htdocs/comm/prospect/index.php +++ b/htdocs/comm/prospect/index.php @@ -2,6 +2,7 @@ /* Copyright (C) 2001-2004 Rodolphe Quiedeville * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -71,7 +72,7 @@ if (!empty($conf->propal->enabled)) * */ -$sql = "SELECT count(*) as cc, st.libelle, st.id"; +$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) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -98,7 +99,7 @@ if ($resql) print ''; print ''; - print img_action($langs->trans("Show"), $obj->id).' '; + print img_action($langs->trans("Show"), $obj->id, $obj->picto).' '; print $langs->trans("StatusProspect".$obj->id); print ''.$obj->cc.''; $i++; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 28d2170e49a..a30d04fd761 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3859,6 +3859,7 @@ class Commande extends CommonOrder global $conf, $langs; $langs->load("orders"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'einstein'; diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 5770df78a82..7ed5fe6e919 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -116,7 +116,7 @@ $hookmanager->initHooks(array('orderlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('commande'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); // List of fields to search into when doing a "search in all" diff --git a/htdocs/compta/bank/class/account.class.php b/htdocs/compta/bank/class/account.class.php index 010911b788b..ded439748e5 100644 --- a/htdocs/compta/bank/class/account.class.php +++ b/htdocs/compta/bank/class/account.class.php @@ -469,7 +469,7 @@ class Account extends CommonObject * Add an entry into table ".MAIN_DB_PREFIX."bank * * @param int $date Date operation - * @param string $oper 1,2,3,4... (deprecated) or 'TYP','VIR','PRE','LIQ','VAD','CB','CHQ'... + * @param string $oper 'VIR','PRE','LIQ','VAD','CB','CHQ'... * @param string $label Descripton * @param float $amount Amount * @param string $num_chq Numero cheque ou virement diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index ce6f948aa0a..50b84840901 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4296,6 +4296,7 @@ class Facture extends CommonInvoice global $conf, $langs; $langs->load("bills"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php index 218cede3efa..400fb3be7ed 100644 --- a/htdocs/compta/facture/invoicetemplate_list.php +++ b/htdocs/compta/facture/invoicetemplate_list.php @@ -108,7 +108,7 @@ $hookmanager->initHooks(array('invoicereclist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('facture_rec'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index a0ce91bec86..aef7aa1869c 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -150,7 +150,7 @@ $hookmanager->initHooks(array('invoicelist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('facture'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); @@ -830,12 +830,15 @@ if ($resql) { print ''; print '
'; + /* print $langs->trans('From').' '; print $form->selectDate($search_datelimit_start ? $search_datelimit_start : -1, 'search_datelimit_start', 0, 0, 1); print '
'; print '
'; - print $langs->trans('to').' '; + print $langs->trans('to').' ';*/ + print $langs->trans("Before").' '; print $form->selectDate($search_datelimit_end ? $search_datelimit_end : -1, 'search_datelimit_end', 0, 0, 1); + print '
'.$langs->trans("Alert"); print '
'; print ''; } @@ -1442,7 +1445,7 @@ if ($resql) { $userstatic->id = $obj->fk_user_author; $userstatic->login = $obj->login; - print ''; + print ''; if ($userstatic->id) print $userstatic->getLoginUrl(1); else print ' '; print "\n"; diff --git a/htdocs/compta/paymentbybanktransfer/index.php b/htdocs/compta/paymentbybanktransfer/index.php index 2f9d7ed127f..e2477d86544 100644 --- a/htdocs/compta/paymentbybanktransfer/index.php +++ b/htdocs/compta/paymentbybanktransfer/index.php @@ -68,7 +68,7 @@ print '
'; $thirdpartystatic = new Societe($db); -$invoicestatic = new Facture($db); +$invoicestatic = new FactureFournisseur($db); $bprev = new BonPrelevement($db); print '
'; diff --git a/htdocs/compta/prelevement/card.php b/htdocs/compta/prelevement/card.php index 5bce8045df9..4ec2b5d3443 100644 --- a/htdocs/compta/prelevement/card.php +++ b/htdocs/compta/prelevement/card.php @@ -86,7 +86,11 @@ if (empty($reshook)) $res = $object->delete($user); if ($res > 0) { - header("Location: index.php"); + if ($object->type == 'bank-transfer') { + header("Location: ".DOL_URL_ROOT.'/compta/paymentbybanktransfer/index.php'); + } else { + header("Location: ".DOL_URL_ROOT.'/compta/prelevement/index.php'); + } exit; } } @@ -142,11 +146,9 @@ if (empty($reshook)) $dt = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int')); $error = $object->set_infocredit($user, $dt); - if ($error) { - header("Location: card.php?id=".$id."&error=$error"); - exit; + setEventMessages($object->error, $object->errors, 'errors'); } } } diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 1ac0926792e..1bea234abfc 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; @@ -67,6 +68,9 @@ class BonPrelevement extends CommonObject public $emetteur_bic; public $emetteur_ics; + public $date_trans; + public $user_trans; + public $total; public $fetched; public $statut; // 0-Wait, 1-Trans, 2-Done @@ -405,7 +409,7 @@ class BonPrelevement extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Set direct debit order to "credited" status. + * Set direct debit or credit transfer order to "paid" status. * * @param User $user Id of user * @param int $date date of action @@ -420,118 +424,151 @@ class BonPrelevement extends CommonObject if ($this->fetched == 1) { - if ($date >= $this->date_trans) + if ($date < $this->date_trans) { - if ($this->db->begin()) + $this->error = 'DateOfMovementLowerThanDateOfFileTransmission'; + dol_syslog("bon-prelevment::set_infocredit 1027 ".$this->error); + return -1027; + } + + $this->db->begin(); + + $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_bons "; + $sql .= " SET fk_user_credit = ".$user->id; + $sql .= ", statut = ".self::STATUS_CREDITED; + $sql .= ", date_credit = '".$this->db->idate($date)."'"; + $sql .= " WHERE rowid=".$this->id; + $sql .= " AND entity = ".$conf->entity; + $sql .= " AND statut = ".self::STATUS_TRANSFERED; + + $resql = $this->db->query($sql); + if ($resql) + { + $langs->load('withdrawals'); + $subject = $langs->trans("InfoCreditSubject", $this->ref); + $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour')); + + //Add payment of withdrawal into bank + $bankaccount = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; + $facs = array(); + $amounts = array(); + $amountsperthirdparty = array(); + + $facs = $this->getListInvoices(1); + + // Loop on each invoice. $facs=array(0=>id, 1=>amount requested) + $num = count($facs); + for ($i = 0; $i < $num; $i++) { - $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_bons "; - $sql .= " SET fk_user_credit = ".$user->id; - $sql .= ", statut = ".self::STATUS_CREDITED; - $sql .= ", date_credit = '".$this->db->idate($date)."'"; - $sql .= " WHERE rowid=".$this->id; - $sql .= " AND entity = ".$conf->entity; - $sql .= " AND statut = ".self::STATUS_TRANSFERED; - - if ($this->db->query($sql)) - { - $langs->load('withdrawals'); - $subject = $langs->trans("InfoCreditSubject", $this->ref); - $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour')); - - //Add payment of withdrawal into bank - $bankaccount = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; - $facs = array(); - $amounts = array(); - $amountsperthirdparty = array(); - - $facs = $this->getListInvoices(1); - - // Loop on each invoice. $facs=array(0=>id, 1=>amount requested) - $num = count($facs); - for ($i = 0; $i < $num; $i++) - { - $fac = new Facture($this->db); - $fac->fetch($facs[$i][0]); - $amounts[$fac->id] = $facs[$i][1]; - $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1]; - - $totalpaye = $fac->getSommePaiement(); - $totalcreditnotes = $fac->getSumCreditNotesUsed(); - $totaldeposits = $fac->getSumDepositsUsed(); - $alreadypayed = $totalpaye + $totalcreditnotes + $totaldeposits; - - if (price2num($alreadypayed + $facs[$i][1], 'MT') == $fac->total_ttc) { - $result = $fac->set_paid($user); - } - } - - // Make one payment per customer - foreach ($amountsperthirdparty as $thirdpartyid => $cursoramounts) - { - $paiement = new Paiement($this->db); - $paiement->datepaye = $date; - $paiement->amounts = $cursoramounts; // Array with detail of dispatching of payments for each invoice - $paiement->paiementid = 3; // - $paiement->num_payment = $this->ref; // Set ref of direct debit note - $paiement->num_paiement = $this->ref; // For backward compatibility - $paiement->id_prelevement = $this->id; - - $paiement_id = $paiement->create($user); - if ($paiement_id < 0) - { - dol_syslog(get_class($this)."::set_infocredit AddPayment Error"); - $error++; - } else { - $result = $paiement->addPaymentToBank($user, 'payment', '(WithdrawalPayment)', $bankaccount, '', ''); - if ($result < 0) - { - dol_syslog(get_class($this)."::set_infocredit AddPaymentToBank Error"); - $error++; - } - } - //var_dump($paiement->amounts); - //var_dump($thirdpartyid); - //var_dump($cursoramounts); - } - - // Update withdrawal line - // TODO: Translate to ligneprelevement.class.php - $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; - $sql .= " SET statut = 2"; - $sql .= " WHERE fk_prelevement_bons = ".$this->id; - - if (!$this->db->query($sql)) - { - dol_syslog(get_class($this)."::set_infocredit Update lines Error"); - $error++; - } + if ($this->type == 'bank-transfer') { + $fac = new FactureFournisseur($this->db); } else { - dol_syslog(get_class($this)."::set_infocredit Update Bons Error"); + $fac = new Facture($this->db); + } + + $result = $fac->fetch($facs[$i][0]); + + $amounts[$fac->id] = $facs[$i][1]; + $amountsperthirdparty[$fac->socid][$fac->id] = $facs[$i][1]; + + $totalpaye = $fac->getSommePaiement(); + $totalcreditnotes = $fac->getSumCreditNotesUsed(); + $totaldeposits = $fac->getSumDepositsUsed(); + $alreadypayed = $totalpaye + $totalcreditnotes + $totaldeposits; + + // @TODO Move this after creation of payment + if (price2num($alreadypayed + $facs[$i][1], 'MT') == $fac->total_ttc) { + $result = $fac->set_paid($user); + if ($result < 0) { + $this->error = $fac->error; + $this->errors = $fac->errors; + } + } + } + //var_dump($amountsperthirdparty);exit; + + // Make one payment per customer + foreach ($amountsperthirdparty as $thirdpartyid => $cursoramounts) + { + if ($this->type == 'bank-transfer') { + $paiement = new PaiementFourn($this->db); + } else { + $paiement = new Paiement($this->db); + } + $paiement->datepaye = $date; + $paiement->amounts = $cursoramounts; // Array with detail of dispatching of payments for each invoice + + if ($this->type == 'bank-transfer') { + $paiement->paiementid = 2; + $paiement->paiementcode = 'VIR'; + } else { + $paiement->paiementid = 3; + $paiement->paiementcode = 'PRE'; + } + + $paiement->num_payment = $this->ref; // Set ref of direct debit note + $paiement->num_paiement = $this->ref; // For backward compatibility + $paiement->id_prelevement = $this->id; + + $paiement_id = $paiement->create($user); // This use ->paiementid, that is ID of payment mode + if ($paiement_id < 0) + { + $error++; + $this->error = $paiement->error; + $this->errors = $paiement->errors; + dol_syslog(get_class($this)."::set_infocredit AddPayment Error ".$this->error); + } else { + if ($this->type == 'bank-transfer') { + $modeforaddpayment = 'payment_supplier'; + } else { + $modeforaddpayment = 'payment'; + } + + $result = $paiement->addPaymentToBank($user, $modeforaddpayment, '(WithdrawalPayment)', $bankaccount, '', ''); + if ($result < 0) + { + $error++; + $this->error = $paiement->error; + $this->errors = $paiement->errors; + dol_syslog(get_class($this)."::set_infocredit AddPaymentToBank Error ".$this->error); + } + } + //var_dump($paiement->amounts); + //var_dump($thirdpartyid); + //var_dump($cursoramounts); + } + + // Update withdrawal line + // TODO: Translate to ligneprelevement.class.php + if (! $error) { + $sql = " UPDATE ".MAIN_DB_PREFIX."prelevement_lignes"; + $sql .= " SET statut = 2"; + $sql .= " WHERE fk_prelevement_bons = ".$this->id; + + if (!$this->db->query($sql)) { + dol_syslog(get_class($this)."::set_infocredit Update lines Error"); $error++; } - - /* - * End of procedure - */ - if ($error == 0) - { - $this->date_credit = $date; - $this->statut = self::STATUS_CREDITED; - - $this->db->commit(); - return 0; - } else { - $this->db->rollback(); - dol_syslog("bon-prelevment::set_infocredit ROLLBACK "); - return -1; - } - } else { - dol_syslog(get_class($this)."::set_infocredit 1025 Open SQL transaction impossible "); - return -1025; } } else { - dol_syslog("bon-prelevment::set_infocredit 1027 Date de credit < Date de trans "); - return -1027; + $this->error = $this->db->lasterror(); + dol_syslog(get_class($this)."::set_infocredit Update Bons Error"); + $error++; + } + + /* + * End of procedure + */ + if ($error == 0) + { + $this->date_credit = $date; + $this->statut = self::STATUS_CREDITED; + + $this->db->commit(); + return 0; + } else { + $this->db->rollback(); + return -1; } } else { return -1026; @@ -561,7 +598,7 @@ class BonPrelevement extends CommonObject $sql .= " SET fk_user_trans = ".$user->id; $sql .= " , date_trans = '".$this->db->idate($date)."'"; $sql .= " , method_trans = ".$method; - $sql .= " , statut = 1"; + $sql .= " , statut = ".self::STATUS_TRANSFERED; $sql .= " WHERE rowid = ".$this->id; $sql .= " AND entity = ".$conf->entity; $sql .= " AND statut = 0"; @@ -583,6 +620,7 @@ class BonPrelevement extends CommonObject { $this->date_trans = $date; $this->statut = 1; + $this->user_trans = $user->id; $this->db->commit(); return 0; @@ -613,7 +651,12 @@ class BonPrelevement extends CommonObject /* * Returns all invoices presented within same order */ - $sql = "SELECT fk_facture"; + $sql = "SELECT "; + if ($this->type == 'bank-transfer') { + $sql .= " pf.fk_facture_fourn"; + } else { + $sql .= " pf.fk_facture"; + } if ($amounts) $sql .= ", SUM(pl.amount)"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql .= " , ".MAIN_DB_PREFIX."prelevement_lignes as pl"; @@ -622,7 +665,13 @@ class BonPrelevement extends CommonObject $sql .= " AND pl.fk_prelevement_bons = p.rowid"; $sql .= " AND p.rowid = ".$this->id; $sql .= " AND p.entity = ".$conf->entity; - if ($amounts) $sql .= " GROUP BY fk_facture"; + if ($amounts) { + if ($this->type == 'bank-transfer') { + $sql .= " GROUP BY fk_facture_fourn"; + } else { + $sql .= " GROUP BY fk_facture"; + } + } $resql = $this->db->query($sql); if ($resql) @@ -835,14 +884,11 @@ class BonPrelevement extends CommonObject $sql .= " AND f.rowid = pfd.fk_facture_fourn"; } $sql .= " AND s.rowid = f.fk_soc"; - //if ($banque || $agence) $sql.= " AND s.rowid = sr.fk_soc"; - $sql .= " AND f.fk_statut = 1"; + $sql .= " AND f.fk_statut = 1"; // Invoice validated $sql .= " AND f.paye = 0"; $sql .= " AND pfd.traite = 0"; $sql .= " AND f.total_ttc > 0"; $sql .= " AND pfd.ext_payment_id IS NULL"; - //if ($banque) $sql.= " AND sr.code_banque = '".$conf->global->PRELEVEMENT_CODE_BANQUE."'"; - //if ($agence) $sql.= " AND sr.code_guichet = '".$conf->global->PRELEVEMENT_CODE_GUICHET."'"; dol_syslog(__METHOD__."::Read invoices, sql=".$sql, LOG_DEBUG); @@ -951,15 +997,13 @@ class BonPrelevement extends CommonObject if (count($factures_prev) > 0) { - if ($mode == 'real') - { + if ($mode == 'real') { $ok = 1; } else { - print $langs->trans("ModeWarning"); //"Option for real mode was not set, we stop after this simulation\n"; + print $langs->trans("ModeWarning"); // "Option for real mode was not set, we stop after this simulation\n"; } } - if ($ok) { /* @@ -1002,7 +1046,7 @@ class BonPrelevement extends CommonObject // Create withdraw receipt in database $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons ("; - $sql .= " ref, entity, datec, type"; + $sql .= "ref, entity, datec, type"; $sql .= ") VALUES ("; $sql .= "'".$this->db->escape($ref)."'"; $sql .= ", ".$conf->entity; @@ -1028,6 +1072,12 @@ class BonPrelevement extends CommonObject if (!$error) { + if ($type != 'bank-transfer') { + $fact = new Facture($this->db); + } else { + $fact = new FactureFournisseur($this->db); + } + /* * Create withdrawal receipt in database */ @@ -1036,11 +1086,14 @@ class BonPrelevement extends CommonObject foreach ($factures_prev as $fac) // Add a link in database for each invoice { // Fetch invoice - $fact = new Facture($this->db); - $fact->fetch($fac[0]); + $result = $fact->fetch($fac[0]); + if ($result < 0) { + $this->error = 'ERRORBONPRELEVEMENT Failed to load invoice with id '.$fac[0]; + break; + } /* - * Add standing order + * Add standing order. This add record into llx_prelevement_lignes * * $fac[0] : invoice_id * $fac[1] : ??? @@ -1051,9 +1104,7 @@ class BonPrelevement extends CommonObject * $fac[6] : cle rib * $fac[7] : amount * $fac[8] : client nom - * $fac[2] : client id */ - $ri = $this->AddFacture($fac[0], $fac[2], $fac[8], $fac[7], $fac[3], $fac[4], $fac[5], $fac[6], $type); if ($ri <> 0) { @@ -1068,7 +1119,6 @@ class BonPrelevement extends CommonObject $sql .= " WHERE rowid = ".$fac[1]; $resql = $this->db->query($sql); - if (!$resql) { $error++; @@ -1081,7 +1131,7 @@ class BonPrelevement extends CommonObject if (!$error) { /* - * Create file of direct debit order or credit transfer into a XML file + * Create file of type='direct-debit' for direct debit order or type='bank-transfer' for credit transfer into a XML file */ dol_syslog(__METHOD__."::Init direct debit or credit transfer file for ".count($factures_prev)." invoices", LOG_DEBUG); @@ -1092,6 +1142,9 @@ class BonPrelevement extends CommonObject $this->reference_remise = $ref; $id = $conf->global->PRELEVEMENT_ID_BANKACCOUNT; + if ($type == 'bank-transfer') { + $id = $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT; + } $account = new Account($this->db); if ($account->fetch($id) > 0) { @@ -1113,24 +1166,31 @@ class BonPrelevement extends CommonObject // Generation of direct debit or credti transfer file $this->filename (May be a SEPA file for european countries) // This also set the property $this->total with amount that is included into file $result = $this->generate($format, $executiondate, $type); + if ($result < 0) { + /*var_dump($this->error); + var_dump($this->invoice_in_error); */ + $error++; + } } dol_syslog(__METHOD__."::End withdraw receipt, file ".$this->filename, LOG_DEBUG); } - //var_dump($factures_prev);exit; + //var_dump($this->total);exit; /* * Update total defined after generation of file */ - $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; - $sql .= " SET amount = ".price2num($this->total); - $sql .= " WHERE rowid = ".$this->id; - $sql .= " AND entity = ".$conf->entity; + if (! $error) { + $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_bons"; + $sql .= " SET amount = ".price2num($this->total); + $sql .= " WHERE rowid = ".$this->id; + $sql .= " AND entity = ".$conf->entity; - $resql = $this->db->query($sql); - if (!$resql) - { - $error++; - dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR); + $resql = $this->db->query($sql); + if (!$resql) + { + $error++; + dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR); + } } if (!$error && !$notrigger) @@ -1149,11 +1209,11 @@ class BonPrelevement extends CommonObject if (!$error) { $this->db->commit(); + return count($factures_prev); } else { $this->db->rollback(); + return -1; } - - return count($factures_prev); } else { return 0; } @@ -1399,7 +1459,7 @@ class BonPrelevement extends CommonObject * * @param string $format FRST, RCUR or ALL * @param string $executiondate Date to execute transfer - * @param string $type 'direct-debit' or 'credit-transfer' + * @param string $type 'direct-debit' or 'bank-transfer' * @return int >=0 if OK, <0 if KO */ public function generate($format = 'ALL', $executiondate = '', $type = 'direct-debit') @@ -1427,112 +1487,9 @@ class BonPrelevement extends CommonObject { $found++; - if ($type == 'bank-transfer') { + if ($type != 'bank-transfer') { /** - * SECTION CREATION FICHIER SEPA - CREDIT TRANSFER - */ - // SEPA Initialisation - $CrLf = "\n"; - - $now = dol_now(); - - $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S'); - - $date_actu = $now; - if (!empty($executiondate)) $date_actu = $executiondate; - - $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d'); - $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S'); - $fileCrediteurSection = ''; - $fileEmetteurSection = ''; - $i = 0; - - /* - * Section Creditor (sepa Crediteurs bloc lines) - */ - - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; - $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; - $sql .= " f.ref as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; - $sql .= " FROM"; - $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; - $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf,"; - $sql .= " ".MAIN_DB_PREFIX."societe as soc,"; - $sql .= " ".MAIN_DB_PREFIX."c_country as c,"; - $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib"; - $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; - $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture_fourn = f.rowid"; - $sql .= " AND soc.fk_pays = c.rowid"; - $sql .= " AND soc.rowid = f.fk_soc"; - $sql .= " AND rib.fk_soc = f.fk_soc"; - $sql .= " AND rib.default_rib = 1"; - $sql .= " AND rib.type = 'ban'"; - //print $sql; - - // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); - $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum); - $this->total = $this->total + $obj->somme; - $i++; - } - $nbtotalDrctDbtTxInf = $i; - } else { - fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers - $result = -2; - } - - // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf - if ($result != -2) - { - $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format); - } - - /** - * SECTION CREATION SEPA FILE - CREDTI TRANSFER - ISO200022 - */ - // SEPA File Header - fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); - fputs($this->file, ''.$CrLf); - fputs($this->file, ' '.$CrLf); - // SEPA Group header - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.('CREDTRANS'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); - fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); - fputs($this->file, ' '.$i.''.$CrLf); - fputs($this->file, ' '.$this->total.''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$conf->global->PRELEVEMENT_ICS.''.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - // SEPA File Emetteur (mycompany) - if ($result != -2) - { fputs($this-> file, $fileEmetteurSection); } - // SEPA File Creditors - if ($result != -2) - { fputs($this-> file, $fileCrediteurSection); } - // SEPA FILE FOOTER - fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.$CrLf); - fputs($this->file, ''.$CrLf); - } else { - /** - * SECTION CREATION FICHIER SEPA + * SECTION CREATION FICHIER SEPA - DIRECT DEBIT */ // SEPA Initialisation $CrLf = "\n"; @@ -1554,9 +1511,10 @@ class BonPrelevement extends CommonObject * Section Debitor (sepa Debiteurs bloc lines) */ - $sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; - $sql .= " f.ref as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " f.ref as fac, pf.fk_facture as idfac,"; + $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; $sql .= " ".MAIN_DB_PREFIX."facture as f,"; @@ -1567,28 +1525,39 @@ class BonPrelevement extends CommonObject $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; $sql .= " AND pf.fk_facture = f.rowid"; + $sql .= " AND f.fk_soc = soc.rowid"; $sql .= " AND soc.fk_pays = c.rowid"; - $sql .= " AND soc.rowid = f.fk_soc"; $sql .= " AND rib.fk_soc = f.fk_soc"; $sql .= " AND rib.default_rib = 1"; $sql .= " AND rib.type = 'ban'"; - //print $sql; // Define $fileDebiteurSection. One section DrctDbtTxInf per invoice. $resql = $this->db->query($sql); if ($resql) { + $cachearraytotestduplicate = array(); + $num = $this->db->num_rows($resql); while ($i < $num) { $obj = $this->db->fetch_object($resql); + + if (! empty($cachearraytotestduplicate[$obj->idfac])) { + $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid); + $this->invoice_in_error[$obj->idfac] = $this->error; + $result = -2; + break; + } + $cachearraytotestduplicate[$obj->idfac] = $obj->rowid; + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); - $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum); + $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); $this->total = $this->total + $obj->somme; $i++; } $nbtotalDrctDbtTxInf = $i; } else { + $this->error = $this->db->lasterror(); fputs($this->file, 'ERROR DEBITOR '.$sql.$CrLf); // DEBITOR = Customers $result = -2; } @@ -1596,7 +1565,7 @@ class BonPrelevement extends CommonObject // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf if ($result != -2) { - $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format); + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); } /** @@ -1608,7 +1577,7 @@ class BonPrelevement extends CommonObject fputs($this->file, ' '.$CrLf); // SEPA Group header fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.('PREL'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); + fputs($this->file, ' '.('DD/'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); fputs($this->file, ' '.$i.''.$CrLf); fputs($this->file, ' '.$this->total.''.$CrLf); @@ -1633,21 +1602,135 @@ class BonPrelevement extends CommonObject fputs($this->file, ' '.$CrLf); fputs($this->file, ' '.$CrLf); fputs($this->file, ''.$CrLf); + } else { + /** + * SECTION CREATION FICHIER SEPA - CREDIT TRANSFER + */ + // SEPA Initialisation + $CrLf = "\n"; + + $now = dol_now(); + + $dateTime_ECMA = dol_print_date($now, '%Y-%m-%dT%H:%M:%S'); + + $date_actu = $now; + if (!empty($executiondate)) $date_actu = $executiondate; + + $dateTime_YMD = dol_print_date($date_actu, '%Y%m%d'); + $dateTime_YMDHMS = dol_print_date($date_actu, '%Y%m%d%H%M%S'); + $fileCrediteurSection = ''; + $fileEmetteurSection = ''; + $i = 0; + + /* + * Section Creditor (sepa Crediteurs bloc lines) + */ + + $sql = "SELECT soc.rowid as socid, soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,"; + $sql .= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,"; + $sql .= " f.ref as fac, pf.fk_facture_fourn as idfac,"; + $sql .= " rib.rowid, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum, rib.rum, rib.date_rum"; + $sql .= " FROM"; + $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; + $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf,"; + $sql .= " ".MAIN_DB_PREFIX."societe as soc,"; + $sql .= " ".MAIN_DB_PREFIX."c_country as c,"; + $sql .= " ".MAIN_DB_PREFIX."societe_rib as rib"; + $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; + $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; + $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND f.fk_soc = soc.rowid"; + $sql .= " AND soc.fk_pays = c.rowid"; + $sql .= " AND rib.fk_soc = f.fk_soc"; + $sql .= " AND rib.default_rib = 1"; + $sql .= " AND rib.type = 'ban'"; + + // Define $fileCrediteurSection. One section DrctDbtTxInf per invoice. + $resql = $this->db->query($sql); + if ($resql) + { + $cachearraytotestduplicate = array(); + + $num = $this->db->num_rows($resql); + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + + if (! empty($cachearraytotestduplicate[$obj->idfac])) { + $this->error = $langs->trans('ErrorCompanyHasDuplicateDefaultBAN', $obj->socid); + $this->invoice_in_error[$obj->idfac] = $this->error; + $result = -2; + break; + } + $cachearraytotestduplicate[$obj->idfac] = $obj->rowid; + + $daterum = (!empty($obj->date_rum)) ? $this->db->jdate($obj->date_rum) : $this->db->jdate($obj->datec); + $fileCrediteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $daterum, $obj->drum, $obj->rum, $type); + $this->total = $this->total + $obj->somme; + $i++; + } + $nbtotalDrctDbtTxInf = $i; + } else { + $this->error = $this->db->lasterror(); + fputs($this->file, 'ERROR CREDITOR '.$sql.$CrLf); // CREDITORS = Suppliers + $result = -2; + } + + // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf + if ($result != -2) { + $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); + } + + /** + * SECTION CREATION SEPA FILE - CREDIT TRANSFER - ISO200022 + */ + // SEPA File Header + fputs($this->file, '<'.'?xml version="1.0" encoding="UTF-8" standalone="yes"?'.'>'.$CrLf); + fputs($this->file, ''.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA Group header + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.('TRF/'.$dateTime_YMD.'/REF'.$this->id).''.$CrLf); + fputs($this->file, ' '.$dateTime_ECMA.''.$CrLf); + fputs($this->file, ' '.$i.''.$CrLf); + fputs($this->file, ' '.$this->total.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$conf->global->PRELEVEMENT_ICS.''.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + // SEPA File Emetteur (mycompany) + if ($result != -2) + { fputs($this-> file, $fileEmetteurSection); } + // SEPA File Creditors + if ($result != -2) + { fputs($this-> file, $fileCrediteurSection); } + // SEPA FILE FOOTER + fputs($this->file, ' '.$CrLf); + fputs($this->file, ' '.$CrLf); + fputs($this->file, ''.$CrLf); } } // Build file for Other Countries with unknow format if (!$found) { - if ($type == 'bank-transfer') { + if ($type != 'bank-transfer') { $sql = "SELECT pl.amount"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql .= " ".MAIN_DB_PREFIX."facture as f,"; $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture_fourn = f.rowid"; + $sql .= " AND pf.fk_facture = f.rowid"; // Lines $i = 0; @@ -1671,11 +1754,11 @@ class BonPrelevement extends CommonObject $sql = "SELECT pl.amount"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_lignes as pl,"; - $sql .= " ".MAIN_DB_PREFIX."facture as f,"; + $sql .= " ".MAIN_DB_PREFIX."facture_fourn as f,"; $sql .= " ".MAIN_DB_PREFIX."prelevement_facture as pf"; $sql .= " WHERE pl.fk_prelevement_bons = ".$this->id; $sql .= " AND pl.rowid = pf.fk_prelevement_lignes"; - $sql .= " AND pf.fk_facture = f.rowid"; + $sql .= " AND pf.fk_facture_fourn = f.rowid"; // Lines $i = 0; @@ -1712,6 +1795,22 @@ class BonPrelevement extends CommonObject } + /** + * Generate dynamically a RUM number for a customer bank account + * + * @param string $row_code_client Customer code (soc.code_client) + * @param int $row_datec Creation date of bank account (rib.datec) + * @param string $row_drum Id of customer bank account (rib.rowid) + * @return string RUM number + */ + public static function buildRumNumber($row_code_client, $row_datec, $row_drum) + { + global $langs; + $pre = substr(dol_string_nospecial(dol_string_unaccent($langs->transnoentitiesnoconv('RUM'))), 0, 3); // Must always be on 3 char ('RUM' or 'UMR'. This is a protection against bad translation) + return $pre.'-'.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Write recipient of request (customer) @@ -1725,9 +1824,11 @@ class BonPrelevement extends CommonObject * @param string $ref ref of invoice * @param int $facid id of invoice * @param string $rib_dom rib domiciliation + * @param string $type 'direct-debit' or 'bank-transfer' * @return void + * @see EnregDestinataireSEPA() */ - public function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom = '') + public function EnregDestinataire($rowid, $client_nom, $rib_banque, $rib_guichet, $rib_number, $amount, $ref, $facid, $rib_dom = '', $type = 'direct-debit') { // phpcs:enable fputs($this->file, "06"); @@ -1784,22 +1885,6 @@ class BonPrelevement extends CommonObject fputs($this->file, "\n"); } - - /** - * Build RUM number for a customer bank account - * - * @param string $row_code_client Customer code (soc.code_client) - * @param int $row_datec Creation date of bank account (rib.datec) - * @param string $row_drum Id of customer bank account (rib.rowid) - * @return string RUM number - */ - public static function buildRumNumber($row_code_client, $row_datec, $row_drum) - { - global $langs; - $pre = substr(dol_string_nospecial(dol_string_unaccent($langs->transnoentitiesnoconv('RUM'))), 0, 3); // Must always be on 3 char ('RUM' or 'UMR'. This is a protection against bad translation) - return $pre.'-'.$row_code_client.'-'.$row_drum.'-'.date('U', $row_datec); - } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Write recipient of request (customer) @@ -1821,9 +1906,11 @@ class BonPrelevement extends CommonObject * @param string $row_datec rib.datec, * @param string $row_drum rib.rowid used to generate rum * @param string $row_rum rib.rum Rum defined on company bank account + * @param string $type 'direct-debit' or 'bank-transfer' * @return string Return string with SEPA part DrctDbtTxInf + * @see EnregDestinataire() */ - public function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum) + public function EnregDestinataireSEPA($row_code_client, $row_nom, $row_address, $row_zip, $row_town, $row_country_code, $row_cb, $row_cg, $row_cc, $row_somme, $row_ref, $row_idfac, $row_iban, $row_bic, $row_datec, $row_drum, $row_rum, $type = 'direct-debit') { // phpcs:enable global $conf; @@ -1831,7 +1918,7 @@ class BonPrelevement extends CommonObject include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $CrLf = "\n"; - $Rowing = sprintf("%06d", $row_idfac); + $Rowing = sprintf("%010d", $row_idfac); // Define value for RUM // Example: RUMCustomerCode-CustomerBankAccountId-01424448606 (note: Date is date of creation of CustomerBankAccountId) @@ -1840,57 +1927,108 @@ class BonPrelevement extends CommonObject // Define date of RUM signature $DtOfSgntr = dol_print_date($row_datec, '%Y-%m-%d'); - $XML_DEBITOR = ''; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - // $XML_DEBITOR .=' '.('AS-'.dol_trunc($row_ref,20).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters - $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.round($row_somme, 2).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$Rum.''.$CrLf; - $XML_DEBITOR .= ' '.$DtOfSgntr.''.$CrLf; - $XML_DEBITOR .= ' false'.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$row_bic.''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$row_country_code.''.$CrLf; - $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); - $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); - if (trim($addressline1)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; - if (trim($addressline2)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - // $XML_DEBITOR .=' '.($row_ref.'/'.$Rowing.'/'.$Rum).''.$CrLf; - // $XML_DEBITOR .=' '.dol_trunc($row_ref, 135).''.$CrLf; // 140 max - $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max - $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.$CrLf; - return $XML_DEBITOR; + if ($type != 'bank-transfer') { + // SEPA Paiement Information of buyer for Direct debit + $XML_DEBITOR = ''; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum) + $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.round($row_somme, 2).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$Rum.''.$CrLf; + $XML_DEBITOR .= ' '.$DtOfSgntr.''.$CrLf; + $XML_DEBITOR .= ' false'.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$row_bic.''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$row_country_code.''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); + if (trim($addressline1)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; + if (trim($addressline2)) $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + // A string with some information on payment - 140 max + $XML_DEBITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max + $XML_DEBITOR .= ' '.$CrLf; + $XML_DEBITOR .= ' '.$CrLf; + return $XML_DEBITOR; + } else { + // SEPA Paiement Information of seller for Credit Transfer + $XML_CREDITOR = ''; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + // Add EndToEndId. Must be a unique ID for each payment (for example by including bank, buyer or seller, date, checksum) + $XML_CREDITOR .= ' '.(($conf->global->PRELEVEMENT_END_TO_END != "") ? $conf->global->PRELEVEMENT_END_TO_END : ('AS-'.dol_trunc($row_ref, 20)).'-'.$Rowing).''.$CrLf; // ISO20022 states that EndToEndId has a MaxLength of 35 characters + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.round($row_somme, 2).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + /* + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$Rum.''.$CrLf; + $XML_CREDITOR .= ' '.$DtOfSgntr.''.$CrLf; + $XML_CREDITOR .= ' false'.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + */ + //$XML_CREDITOR .= ' SLEV'.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$row_bic.''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.dolEscapeXML(strtoupper(dol_string_unaccent($row_nom))).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$row_country_code.''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => ""))); + if (trim($addressline1)) $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc($addressline1, 70, 'right', 'UTF-8', true)).''.$CrLf; + if (trim($addressline2)) $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc($addressline2, 70, 'right', 'UTF-8', true)).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.preg_replace('/\s/', '', $row_iban).''.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + // A string with some information on payment - 140 max + $XML_CREDITOR .= ' '.(($conf->global->PRELEVEMENT_USTRD != "") ? $conf->global->PRELEVEMENT_USTRD : dol_trunc($row_ref, 135)).''.$CrLf; // 140 max + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + return $XML_CREDITOR; + } } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Write sender of request (me) + * Write sender of request (me). * + * @param string $type 'direct-debit' or 'bank-transfer' * @return void + * @see EnregEmetteurSEPA() */ - public function EnregEmetteur() + public function EnregEmetteur($type = 'direct-debit') { // phpcs:enable fputs($this->file, "03"); @@ -1962,9 +2100,11 @@ class BonPrelevement extends CommonObject * @param float $total Total * @param string $CrLf End of line character * @param string $format FRST or RCUR or ALL + * @param string $type 'direct-debit' or 'bank-transfer' * @return string String with SEPA Sender + * @see EnregEmetteur() */ - public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST') + public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST', $type = 'direct-debit') { // phpcs:enable // SEPA INITIALISATION @@ -1991,7 +2131,7 @@ class BonPrelevement extends CommonObject $this->raison_sociale = $account->proprio; } - // Récupération info demandeur + // Get pending payments $sql = "SELECT rowid, ref"; $sql .= " FROM"; $sql .= " ".MAIN_DB_PREFIX."prelevement_bons as pb"; @@ -2002,72 +2142,134 @@ class BonPrelevement extends CommonObject { $obj = $this->db->fetch_object($resql); - // DONNEES BRUTES : par la suite Rows['XXX'] de la requete au dessus $country = explode(':', $configuration->global->MAIN_INFO_SOCIETE_COUNTRY); $IdBon = sprintf("%05d", $obj->rowid); $RefBon = $obj->ref; - // SEPA Paiement Information - $XML_SEPA_INFO = ''; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.('PREL'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; - $XML_SEPA_INFO .= ' DD'.$CrLf; - $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; - $XML_SEPA_INFO .= ' '.$total.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' CORE'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$format.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$dateTime_ETAD.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; - $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); - $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); - if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; - if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - /* $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; - $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; - $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf;*/ - $XML_SEPA_INFO .= ' SLEV'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; + if ($type != 'bank-transfer') { + // SEPA Paiement Information of my company for Direct debit + $XML_SEPA_INFO = ''; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.('DD/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' DD'.$CrLf; + $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; + $XML_SEPA_INFO .= ' '.$total.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' CORE'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$format.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$dateTime_ETAD.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); + if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; + if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + /* $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + } else { + // SEPA Paiement Information of my company for Credit Transfer + $XML_SEPA_INFO = ''; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.('TRF/'.$dateTime_YMD.'/ID'.$IdBon.'-'.$RefBon).''.$CrLf; + $XML_SEPA_INFO .= ' TRF'.$CrLf; + //$XML_SEPA_INFO .= ' False'.$CrLf; + $XML_SEPA_INFO .= ' '.$nombre.''.$CrLf; + $XML_SEPA_INFO .= ' '.$total.''.$CrLf; + /* + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' TRF'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SECU'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + */ + $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.strtoupper(dol_string_unaccent($this->raison_sociale)).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $addressline1 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => ""))); + $addressline2 = dol_string_unaccent(strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => ""))); + if ($addressline1) $XML_SEPA_INFO .= ' '.$addressline1.''.$CrLf; + if ($addressline2) $XML_SEPA_INFO .= ' '.$addressline2.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.preg_replace('/\s/', '', $this->emetteur_iban).''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_bic.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + /* $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->raison_sociale.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ADDRESS.''.$CrLf; + $XML_SEPA_INFO .= ' '.$conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV + /*$XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ + } } else { fputs($this->file, 'INCORRECT EMETTEUR '.$XML_SEPA_INFO.$CrLf); - $result = -2; } return $XML_SEPA_INFO; } diff --git a/htdocs/compta/prelevement/class/ligneprelevement.class.php b/htdocs/compta/prelevement/class/ligneprelevement.class.php index 78e364c1abc..a645d2bb078 100644 --- a/htdocs/compta/prelevement/class/ligneprelevement.class.php +++ b/htdocs/compta/prelevement/class/ligneprelevement.class.php @@ -59,7 +59,7 @@ class LignePrelevement $langs->load("withdrawals"); $this->statuts[0] = $langs->trans("StatusWaiting"); - $this->statuts[2] = $langs->trans("StatusCredited"); + $this->statuts[2] = $langs->trans("StatusPaid"); $this->statuts[3] = $langs->trans("StatusRefused"); } diff --git a/htdocs/compta/prelevement/create.php b/htdocs/compta/prelevement/create.php index 0be8dfc9e52..f8d67de48c2 100644 --- a/htdocs/compta/prelevement/create.php +++ b/htdocs/compta/prelevement/create.php @@ -88,11 +88,9 @@ if (empty($reshook)) // $conf->global->PRELEVEMENT_CODE_BANQUE and $conf->global->PRELEVEMENT_CODE_GUICHET should be empty (we don't use them anymore) $result = $bprev->create($conf->global->PRELEVEMENT_CODE_BANQUE, $conf->global->PRELEVEMENT_CODE_GUICHET, $mode, $format, $executiondate, 0, $type); - if ($result < 0) - { + if ($result < 0) { setEventMessages($bprev->error, $bprev->errors, 'errors'); - } elseif ($result == 0) - { + } elseif ($result == 0) { $mesg = $langs->trans("NoInvoiceCouldBeWithdrawed", $format); setEventMessages($mesg, null, 'errors'); $mesg .= '
'."\n"; @@ -370,10 +368,15 @@ if ($resql) // RUM print ''; - print $thirdpartystatic->display_rib('rum'); - $format = $thirdpartystatic->display_rib('format'); - if ($type != 'bank-transfer') { - if ($format) print ' ('.$format.')'; + $rumtoshow = $thirdpartystatic->display_rib('rum'); + if ($rumtoshow) { + print $rumtoshow; + $format = $thirdpartystatic->display_rib('format'); + if ($type != 'bank-transfer') { + if ($format) print ' ('.$format.')'; + } + } else { + print img_warning($langs->trans("NoBankAccount")); } print ''; // Amount diff --git a/htdocs/compta/prelevement/demandes.php b/htdocs/compta/prelevement/demandes.php index feda7f0771d..53934deaac1 100644 --- a/htdocs/compta/prelevement/demandes.php +++ b/htdocs/compta/prelevement/demandes.php @@ -105,14 +105,17 @@ if ($type != 'bank-transfer') { llxHeader('', $title); $thirdpartystatic = new Societe($db); -$invoicestatic = new Facture($db); +if ($type == 'bank-transfer') { + $invoicestatic = new FactureFournisseur($db); +} else { + $invoicestatic = new Facture($db); +} // List of requests $sql = "SELECT f.ref, f.rowid, f.total_ttc,"; $sql .= " s.nom as name, s.rowid as socid,"; -$sql .= " pfd.date_demande as date_demande,"; -$sql .= " pfd.fk_user_demande"; +$sql .= " pfd.date_demande as date_demande, pfd.amount, pfd.fk_user_demande"; if ($type != 'bank-transfer') { $sql .= " FROM ".MAIN_DB_PREFIX."facture as f,"; } else { @@ -126,6 +129,7 @@ $sql .= " AND f.entity IN (".getEntity('invoice').")"; if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id; if ($socid) $sql .= " AND f.fk_soc = ".$socid; if (!$status) $sql .= " AND pfd.traite = 0"; +$sql .= " AND pfd.ext_payment_id IS NULL"; if ($status) $sql .= " AND pfd.traite = ".$status; $sql .= " AND f.total_ttc > 0"; if (empty($conf->global->WITHDRAWAL_ALLOW_ANY_INVOICE_STATUS)) @@ -141,7 +145,6 @@ if ($search_facture) $sql .= natural_search("f.ref", $search_facture); if ($search_societe) $sql .= natural_search("s.nom", $search_societe); $sql .= $db->order($sortfield, $sortorder); - // Count total nb of records $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) @@ -173,9 +176,9 @@ if (is_numeric($nbtotalofrecords) && $limit > $nbtotalofrecords) -$newcardbutton = ''.$langs->trans("Back").''; +$newcardbutton = ''.$langs->trans("Back").''; if ($type == 'bank-transfer') { - $newcardbutton = ''.$langs->trans("Back").''; + $newcardbutton = ''.$langs->trans("Back").''; } print ''; @@ -205,7 +208,7 @@ print ''; print ''; print_liste_field_titre("Bill", $_SERVER["PHP_SELF"]); print_liste_field_titre("Company", $_SERVER["PHP_SELF"]); -print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'right '); +print_liste_field_titre("AmountRequested", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'right '); print_liste_field_titre("DateRequest", $_SERVER["PHP_SELF"], "", "", $param, '', '', '', 'center '); print_liste_field_titre(''); print ''; @@ -228,12 +231,12 @@ while ($i < min($num, $limit)) $obj = $db->fetch_object($resql); if (empty($obj)) break; // Should not happen + $invoicestatic->fetch($obj->rowid); + print ''; // Ref facture print ''; @@ -243,7 +246,9 @@ while ($i < min($num, $limit)) print $thirdpartystatic->getNomUrl(1, 'customer'); print ''; - print ''; + print ''; print ''; diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 300bc6b8301..fcdb2f01404 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -105,7 +105,7 @@ if ($id > 0 || $ref) print ''; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''; @@ -158,7 +158,7 @@ if ($id > 0 || $ref) // List of invoices -$sql = "SELECT pf.rowid,"; +$sql = "SELECT pf.rowid, p.type,"; $sql .= " f.rowid as facid, f.ref as ref, f.total_ttc,"; $sql .= " s.rowid as socid, s.nom as name, pl.statut, pl.amount as amount_requested"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; @@ -191,8 +191,8 @@ $sql .= $db->order($sortfield, $sortorder); $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); + $resql = $db->query($sql); + $nbtotalofrecords = $db->num_rows($resql); if (($page * $limit) > $nbtotalofrecords) // if total resultset is smaller then paging size (filtering), goto and load page 0 { $page = 0; @@ -202,10 +202,10 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql .= $db->plimit($limit + 1, $offset); -$result = $db->query($sql); -if ($result) +$resql = $db->query($sql); +if ($resql) { - $num = $db->num_rows($result); + $num = $db->num_rows($resql); $i = 0; $param = "&id=".$id; @@ -234,22 +234,28 @@ if ($result) print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "s.nom", '', $param, '', $sortfield, $sortorder); print_liste_field_titre("AmountInvoice", $_SERVER["PHP_SELF"], "f.total_ttc", "", $param, 'class="right"', $sortfield, $sortorder); print_liste_field_titre("AmountRequested", $_SERVER["PHP_SELF"], "pl.amount", "", $param, 'class="right"', $sortfield, $sortorder); - print_liste_field_titre("StatusDebitCredit", $_SERVER["PHP_SELF"], "", "", $param, 'align="center"', $sortfield, $sortorder); + print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "", "", $param, 'align="center"', $sortfield, $sortorder); print_liste_field_titre(''); print "\n"; $totalinvoices = 0; $totalamount_requested = 0; + $invoicetmpcustomer = new Facture($db); + $invoicetmpsupplier = new FactureFournisseur($db); + while ($i < min($num, $limit)) { - $obj = $db->fetch_object($result); + $obj = $db->fetch_object($resql); - $invoicetmp->id = $obj->facid; - $invoicetmp->ref = $obj->ref; + if ($obj->type == 'bank-transfer') { + $invoicetmp = $invoicetmpsupplier; + } else { + $invoicetmp = $invoicetmpcustomer; + } + $invoicetmp->fetch($obj->facid); - $thirdpartytmp->id = $obj->socid; - $thirdpartytmp->name = $obj->name; + $thirdpartytmp->fetch($obj->socid); print ''; @@ -270,14 +276,15 @@ if ($result) // Status of requests print ''; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''; @@ -230,7 +230,7 @@ if ($resql) $i++; } } else { - print ''; + print ''; } if ($num > 0) diff --git a/htdocs/compta/prelevement/fiche-stat.php b/htdocs/compta/prelevement/fiche-stat.php index 3e6d85e9b42..c59ed2d4232 100644 --- a/htdocs/compta/prelevement/fiche-stat.php +++ b/htdocs/compta/prelevement/fiche-stat.php @@ -98,7 +98,7 @@ if ($prev_id > 0 || $ref) print ''; + print ' '.$langs->trans("By").' '.$muser->getFullName($langs).''; print ''; diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index e8c61c8b67c..eeb51e65442 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -10,6 +10,7 @@ * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2018-2019 Frédéric France * Copyright (C) 2019 Josep Lluís Amador + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -458,6 +459,23 @@ if (empty($reshook)) } } + if ($action == 'setprospectcontactlevel' && $user->rights->societe->contact->creer) + { + $object->fetch($id); + $object->fk_prospectlevel = GETPOST('prospect_contact_level_id', 'alpha'); + $result = $object->update($object->id, $user); + if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); + } + + // set communication status + if ($action == 'setstcomm') + { + $object->fetch($id); + $object->stcomm_id = dol_getIdFromCode($db, GETPOST('stcomm', 'alpha'), 'c_stcommcontact'); + $result = $object->update($object->id, $user); + if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); + } + // Actions to send emails $triggersendname = 'CONTACT_SENTBYMAIL'; $paramname = 'id'; @@ -1333,8 +1351,51 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) print ''; print '
'; - $invoicestatic->id = $obj->rowid; - $invoicestatic->ref = $obj->ref; print $invoicestatic->getNomUrl(1, 'withdraw'); print ''.price($obj->total_ttc).''; + print price($obj->amount, 1, $langs, 1, -1, -1, $conf->currency).' / '.price($obj->total_ttc, 1, $langs, 1, -1, -1, $conf->currency); + print ''.dol_print_date($db->jdate($obj->date_demande), 'day').'
'.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
'.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
'; - if ($obj->statut == 0) - { + if ($obj->statut == 0) { print '-'; - } elseif ($obj->statut == 2) - { - print $langs->trans("StatusCredited"); - } elseif ($obj->statut == 3) - { + } elseif ($obj->statut == 2) { + if ($obj->type == 'bank-transfer') { + print $langs->trans("StatusDebited"); + } else { + print $langs->trans("StatusCredited"); + } + } elseif ($obj->statut == 3) { print ''.$langs->trans("StatusRefused").''; } diff --git a/htdocs/compta/prelevement/fiche-rejet.php b/htdocs/compta/prelevement/fiche-rejet.php index dc13a666573..bddebaedda5 100644 --- a/htdocs/compta/prelevement/fiche-rejet.php +++ b/htdocs/compta/prelevement/fiche-rejet.php @@ -99,7 +99,7 @@ if ($prev_id > 0 || $ref) print '
'.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
'.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
'.$langs->trans("None").'
'.$langs->trans("None").'
'.$langs->trans("TransData").''; print dol_print_date($object->date_trans, 'day'); - print ' '.$langs->trans("By").' '.$muser->getFullName($langs).'
'.$langs->trans("TransMetod").''; print $object->methodes_trans[$object->method_trans]; print '
'; - print '
'; + + $object->fetch_thirdparty(); + + if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { + if ($object->thirdparty->client == 2 || $object->thirdparty->client == 3) + { + print '
'; + + print '
'; + print ''; + + // Level of prospect + print '"; + print ''; + + // Status of prospection + $object->loadCacheOfProspStatus(); + print ''; + + print "
'; + print ''; + print '
'; + print $langs->trans('ProspectLevel'); + print ''; + if ($action != 'editlevel' && $user->rights->societe->contact->creer) print 'id . '">' . img_edit($langs->trans('Modify'), 1) . '
'; + print '
'; + if ($action == 'editlevel') { + $formcompany->formProspectContactLevel($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->fk_prospectlevel, 'prospect_contact_level_id', 1); + } else { + print $object->getLibProspLevel(); + } + print "
' . $langs->trans("StatusProsp") . '' . $object->getLibProspCommStatut(4, $object->cacheprospectstatus[$object->stcomm_id]['label']); + print '     '; + print '
'; + foreach ($object->cacheprospectstatus as $key => $val) { + $titlealt = 'default'; + if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; + if ($object->stcomm_id != $val['id']) print '' . img_action($titlealt, $val['code'], $val['picto']) . ''; + } + print '
"; + print '
'; + } + } + print '
'; print '
'; diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 0fd80dbdac9..c475c1b439d 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -10,6 +10,7 @@ * Copyright (C) 2013 Juanjo Menent * Copyright (C) 2015 Marcos García * Copyright (C) 2019 Nicolas ZABOURI + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -89,6 +90,8 @@ class Contact extends CommonObject 'socialnetworks' =>array('type'=>'text', 'label'=>'SocialNetworks', 'enabled'=>1, 'visible'=>-1, 'position'=>115), 'photo' =>array('type'=>'varchar(255)', 'label'=>'Photo', 'enabled'=>1, 'visible'=>-1, 'position'=>170), 'priv' =>array('type'=>'smallint(6)', 'label'=>'Private', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>175), + 'fk_stcomm' =>array('type'=>'integer', 'label'=>'Fk stcommcontact', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>220), + 'fk_prospectlevel' =>array('type'=>'varchar(12)', 'label'=>'ProspectLevel', 'enabled'=>1, 'visible'=>-1, 'position'=>255), 'no_email' =>array('type'=>'smallint(6)', 'label'=>'No email', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>180), 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'position'=>185), 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'position'=>190), @@ -209,6 +212,11 @@ class Contact extends CommonObject public $roles = array(); + public $cacheprospectstatus = array(); + public $fk_prospectlevel; + public $stcomm_id; + public $statut_commercial; + public $stcomm_picto; /** * Constructor @@ -224,6 +232,10 @@ class Contact extends CommonObject if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid'])) $this->fields['rowid']['visible'] = 0; if (empty($conf->mailing->enabled)) $this->fields['no_email']['enabled'] = 0; if (!empty($conf->global->SOCIETE_DISABLE_CONTACTS)) $this->fields['thirdparty']['enabled'] = 0; + if (empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { // Default behaviour + $this->field['fk_stcomm']['enabled'] = 0; + $this->field['fk_prospectlevel']['enabled'] = 0; + } $this->statut = 1; // By default, status is enabled // Unset fields that are disabled @@ -328,6 +340,7 @@ class Contact extends CommonObject $sql .= ", firstname"; $sql .= ", fk_user_creat"; $sql .= ", priv"; + $sql.= ", fk_stcommcontact"; $sql .= ", statut"; $sql .= ", canvas"; $sql .= ", entity"; @@ -341,6 +354,7 @@ class Contact extends CommonObject $sql .= "'".$this->db->escape($this->firstname)."',"; $sql .= " ".($user->id > 0 ? "'".$this->db->escape($user->id)."'" : "null").","; $sql .= " ".$this->db->escape($this->priv).","; + $sql.= " 0,"; $sql .= " ".$this->db->escape($this->statut).","; $sql .= " ".(!empty($this->canvas) ? "'".$this->db->escape($this->canvas)."'" : "null").","; $sql .= " ".$this->db->escape($this->entity).","; @@ -465,6 +479,11 @@ class Contact extends CommonObject $sql .= ", phone_perso = ".(isset($this->phone_perso) ? "'".$this->db->escape($this->phone_perso)."'" : "null"); $sql .= ", phone_mobile = ".(isset($this->phone_mobile) ? "'".$this->db->escape($this->phone_mobile)."'" : "null"); $sql .= ", priv = '".$this->db->escape($this->priv)."'"; + $sql .= ", fk_prospectcontactlevel = '".$this->db->escape($this->fk_prospectlevel)."'"; + if (isset($this->stcomm_id)) + { + $sql .= ", fk_stcommcontact = ".($this->stcomm_id > 0 || $this->stcomm_id == -1 ? $this->stcomm_id : "0"); + } $sql .= ", statut = ".$this->db->escape($this->statut); $sql .= ", fk_user_modif=".($user->id > 0 ? "'".$this->db->escape($user->id)."'" : "NULL"); $sql .= ", default_lang=".($this->default_lang ? "'".$this->db->escape($this->default_lang)."'" : "NULL"); @@ -818,6 +837,7 @@ class Contact extends CommonObject $sql .= " c.socialnetworks,"; $sql .= " c.photo,"; $sql .= " c.priv, c.note_private, c.note_public, c.default_lang, c.canvas,"; + $sql.= " c.fk_prospectcontactlevel, c.fk_stcommcontact, st.libelle as stcomm, st.picto as stcomm_picto,"; $sql .= " c.import_key,"; $sql .= " c.datec as date_creation, c.tms as date_modification,"; $sql .= " co.label as country, co.code as country_code,"; @@ -829,6 +849,7 @@ class Contact extends CommonObject $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as d ON c.fk_departement = d.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON c.rowid = u.fk_socpeople"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON c.fk_soc = s.rowid"; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcommcontact as st ON c.fk_stcommcontact = st.id'; if ($id) $sql .= " WHERE c.rowid = ".$id; else { $sql .= " WHERE c.entity IN (".getEntity($this->element).")"; @@ -884,6 +905,14 @@ class Contact extends CommonObject $this->poste = $obj->poste; $this->statut = $obj->statut; + $this->fk_prospectlevel = $obj->fk_prospectcontactlevel; + + $transcode=$langs->trans('StatusProspect'.$obj->fk_stcommcontact); + $libelle=($transcode!='StatusProspect'.$obj->fk_stcommcontact?$transcode:$obj->stcomm); + $this->stcomm_id = $obj->fk_stcommcontact; // id statut commercial + $this->statut_commercial = $libelle; // libelle statut commercial + $this->stcomm_picto = $obj->stcomm_picto; // Picto statut commercial + $this->phone_pro = trim($obj->phone); $this->fax = trim($obj->fax); $this->phone_perso = trim($obj->phone_perso); @@ -1701,4 +1730,137 @@ class Contact extends CommonObject return $error * -1; } } + + /** + * Load array of prospect status + * + * @param int $active 1=Active only, 0=Not active only, -1=All + * @return int <0 if KO, >0 if OK + */ + public function loadCacheOfProspStatus($active = 1) + { + global $langs; + + $sql = "SELECT id, code, libelle as label, picto FROM " . MAIN_DB_PREFIX . "c_stcommcontact"; + if ($active >= 0) $sql .= " WHERE active = " . $active; + $resql = $this->db->query($sql); + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $this->cacheprospectstatus[$obj->id] = array('id' => $obj->id, 'code' => $obj->code, 'label' => ($langs->trans("ST_" . strtoupper($obj->code)) == "ST_" . strtoupper($obj->code)) ? $obj->label : $langs->trans("ST_" . strtoupper($obj->code)), 'picto' => $obj->picto); + $i++; + } + return 1; + } + + /** + * Return prostect level + * + * @return string Libelle + */ + public function getLibProspLevel() + { + return $this->libProspLevel($this->fk_prospectlevel); + } + + /** + * Return label of prospect level + * + * @param int $fk_prospectlevel Prospect level + * @return string label of level + */ + public function libProspLevel($fk_prospectlevel) + { + global $langs; + + $lib = $langs->trans("ProspectLevel" . $fk_prospectlevel); + // If lib not found in language file, we get label from cache/databse + if ($lib == $langs->trans("ProspectLevel" . $fk_prospectlevel)) + { + $lib = $langs->getLabelFromKey($this->db, $fk_prospectlevel, 'c_prospectlevel', 'code', 'label'); + } + return $lib; + } + + + /** + * Set prospect level + * + * @param User $user Utilisateur qui definie la remise + * @return int <0 if KO, >0 if OK + * @deprecated Use update function instead + */ + public function setProspectLevel(User $user) + { + return $this->update($this->id, $user); + } + + /** + * Return status of prospect + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long + * @param string $label Label to use for status for added status + * @return string Libelle + */ + public function getLibProspCommStatut($mode = 0, $label = '') + { + return $this->libProspCommStatut($this->stcomm_id, $mode, $label, $this->stcomm_picto); + } + + /** + * Return label of a given status + * + * @param int|string $statut Id or code for prospection status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto + * @param string $label Label to use for status for added status + * @param string $picto Name of image file to show ('filenew', ...) + * If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory. + * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img + * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img + * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) + * @return string Libelle du statut + */ + public function libProspCommStatut($statut, $mode = 0, $label = '', $picto = '') + { + global $langs; + $langs->load('customers'); + + if ($mode == 2) + { + if ($statut == '-1' || $statut == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1, $picto) . ' ' . $langs->trans("StatusProspect-1"); + elseif ($statut == '0' || $statut == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0, $picto) . ' ' . $langs->trans("StatusProspect0"); + elseif ($statut == '1' || $statut == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto) . ' ' . $langs->trans("StatusProspect1"); + elseif ($statut == '2' || $statut == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto) . ' ' . $langs->trans("StatusProspect2"); + elseif ($statut == '3' || $statut == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto) . ' ' . $langs->trans("StatusProspect3"); + else { + return img_action(($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label, 0, $picto) . ' ' . (($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label); + } + } + if ($mode == 3) + { + if ($statut == '-1' || $statut == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1, $picto); + elseif ($statut == '0' || $statut == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0, $picto); + elseif ($statut == '1' || $statut == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto); + elseif ($statut == '2' || $statut == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto); + elseif ($statut == '3' || $statut == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto); + else { + return img_action(($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label, 0, $picto); + } + } + if ($mode == 4) + { + if ($statut == '-1' || $statut == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1, $picto) . ' ' . $langs->trans("StatusProspect-1"); + elseif ($statut == '0' || $statut == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0, $picto) . ' ' . $langs->trans("StatusProspect0"); + elseif ($statut == '1' || $statut == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto) . ' ' . $langs->trans("StatusProspect1"); + elseif ($statut == '2' || $statut == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto) . ' ' . $langs->trans("StatusProspect2"); + elseif ($statut == '3' || $statut == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto) . ' ' . $langs->trans("StatusProspect3"); + else { + return img_action(($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label, 0, $picto) . ' ' . (($langs->trans("StatusProspect" . $statut) != "StatusProspect" . $statut) ? $langs->trans("StatusProspect" . $statut) : $label); + } + } + + return "Error, mode/status not found"; + } } diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 35a7c6a2209..7dad73cdb1c 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -11,6 +11,7 @@ * Copyright (C) 2018 Juanjo Menent * Copyright (C) 2019 Frédéric France * Copyright (C) 2019 Josep Lluís Amador + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,6 +92,8 @@ $search_town = GETPOST('search_town', 'alpha'); $search_import_key = GETPOST("search_import_key", "alpha"); $search_country = GETPOST("search_country", 'intcomma'); $search_roles = GETPOST("search_roles", 'array'); +$search_level = GETPOST("search_level", "array"); +$search_stcomm = GETPOST('search_stcomm', 'int'); if ($search_status == '') $search_status = 1; // always display active customer first @@ -141,7 +144,7 @@ $hookmanager->initHooks(array('contactlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contact'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); @@ -181,6 +184,11 @@ $arrayfields = array( 'p.statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000), 'p.import_key'=>array('label'=>"ImportId", 'checked'=>0, 'position'=>1100), ); +if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { + $arrayfields['p.fk_prospectcontactlevel'] = array('label'=>"ProspectLevelShort", 'checked'=>1, 'position'=>210); + $arrayfields['p.fk_stcommcontact'] = array('label'=>"StatusProsp", 'checked'=>1, 'position'=>215); +} + if (!empty($conf->socialnetworks->enabled)) { foreach ($socialnetworks as $key => $value) { if ($value['active']) { @@ -256,6 +264,8 @@ if (empty($reshook)) } } $search_priv = ""; + $search_stcomm=''; + $search_level=''; $search_status = -1; $search_categ = ''; $search_categ_thirdparty = ''; @@ -273,6 +283,17 @@ if (empty($reshook)) $permissiontodelete = $user->rights->societe->supprimer; $uploaddir = $conf->societe->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; + + if ($action == 'setstcomm') + { + $object = new Contact($db); + $result = $object->fetch(GETPOST('stcommcontactid')); + $object->stcomm_id = dol_getIdFromCode($db, GETPOST('stcomm', 'alpha'), 'c_stcommcontact'); + $result = $object->update($object->id, $user); + if ($result < 0) setEventMessages($object->error, $object->errors, 'errors'); + + $action = ''; + } } if ($search_priv < 0) $search_priv = ''; @@ -287,12 +308,36 @@ $formother = new FormOther($db); $formcompany = new FormCompany($db); $contactstatic = new Contact($db); +if (! empty($conf->global->THIRDPARTY_ENABLE_PROSPECTION_ON_ALTERNATIVE_ADRESSES)) { + $contactstatic->loadCacheOfProspStatus(); +} + $title = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("Contacts") : $langs->trans("ContactsAddresses")); +// Select every potentiels, and note each potentiels which fit in search parameters +$tab_level = array(); +$sql = "SELECT code, label, sortorder"; +$sql.= " FROM ".MAIN_DB_PREFIX."c_prospectcontactlevel"; +$sql.= " WHERE active > 0"; +$sql.= " ORDER BY sortorder"; +$resql = $db->query($sql); +if ($resql) +{ + while ($obj = $db->fetch_object($resql)) + { + // Compute level text + $level=$langs->trans($obj->code); + if ($level == $obj->code) $level=$langs->trans($obj->label); + $tab_level[$obj->code] = $level; + } +} +else dol_print_error($db); + $sql = "SELECT s.rowid as socid, s.nom as name,"; $sql .= " p.rowid, p.lastname as lastname, p.statut, p.firstname, p.zip, p.town, p.poste, p.email, p.no_email,"; $sql .= " p.socialnetworks, p.photo,"; $sql .= " p.phone as phone_pro, p.phone_mobile, p.phone_perso, p.fax, p.fk_pays, p.priv, p.datec as date_creation, p.tms as date_update,"; +$sql.= " st.libelle as stcomm, st.picto as stcomm_picto, p.fk_stcommcontact as stcomm_id, p.fk_prospectcontactlevel,"; $sql .= " co.label as country, co.code as country_code"; // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { @@ -306,6 +351,7 @@ $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p"; if (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 (p.rowid = ef.fk_object)"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = p.fk_pays"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc"; +$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_stcommcontact as st ON st.id = p.fk_stcommcontact"; if (!empty($search_categ)) $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_contact as cc ON p.rowid = cc.fk_socpeople"; // We need this table joined to the select in order to filter by categ if (!empty($search_categ_thirdparty)) $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_societe as cs ON s.rowid = cs.fk_soc"; // We need this table joined to the select in order to filter by categ if (!empty($search_categ_supplier)) $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_fournisseur as cs2 ON s.rowid = cs2.fk_soc"; // We need this table joined to the select in order to filter by categ @@ -319,6 +365,8 @@ if (!empty($userid)) // propre au commercial { $sql .= " AND p.fk_user_creat=".$db->escape($userid); } +if ($search_level) $sql .= natural_search("p.fk_prospectcontactlevel", join(',', $search_level), 3); +if ($search_stcomm != '' && $search_stcomm != -2) $sql .= natural_search("p.fk_stcommcontact", $search_stcomm, 2); // Filter to exclude not owned private contacts if ($search_priv != '0' && $search_priv != '1') @@ -461,8 +509,14 @@ if ($search_email != '') $param .= '&search_email='.urlencode($search_email) if ($search_no_email != '') $param .= '&search_no_email='.urlencode($search_no_email); if ($search_status != '') $param .= '&search_status='.urlencode($search_status); if ($search_priv == '0' || $search_priv == '1') $param .= "&search_priv=".urlencode($search_priv); +if ($search_stcomm != '') $param.='&search_stcomm='.urlencode($search_stcomm); +if (is_array($search_level) && count($search_level)) { + foreach ($search_level as $slevel) { + $param.='&search_level[]='.urlencode($slevel); + } +} if ($search_import_key != '') $param .= '&search_import_key='.urlencode($search_import_key); -if ($optioncss != '') $param .= '&optioncss='.$optioncss; +if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss); if (count($search_roles) > 0) $param .= implode('&search_roles[]=', $search_roles); // Add $param from extra fields @@ -678,6 +732,25 @@ if (!empty($arrayfields['p.priv']['checked'])) print $form->selectarray('search_priv', $selectarray, $search_priv, 1); print ''; } +// Prospect level +if (! empty($arrayfields['p.fk_prospectcontactlevel']['checked'])) +{ + print ''; + print $form->multiselectarray('search_level', $tab_level, $search_level, 0, 0, 'width75', 0, 0, '', '', '', 2); + print ''; +} +// Prospect status +if (! empty($arrayfields['p.fk_stcommcontact']['checked'])) +{ + print ''; + $arraystcomm=array(); + foreach ($contactstatic->cacheprospectstatus as $key => $val) + { + $arraystcomm[$val['id']]=($langs->trans("StatusProspect".$val['id']) != "StatusProspect".$val['id'] ? $langs->trans("StatusProspect".$val['id']) : $val['label']); + } + print $form->selectarray('search_stcomm', $arraystcomm, $search_stcomm, -2, 0, 0, '', 0, 0, 0, '', 'nowrap '); + print ''; +} // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; @@ -746,6 +819,8 @@ if (!empty($conf->socialnetworks->enabled)) { } if (!empty($arrayfields['p.thirdparty']['checked'])) print_liste_field_titre($arrayfields['p.thirdparty']['label'], $_SERVER["PHP_SELF"], "s.nom", $begin, $param, '', $sortfield, $sortorder); if (!empty($arrayfields['p.priv']['checked'])) print_liste_field_titre($arrayfields['p.priv']['label'], $_SERVER["PHP_SELF"], "p.priv", $begin, $param, '', $sortfield, $sortorder, 'center '); +if (!empty($arrayfields['p.fk_prospectcontactlevel']['checked'])) print_liste_field_titre($arrayfields['p.fk_prospectcontactlevel']['label'], $_SERVER["PHP_SELF"], "p.fk_prospectcontactlevel", "", $param, '', $sortfield, $sortorder, 'center '); +if (!empty($arrayfields['p.fk_stcommcontact']['checked'])) print_liste_field_titre($arrayfields['p.fk_stcommcontact']['label'], $_SERVER["PHP_SELF"], "p.fk_stcommcontact", "", $param, '', $sortfield, $sortorder, 'center '); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields @@ -796,6 +871,8 @@ while ($i < min($num, $limit)) $contactstatic->country_code = $obj->country_code; $contactstatic->photo = $obj->photo; + $contactstatic->fk_prospectlevel=$obj->fk_prospectcontactlevel; + print ''; // ID @@ -924,6 +1001,30 @@ while ($i < min($num, $limit)) if (!$i) $totalarray['nbfield']++; } + if (! empty($arrayfields['p.fk_prospectcontactlevel']['checked'])) + { + // Prospect level + print ''; + print $contactstatic->getLibProspLevel(); + print ""; + if (!$i) $totalarray['nbfield']++; + } + + if (! empty($arrayfields['p.fk_stcommcontact']['checked'])) + { + // Prospect status + print '
'; + print '
' . $contactstatic->libProspCommStatut($obj->stcomm_id, 2, $contactstatic->cacheprospectstatus[$obj->stcomm_id]['label'], $obj->stcomm_picto); + print '
-
'; + foreach ($contactstatic->cacheprospectstatus as $key => $val) { + $titlealt = 'default'; + if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; + if ($obj->stcomm_id != $val['id']) print '' . img_action($titlealt, $val['code'], $val['picto']) . ''; + } + print '
'; + if (!$i) $totalarray['nbfield']++; + } + // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 12ad603ea14..ab94e73b58c 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -2393,6 +2393,7 @@ class Contrat extends CommonObject global $conf, $langs; $langs->load("contracts"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'strato'; diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index 3627661c727..8afc2f0e335 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -100,7 +100,7 @@ $hookmanager->initHooks(array('contractlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contrat'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); // List of fields to search into when doing a "search in all" diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 18a5b561387..38aae136b39 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -84,7 +84,7 @@ $hookmanager->initHooks(array('contractservicelist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('contratdet'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php index 6f9144330e1..1114e33f6f6 100644 --- a/htdocs/core/actions_addupdatedelete.inc.php +++ b/htdocs/core/actions_addupdatedelete.inc.php @@ -156,7 +156,7 @@ if ($action == 'update' && !empty($permissiontoadd)) } elseif (preg_match('/^(integer|price|real|double)/', $object->fields[$key]['type'])) { $value = price2num(GETPOST($key, 'none')); // To fix decimal separator according to lang setup } elseif ($object->fields[$key]['type'] == 'boolean') { - $value = (GETPOST($key) == 'on' ? 1 : 0); + $value = ((GETPOST($key, 'aZ09') == 'on' || GETPOST($key, 'aZ09') == '1') ? 1 : 0); } else { $value = GETPOST($key, 'alpha'); } @@ -206,7 +206,7 @@ if ($action == "update_extras" && !empty($permissiontoadd)) $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'); + $object->array_options['options_'.$attributekey] = GETPOST($attributekeylong, 'alpha'); } $result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user); @@ -285,18 +285,20 @@ if ($action == 'confirm_validate' && $confirm == 'yes' && $permissiontoadd) // Define output language if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (!empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - $model = $object->modelpdf; - $ret = $object->fetch($id); // Reload to get new records + if (method_exists($object, 'generateDocument')) { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $model = $object->modelpdf; + $ret = $object->fetch($id); // Reload to get new records - $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + $object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref); + } } } else { setEventMessages($object->error, $object->errors, 'errors'); diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 9ec895926a0..48a2b503eca 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -268,6 +268,28 @@ class CMailFile } } + $this->addr_to = $to; + $this->addr_cc = $addr_cc; + $this->addr_bcc = $addr_bcc; + $this->reply_to = $replyto; + $this->addr_from = $from; + $this->subject = $subject; + $this->errors_to = $errors_to; + $this->deliveryreceipt = $deliveryreceipt; + $this->trackid = $trackid; + + if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) + { + $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; + $this->addr_cc = ''; + $this->addr_bcc = ''; + } + + // Add autocopy to (Note: Adding bcc for specific modules are also done from pages) + if (!empty($conf->global->MAIN_MAIL_AUTOCOPY_TO)) { + $addr_bcc.=($addr_bcc?', ':'').$conf->global->MAIN_MAIL_AUTOCOPY_TO; + } + // We set all data according to choosed sending method. // We also set a value for ->msgid if ($this->sendmode == 'mail') @@ -327,16 +349,16 @@ class CMailFile $smtps->setCharSet($conf->file->character_set_client); // Encode subject if required. - $subjecttouse = $subject; + $subjecttouse = $this->subject; if (!ascii_check($subjecttouse)) { $subjecttouse = $this->encodetorfc2822($subjecttouse); } $smtps->setSubject($subjecttouse); - $smtps->setTO($this->getValidAddress($to, 0, 1)); - $smtps->setFrom($this->getValidAddress($from, 0, 1)); - $smtps->setTrackId($trackid); - $smtps->setReplyTo($this->getValidAddress($replyto, 0, 1)); + $smtps->setTO($this->getValidAddress($this->to, 0, 1)); + $smtps->setFrom($this->getValidAddress($this->from, 0, 1)); + $smtps->setTrackId($this->trackid); + $smtps->setReplyTo($this->getValidAddress($this->replyto, 0, 1)); if (!empty($moreinheader)) $smtps->setMoreInHeader($moreinheader); @@ -374,17 +396,16 @@ class CMailFile } } - $smtps->setCC($addr_cc); - $smtps->setBCC($addr_bcc); - $smtps->setErrorsTo($errors_to); - $smtps->setDeliveryReceipt($deliveryreceipt); + $smtps->setCC($this->addr_cc); + $smtps->setBCC($this->addr_bcc); + $smtps->setErrorsTo($this->errors_to); + $smtps->setDeliveryReceipt($this->deliveryreceipt); $host = dol_getprefix('email'); $this->msgid = time().'.SMTPs-dolibarr-'.$trackid.'@'.$host; $this->smtps = $smtps; - } elseif ($this->sendmode == 'swiftmailer') - { + } elseif ($this->sendmode == 'swiftmailer') { // Use Swift Mailer library $host = dol_getprefix('email'); @@ -401,8 +422,8 @@ class CMailFile //$this->message = new Swift_SignedMessage(); // Adding a trackid header to a message $headers = $this->message->getHeaders(); - $headers->addTextHeader('X-Dolibarr-TRACKID', $trackid.'@'.$host); - $this->msgid = time().'.swiftmailer-dolibarr-'.$trackid.'@'.$host; + $headers->addTextHeader('X-Dolibarr-TRACKID', $this->trackid.'@'.$host); + $this->msgid = time().'.swiftmailer-dolibarr-'.$this->trackid.'@'.$host; $headerID = $this->msgid; $msgid = $headers->get('Message-ID'); $msgid->setId($headerID); @@ -411,14 +432,14 @@ class CMailFile // Give the message a subject try { - $result = $this->message->setSubject($subject); + $result = $this->message->setSubject($this->subject); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } // Set the From address with an associative array //$this->message->setFrom(array('john@doe.com' => 'John Doe')); - if (!empty($from)) { + if (! empty($this->addr_from)) { try { if (! empty($conf->global->MAIN_FORCE_DISABLE_MAIL_SPOOFING)) { // Prevent email spoofing for smtp server with a strict configuration @@ -429,10 +450,10 @@ class CMailFile { $result = $this->message->setFrom($conf->global->MAIN_MAIL_SMTPS_ID); } else { - $result = $this->message->setFrom($this->getArrayAddress($from)); + $result = $this->message->setFrom($this->getArrayAddress($this->addr_from)); } } else { - $result = $this->message->setFrom($this->getArrayAddress($from)); + $result = $this->message->setFrom($this->getArrayAddress($this->addr_from)); } } catch (Exception $e) { $this->errors[] = $e->getMessage(); @@ -440,17 +461,17 @@ class CMailFile } // Set the To addresses with an associative array - if (!empty($to)) { + if (! empty($this->addr_to)) { try { - $result = $this->message->setTo($this->getArrayAddress($to)); + $result = $this->message->setTo($this->getArrayAddress($this->addr_to)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } } - if (!empty($replyto)) { + if (! empty($this->reply_to)) { try { - $result = $this->message->SetReplyTo($this->getArrayAddress($replyto)); + $result = $this->message->SetReplyTo($this->getArrayAddress($this->reply_to)); } catch (Exception $e) { $this->errors[] = $e->getMessage(); } @@ -504,10 +525,10 @@ class CMailFile } } - if (!empty($addr_cc)) $this->message->setCc($this->getArrayAddress($addr_cc)); - if (!empty($addr_bcc)) $this->message->setBcc($this->getArrayAddress($addr_bcc)); + if (! empty($this->addr_cc)) $this->message->setCc($this->getArrayAddress($this->addr_cc)); + if (! empty($this->addr_bcc)) $this->message->setBcc($this->getArrayAddress($this->addr_bcc)); //if (! empty($errors_to)) $this->message->setErrorsTo($this->getArrayAddress($errors_to); - if (isset($deliveryreceipt) && $deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($from)); + if (isset($this->deliveryreceipt) && $this->deliveryreceipt == 1) $this->message->setReadReceiptTo($this->getArrayAddress($this->addr_from)); } else { // Send mail method not correctly defined // -------------------------------------- @@ -624,13 +645,6 @@ class CMailFile $keyforstarttls = 'MAIN_MAIL_EMAIL_STARTTLS_EMAILING'; } - if (!empty($conf->global->MAIN_MAIL_FORCE_SENDTO)) - { - $this->addr_to = $conf->global->MAIN_MAIL_FORCE_SENDTO; - $this->addr_cc = ''; - $this->addr_bcc = ''; - } - // Action according to choosed sending method if ($this->sendmode == 'mail') { diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 90694f6afb5..0d0a81a5192 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2847,12 +2847,14 @@ abstract class CommonObject dol_syslog(get_class($this)."::update_note Parameter suffix must be empty, '_private' or '_public'", LOG_ERR); return -2; } + + $newsuffix = $suffix; + // Special cas - //var_dump($this->table_element);exit; - if ($this->table_element == 'product') $suffix = ''; + if ($this->table_element == 'product' && $newsuffix == '_private') $newsuffix = ''; $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql .= " SET note".$suffix." = ".(!empty($note) ? ("'".$this->db->escape($note)."'") : "NULL"); + $sql .= " SET note".$newsuffix." = ".(!empty($note) ? ("'".$this->db->escape($note)."'") : "NULL"); $sql .= " ,".(in_array($this->table_element, array('actioncomm', 'adherent', 'advtargetemailing', 'cronjob', 'establishment')) ? "fk_user_mod" : "fk_user_modif")." = ".$user->id; $sql .= " WHERE rowid =".$this->id; @@ -5309,11 +5311,12 @@ abstract class CommonObject $new_array_options[$key] = null; } break; - case 'double': + case 'price': + case 'double': $value = price2num($value); if (!is_numeric($value) && $value != '') { - dol_syslog($langs->trans("ExtraFieldHasWrongValue")." sur ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); + dol_syslog($langs->trans("ExtraFieldHasWrongValue")." for ".$attributeLabel."(".$value."is not '".$attributeType."')", LOG_DEBUG); $this->errors[] = $langs->trans("ExtraFieldHasWrongValue", $attributeLabel); return -1; } elseif ($value == '') @@ -5361,9 +5364,6 @@ abstract class CommonObject $new_array_options[$key] = $this->array_options[$key]; } break; - case 'price': - $new_array_options[$key] = price2num($this->array_options[$key]); - break; case 'date': case 'datetime': // If data is a string instead of a timestamp, we convert it @@ -5455,7 +5455,7 @@ abstract class CommonObject { if (!isset($extrafields->attributes[$this->table_element]['type'][$tmpkey])) // If field not already added previously { - if (in_array($tmpval, array('int', 'double'))) $sql .= ", 0"; + if (in_array($tmpval, array('int', 'double', 'price'))) $sql .= ", 0"; else $sql .= ", ''"; } } @@ -6731,7 +6731,7 @@ abstract class CommonObject if (is_array($extrafields->attributes[$this->table_element]['label']) && count($extrafields->attributes[$this->table_element]['label']) > 0) { $out .= "\n"; - $out .= ' '; + $out .= ' '; $out .= "\n"; $extrafields_collapse_num = ''; @@ -6865,7 +6865,7 @@ abstract class CommonObject // HTML, select, integer and text add default value if (in_array($extrafields->attributes[$this->table_element]['type'][$key], array('html', 'text', 'select', 'int'))) { - if ($action == 'create') $value = $extrafields->attributes[$this->table_element]['default'][$key]; + if ($action == 'create') $value = GETPOSTISSET($keyprefix.'options_'.$key.$keysuffix) ? GETPOST($keyprefix.'options_'.$key.$keysuffix, 'none', 3) : $extrafields->attributes[$this->table_element]['default'][$key]; else $value = $this->array_options['options_'.$key]; } @@ -6951,7 +6951,7 @@ abstract class CommonObject '."\n"; } - $out .= ' '."\n"; + $out .= ' '."\n"; } } @@ -7618,11 +7618,11 @@ abstract class CommonObject if (array_key_exists('ref', $fieldvalues)) $fieldvalues['ref'] = dol_string_nospecial($fieldvalues['ref']); // If field is a ref, we sanitize data $keys = array(); - $values = array(); + $values = array(); // Array to store string forged for SQL syntax foreach ($fieldvalues as $k => $v) { $keys[$k] = $k; $value = $this->fields[$k]; - $values[$k] = $this->quote($v, $value); + $values[$k] = $this->quote($v, $value); // May return string 'NULL' if $value is null } // Clean and check mandatory @@ -7632,8 +7632,7 @@ abstract class CommonObject if (preg_match('/^integer:/i', $this->fields[$key]['type']) && $values[$key] == '-1') $values[$key] = ''; if (!empty($this->fields[$key]['foreignkey']) && $values[$key] == '-1') $values[$key] = ''; - //var_dump($key.'-'.$values[$key].'-'.($this->fields[$key]['notnull'] == 1)); - if (isset($this->fields[$key]['notnull']) && $this->fields[$key]['notnull'] == 1 && !isset($values[$key]) && is_null($this->fields[$key]['default'])) + if (isset($this->fields[$key]['notnull']) && $this->fields[$key]['notnull'] == 1 && (!isset($values[$key]) || $values[$key] === 'NULL') && is_null($this->fields[$key]['default'])) { $error++; $this->errors[] = $langs->trans("ErrorFieldRequired", $this->fields[$key]['label']); diff --git a/htdocs/core/class/commonobjectline.class.php b/htdocs/core/class/commonobjectline.class.php index f92004120ff..148c9baa67e 100644 --- a/htdocs/core/class/commonobjectline.class.php +++ b/htdocs/core/class/commonobjectline.class.php @@ -50,6 +50,16 @@ abstract class CommonObjectLine extends CommonObject public $fk_unit; + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + $this->db = $db; + } + /** * Returns the translation key from units dictionary. * A langs->trans() must be called on result to get translated value. @@ -74,12 +84,12 @@ abstract class CommonObjectLine extends CommonObject $label_type = 'short_label'; } - $sql = 'select '.$label_type.' from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; + $sql = 'select '.$label_type.',code from '.MAIN_DB_PREFIX.'c_units where rowid='.$this->fk_unit; $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { $res = $this->db->fetch_array($resql); - $label = $res[$label_type]; + $label = ($label_type == 'short' ? $res[$label_type] : 'unit'.$res['code']); $this->db->free($resql); return $label; } else { diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index f54b25731d8..3234b1900f2 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -467,6 +467,26 @@ class dolReceiptPrinter extends Printer return $error; } + /** + * Function to delete a printer template in db + * + * @param int $templateid Template ID + * @return int 0 if OK; >0 if KO + */ + public function deleteTemplate($templateid) + { + global $conf; + $error = 0; + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'printer_receipt_template'; + $sql .= " WHERE rowid = ".((int) $this->db->escape($templateid)); + $sql .= " AND entity = ".$conf->entity; + $resql = $this->db->query($sql); + if (!$resql) { + $error++; + $this->errors[] = $this->db->lasterror; + } + return $error; + } /** * Function to Update a printer template in db diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 3189485ff6c..b2f8905aba9 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -154,8 +154,8 @@ class ExtraFields public static $type2label = array( - 'varchar'=>'String', - 'text'=>'TextLong', + 'varchar'=>'String1Line', + 'text'=>'TextLongNLines', 'html'=>'HtmlText', 'int'=>'Int', 'double'=>'Float', @@ -807,7 +807,7 @@ class ExtraFields /** * Load array this->attributes, or old this->attribute_xxx like attribute_label, attribute_type, ... * - * @param string $elementtype Type of element ('' = all, 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). + * @param string $elementtype Type of element ('' = all or $object->table_element like 'adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...). * @param boolean $forceload Force load of extra fields whatever is status of cache. * @return array Array of attributes keys+label for all extra fields. */ @@ -821,6 +821,7 @@ class ExtraFields if ($elementtype == 'thirdparty') $elementtype = 'societe'; if ($elementtype == 'contact') $elementtype = 'socpeople'; if ($elementtype == 'order_supplier') $elementtype = 'commande_fournisseur'; + if ($elementtype == 'stock_mouvement') $elementtype = 'movement'; $array_name_label = array(); @@ -2025,6 +2026,8 @@ class ExtraFields $value_key = price2num($value_arr); } elseif (in_array($key_type, array('html'))) { $value_key = GETPOST("options_".$key, 'alpha'); + } elseif (in_array($key_type, array('text'))) { + $value_key = GETPOST("options_".$key, 'alphanohtml'); } else { $value_key = GETPOST("options_".$key); if (in_array($key_type, array('link')) && $value_key == '-1') $value_key = ''; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 2e0bc37069e..41d696d49aa 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2641,9 +2641,9 @@ class Form $outval .= ' - '.$langs->transnoentities("VirtualStock").':'; if ($virtualstock > 0) { - $outval .= ' - '; + $outval .= ''; } elseif ($virtualstock <= 0) { - $outval .= ' - '; + $outval .= ''; } $outval .= $virtualstock; $outval .= ''; diff --git a/htdocs/core/class/html.formcompany.class.php b/htdocs/core/class/html.formcompany.class.php index 6969066629c..8a4346ab7d8 100644 --- a/htdocs/core/class/html.formcompany.class.php +++ b/htdocs/core/class/html.formcompany.class.php @@ -3,6 +3,7 @@ * Copyright (C) 2008-2012 Regis Houssin * Copyright (C) 2014 Juanjo Menent * Copyright (C) 2017 Rui Strecht + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -172,6 +173,58 @@ class FormCompany extends Form print ''; } + /** + * Affiche formulaire de selection des niveau de prospection pour les contacts + * + * @param int $page Page + * @param int $selected Id or code preselected + * @param string $htmlname Nom du formulaire select + * @param int $empty Add empty value in list + * @return void + */ + public function formProspectContactLevel($page, $selected = '', $htmlname = 'prospect_contact_level_id', $empty = 0) + { + global $user, $langs; + + print '
'; + print ''; + print ''; + + dol_syslog(__METHOD__, LOG_DEBUG); + $sql = "SELECT code, label"; + $sql .= " FROM " . MAIN_DB_PREFIX . "c_prospectcontactlevel"; + $sql .= " WHERE active > 0"; + $sql .= " ORDER BY sortorder"; + $resql = $this->db->query($sql); + if ($resql) + { + $options = array(); + + if ($empty) + { + $options[''] = ''; + } + + while ($obj = $this->db->fetch_object($resql)) + { + $level = $langs->trans($obj->code); + + if ($level == $obj->code) + { + $level = $langs->trans($obj->label); + } + + $options[$obj->code] = $level; + } + + print Form::selectarray($htmlname, $options, $selected); + } + else dol_print_error($this->db); + if (!empty($htmlname) && $user->admin) print ' ' . info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); + print ''; + print '
'; + } + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Returns the drop-down list of departments/provinces/cantons for all countries or for a given country. diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index c37a7cfc6ab..549c82a9033 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -539,7 +539,10 @@ class Translate { global $conf, $db; - if (!is_string($key)) return 'ErrorBadValueForParamNotAString'; // Avoid multiple errors with code not using function correctly. + if (!is_string($key)) { + //xdebug_print_function_stack('ErrorBadValueForParamNotAString'); + return 'ErrorBadValueForParamNotAString'; // Avoid multiple errors with code not using function correctly. + } $newstr = $key; if (preg_match('/^Civility([0-9A-Z]+)$/i', $key, $reg)) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 1cf166c4d19..00a8ea821e2 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -15,6 +15,7 @@ * Copyright (C) 2015 Jean-François Ferry * Copyright (C) 2018-2020 Frédéric France * Copyright (C) 2019 Thibault Foucart + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -591,7 +592,7 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null // '"' is dangerous because param in url can close the href= or src= and add javascript functions. // '../' is dangerous because it allows dir transversals $out = str_replace(array('"', '../'), '', trim($out)); - $out = dol_string_nohtmltag($out, 1); + $out = dol_string_nohtmltag($out, 0); } break; case 'restricthtml': // Recommended for most html textarea @@ -3012,7 +3013,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ '1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected', 'accountancy', 'address', 'bank_account', 'barcode', 'bank', 'bill', 'bookmark', 'bom', 'building', 'cash-register', 'category', 'check', 'clock', 'close_title', 'company', 'contact', 'contract', 'cubes', - 'delete', 'dolly', 'dollyrevert', 'edit', 'ellipsis-h', 'external-link-alt', 'external-link-square-alt', + 'delete', 'dolly', 'dollyrevert', 'edit', 'ellipsis-h', 'email', 'external-link-alt', 'external-link-square-alt', 'filter', 'file-code', 'file-export', 'file-import', 'file-upload', 'folder', 'folder-open', 'globe', 'globe-americas', 'grip', 'grip_title', 'help', 'intervention', 'label', 'language', 'list', 'listlight', 'lot', 'map-marker-alt', 'money-bill-alt', 'mrp', 'note', @@ -3306,9 +3307,14 @@ function img_picto_common($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0 * * @param string $titlealt Text on alt and title of image. Alt only if param notitle is set to 1. If text is "TextA:TextB", use Text A on alt and Text B on title. * @param string $numaction Action id or code to show + * @param string $picto Name of image file to show ('filenew', ...) + * If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory. + * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img + * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img + * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) * @return string Return an img tag */ -function img_action($titlealt, $numaction) +function img_action($titlealt, $numaction, $picto = '') { global $langs; @@ -3336,7 +3342,7 @@ function img_action($titlealt, $numaction) } if (!is_numeric($numaction)) $numaction = 0; - return img_picto($titlealt, 'stcomm'.$numaction.'.png'); + return img_picto($titlealt, !empty($picto) ? $picto : 'stcomm'.$numaction.'.png'); } /** @@ -5465,7 +5471,7 @@ function picto_required() * @param integer $strip_tags 0=Use internal strip, 1=Use strip_tags() php function (bugged when text contains a < char that is not for a html tag) * @return string String cleaned * - * @see dol_escape_htmltag() strip_tags() dol_string_onlythesehtmltags() dol_string_neverthesehtmltags() + * @see dol_escape_htmltag() strip_tags() dol_string_onlythesehtmltags() dol_string_neverthesehtmltags(), dolStripPhpCode() */ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto = 'UTF-8', $strip_tags = 0) { @@ -5501,12 +5507,13 @@ function dol_string_nohtmltag($stringtoclean, $removelinefeed = 1, $pagecodeto = * Clean a string to keep only desirable HTML tags. * * @param string $stringtoclean String to clean - * @param string $cleanalsosomestyles Clean also some tags + * @param boolean $cleanalsosomestyles Remove absolute/fixed positioning from inline styles + * @param boolean $removeclassattribute Remove the class attribute from tags * @return string String cleaned * * @see dol_escape_htmltag() strip_tags() dol_string_nohtmltag() dol_string_neverthesehtmltags() */ -function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1) +function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1, $removeclassattribute = 1) { $allowed_tags = array( "html", "head", "meta", "body", "article", "a", "abbr", "b", "blockquote", "br", "cite", "div", "dl", "dd", "dt", "em", "font", "img", "ins", "hr", "i", "li", "link", @@ -5518,7 +5525,10 @@ function dol_string_onlythesehtmltags($stringtoclean, $cleanalsosomestyles = 1) $allowed_tags_string = '<'.$allowed_tags_string.'>'; if ($cleanalsosomestyles) { - $stringtoclean = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/', '', $stringtoclean); // Note: If hacker try to introduce css comment into string to bypass this regex, the string must also be encoded by the dol_htmlentitiesbr during output so it become harmless + $stringtoclean = preg_replace('/position\s*:\s*(absolute|fixed)\s*!\s*important/i', '', $stringtoclean); // Note: If hacker try to introduce css comment into string to bypass this regex, the string must also be encoded by the dol_htmlentitiesbr during output so it become harmless + } + if ($removeclassattribute) { + $stringtoclean = preg_replace('/(<[^>]+)\s+class=((["\']).*?\\3|\\w*)/i', '\\1', $stringtoclean); } $temp = strip_tags($stringtoclean, $allowed_tags_string); @@ -8215,14 +8225,13 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st } // TODO : add a hook - if ($displayMode == 0) { - $return = !empty($html) ? $html : $statusLabel; + $return = !empty($html) ? $html : (empty($conf->dol_optimize_smallscreen) ? $statusLabel : (empty($statusLabelShort) ? $statusLabel : $statusLabelShort)); } elseif ($displayMode == 1) { - $return = !empty($html) ? $html : (!empty($statusLabelShort) ? $statusLabelShort : $statusLabel); + $return = !empty($html) ? $html : (empty($statusLabelShort) ? $statusLabel : $statusLabelShort); } // Use status with images (for backward compatibility) elseif (!empty($conf->global->MAIN_STATUS_USES_IMAGES)) { - $return = ''; + $return = ''; $htmlLabel = (in_array($displayMode, array(1, 2, 5)) ? '' : '').(!empty($html) ? $html : $statusLabel).(in_array($displayMode, array(1, 2, 5)) ? '' : ''); $htmlLabelShort = (in_array($displayMode, array(1, 2, 5)) ? '' : '').(!empty($html) ? $html : (!empty($statusLabelShort) ? $statusLabelShort : $statusLabel)).(in_array($displayMode, array(1, 2, 5)) ? '' : ''); @@ -8267,17 +8276,17 @@ function dolGetStatus($statusLabel = '', $statusLabelShort = '', $html = '', $st } } // Use new badge elseif (empty($conf->global->MAIN_STATUS_USES_IMAGES) && !empty($displayMode)) { - $statusLabelShort = !empty($statusLabelShort) ? $statusLabelShort : $statusLabel; + $statusLabelShort = (empty($statusLabelShort) ? $statusLabel : $statusLabelShort); $dolGetBadgeParams['attr']['class'] = 'badge-status'; $dolGetBadgeParams['attr']['title'] = $statusLabel; if ($displayMode == 3) { - $return = dolGetBadge($statusLabel, '', $statusType, 'dot', $url, $dolGetBadgeParams); + $return = dolGetBadge((empty($conf->dol_optimize_smallscreen) ? $statusLabel : (empty($statusLabelShort) ? $statusLabel : $statusLabelShort)), '', $statusType, 'dot', $url, $dolGetBadgeParams); } elseif ($displayMode === 5) { $return = dolGetBadge($statusLabelShort, $html, $statusType, '', $url, $dolGetBadgeParams); } else { - $return = dolGetBadge($statusLabel, $html, $statusType, '', $url, $dolGetBadgeParams); + $return = dolGetBadge((empty($conf->dol_optimize_smallscreen) ? $statusLabel : (empty($statusLabelShort) ? $statusLabel : $statusLabelShort)), $html, $statusType, '', $url, $dolGetBadgeParams); } } diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 04c60bbc8e4..36d0fb0c80d 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -24,23 +24,23 @@ /** - * Function to return number in text. + * Function to return a number into a text. * May use module NUMBERWORDS if found. * - * @param float $num Number to convert + * @param float $num Number to convert (must be a numeric value, like reported by price2num()) * @param Translate $langs Language * @param boolean $currency 0=number to translate | 1=currency to translate - * @param boolean $centimes 0=no centimes | 1=centimes to translate + * @param boolean $centimes 0=no cents/centimes | 1=there is cents/centimes to translate * @return string|false Text of the number */ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) { global $conf; - $num = str_replace(array(',', ' '), '', trim($num)); - if (!$num) { - return false; - } + //$num = str_replace(array(',', ' '), '', trim($num)); This should be useless since $num MUST be a php numeric value + if (!$num) { + return false; + } if ($centimes && strlen($num) == 1) { $num = $num * 10; @@ -57,78 +57,79 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) return $concatWords; } else { $TNum = explode('.', $num); - $num = (int) $TNum[0]; - $words = array(); - $list1 = array( - '', - $langs->transnoentitiesnoconv('one'), - $langs->transnoentitiesnoconv('two'), - $langs->transnoentitiesnoconv('three'), - $langs->transnoentitiesnoconv('four'), - $langs->transnoentitiesnoconv('five'), - $langs->transnoentitiesnoconv('six'), - $langs->transnoentitiesnoconv('seven'), - $langs->transnoentitiesnoconv('eight'), - $langs->transnoentitiesnoconv('nine'), - $langs->transnoentitiesnoconv('ten'), - $langs->transnoentitiesnoconv('eleven'), - $langs->transnoentitiesnoconv('twelve'), - $langs->transnoentitiesnoconv('thirteen'), - $langs->transnoentitiesnoconv('fourteen'), - $langs->transnoentitiesnoconv('fifteen'), - $langs->transnoentitiesnoconv('sixteen'), - $langs->transnoentitiesnoconv('seventeen'), - $langs->transnoentitiesnoconv('eighteen'), - $langs->transnoentitiesnoconv('nineteen') - ); - $list2 = array( - '', - $langs->transnoentitiesnoconv('ten'), - $langs->transnoentitiesnoconv('twenty'), - $langs->transnoentitiesnoconv('thirty'), - $langs->transnoentitiesnoconv('forty'), - $langs->transnoentitiesnoconv('fifty'), - $langs->transnoentitiesnoconv('sixty'), - $langs->transnoentitiesnoconv('seventy'), - $langs->transnoentitiesnoconv('eighty'), - $langs->transnoentitiesnoconv('ninety'), - $langs->transnoentitiesnoconv('hundred') - ); - $list3 = array( - '', - $langs->transnoentitiesnoconv('thousand'), - $langs->transnoentitiesnoconv('million'), - $langs->transnoentitiesnoconv('billion'), - $langs->transnoentitiesnoconv('trillion'), - $langs->transnoentitiesnoconv('quadrillion') - ); - $num_length = strlen($num); - $levels = (int) (($num_length + 2) / 3); - $max_length = $levels * 3; - $num = substr('00'.$num, -$max_length); - $num_levels = str_split($num, 3); - $nboflevels = count($num_levels); - for ($i = 0; $i < $nboflevels; $i++) { - $levels--; - $hundreds = (int) ($num_levels[$i] / 100); - $hundreds = ($hundreds ? ' '.$list1[$hundreds].' '.$langs->transnoentities('hundred').($hundreds == 1 ? '' : 's').' ' : ''); - $tens = (int) ($num_levels[$i] % 100); - $singles = ''; - if ($tens < 20) { - $tens = ($tens ? ' '.$list1[$tens].' ' : ''); - } else { - $tens = (int) ($tens / 10); - $tens = ' '.$list2[$tens].' '; - $singles = (int) ($num_levels[$i] % 10); - $singles = ' '.$list1[$singles].' '; - } - $words[] = $hundreds.$tens.$singles.(($levels && (int) ($num_levels[$i])) ? ' '.$list3[$levels].' ' : ''); - } //end for loop - $commas = count($words); - if ($commas > 1) { - $commas = $commas - 1; - } + $num = (int) $TNum[0]; + $words = array(); + $list1 = array( + '', + $langs->transnoentitiesnoconv('one'), + $langs->transnoentitiesnoconv('two'), + $langs->transnoentitiesnoconv('three'), + $langs->transnoentitiesnoconv('four'), + $langs->transnoentitiesnoconv('five'), + $langs->transnoentitiesnoconv('six'), + $langs->transnoentitiesnoconv('seven'), + $langs->transnoentitiesnoconv('eight'), + $langs->transnoentitiesnoconv('nine'), + $langs->transnoentitiesnoconv('ten'), + $langs->transnoentitiesnoconv('eleven'), + $langs->transnoentitiesnoconv('twelve'), + $langs->transnoentitiesnoconv('thirteen'), + $langs->transnoentitiesnoconv('fourteen'), + $langs->transnoentitiesnoconv('fifteen'), + $langs->transnoentitiesnoconv('sixteen'), + $langs->transnoentitiesnoconv('seventeen'), + $langs->transnoentitiesnoconv('eighteen'), + $langs->transnoentitiesnoconv('nineteen') + ); + $list2 = array( + '', + $langs->transnoentitiesnoconv('ten'), + $langs->transnoentitiesnoconv('twenty'), + $langs->transnoentitiesnoconv('thirty'), + $langs->transnoentitiesnoconv('forty'), + $langs->transnoentitiesnoconv('fifty'), + $langs->transnoentitiesnoconv('sixty'), + $langs->transnoentitiesnoconv('seventy'), + $langs->transnoentitiesnoconv('eighty'), + $langs->transnoentitiesnoconv('ninety'), + $langs->transnoentitiesnoconv('hundred') + ); + $list3 = array( + '', + $langs->transnoentitiesnoconv('thousand'), + $langs->transnoentitiesnoconv('million'), + $langs->transnoentitiesnoconv('billion'), + $langs->transnoentitiesnoconv('trillion'), + $langs->transnoentitiesnoconv('quadrillion') + ); + + $num_length = strlen($num); + $levels = (int) (($num_length + 2) / 3); + $max_length = $levels * 3; + $num = substr('00'.$num, -$max_length); + $num_levels = str_split($num, 3); + $nboflevels = count($num_levels); + for ($i = 0; $i < $nboflevels; $i++) { + $levels--; + $hundreds = (int) ($num_levels[$i] / 100); + $hundreds = ($hundreds ? ' '.$list1[$hundreds].' '.$langs->transnoentities('hundred').($hundreds == 1 ? '' : 's').' ' : ''); + $tens = (int) ($num_levels[$i] % 100); + $singles = ''; + if ($tens < 20) { + $tens = ($tens ? ' '.$list1[$tens].' ' : ''); + } else { + $tens = (int) ($tens / 10); + $tens = ' '.$list2[$tens].' '; + $singles = (int) ($num_levels[$i] % 10); + $singles = ' '.$list1[$singles].' '; + } + $words[] = $hundreds.$tens.$singles.(($levels && (int) ($num_levels[$i])) ? ' '.$list3[$levels].' ' : ''); + } //end for loop + $commas = count($words); + if ($commas > 1) { + $commas = $commas - 1; + } $concatWords = implode(' ', $words); // Delete multi whitespaces $concatWords = trim(preg_replace('/[ ]+/', ' ', $concatWords)); @@ -138,12 +139,16 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) } // If we need to write cents call again this function for cents - if (!empty($TNum[1])) { + $decimalpart = $TNum[1]; + $decimalpart = preg_replace('/0+$/', '', $decimalpart); + + if ($decimalpart) { if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('and'); - $concatWords .= ' '.dol_convertToWord($TNum[1], $langs, $currency, true); + + $concatWords .= ' '.dol_convertToWord($decimalpart, $langs, '', true); if (!empty($currency)) $concatWords .= ' '.$langs->transnoentities('centimes'); } - return $concatWords; + return $concatWords; } } @@ -159,10 +164,12 @@ function dol_convertToWord($num, $langs, $currency = false, $centimes = false) */ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') { - // If the number is negative convert to positive and return -1 if is too long + // If the number is negative convert to positive and return -1 if it is too long if ($numero < 0) $numero *= -1; - if ($numero >= 1000000000001) + if ($numero >= 1000000000001) { return -1; + } + // Get 2 decimals to cents, another functions round or truncate $strnumber = number_format($numero, 10); $len = strlen($strnumber); diff --git a/htdocs/core/lib/images.lib.php b/htdocs/core/lib/images.lib.php index 80bbeed9d4a..4cca58d5c2a 100644 --- a/htdocs/core/lib/images.lib.php +++ b/htdocs/core/lib/images.lib.php @@ -33,11 +33,17 @@ $quality = 80; * Return if a filename is file name of a supported image format * * @param string $file Filename + * @param int $acceptsvg 0=Default (depends on setup), 1=Always accept SVG as image files * @return int -1=Not image filename, 0=Image filename but format not supported for conversion by PHP, 1=Image filename with format supported by this PHP */ -function image_format_supported($file) +function image_format_supported($file, $acceptsvg = 0) { - $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm|\.svg'; // See also into product.class.php + global $conf; + + $regeximgext = '\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm'; // See also into product.class.php + if ($acceptsvg || ! empty($conf->global->MAIN_ALLOW_SVG_FILES_AS_IMAGES)) { + $regeximgext .= '|\.svg'; // Not allowed by default. SVG can contains javascript + } // Case filename is not a format image $reg = array(); diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index 3232bae291a..ff14ec56e18 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -207,11 +207,12 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = * @param string $objectname Name of object * @param string $newmask New mask * @param string $readdir Directory source (use $destdir when not defined) - * @param Object $object If object was already loaded/known, it is pass to avaoid another include and new. + * @param Object $object If object was already loaded/known, it is pass to avoid another include and new. + * @param string $moduletype 'external' or 'internal' * @return int <=0 if KO, >0 if OK * @see rebuildObjectClass() */ -function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null) +function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external') { global $db, $langs; @@ -223,8 +224,14 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = ' $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php'; // Edit .sql file - $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; - $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + if ($moduletype == 'internal') { + $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; + $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + } else { + $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; + $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); + } + if (!dol_is_file($pathoffiletoeditsrc)) { $langs->load("errors"); @@ -293,8 +300,13 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = ' } // Edit .key.sql file - $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; - $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + if ($moduletype == 'internal') { + $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; + $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + } else { + $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; + $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); + } $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r'); diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 3113d8a3e65..cfcdd015f1d 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -234,12 +234,14 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = !empty($conf->ficheinter->enabled) ) ? 1 : 0, 'perms'=>(!empty($user->rights->propal->lire) || - !empty($user->rights->commande->lire) || - !empty($user->rights->fournisseur->lire) || - !empty($user->rights->supplier_proposal->lire) || - !empty($user->rights->supplier_order->lire) || - !empty($user->rights->contrat->lire) || - !empty($user->rights->ficheinter->lire) + !empty($user->rights->commande->lire) || + !empty($user->rights->fournisseur->lire) || + !empty($user->rights->supplier_proposal->lire) || + !empty($user->rights->supplier_order->lire) || + !empty($user->rights->contrat->lire) || + !empty($user->rights->ficheinter->lire) || + !empty($user->rights->supplier_order->lire) || + !empty($user->rights->fournisseur->commande->lire) ), 'module'=>'propal|commande|supplier_proposal|supplier_order|contrat|ficheinter' ); diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 273947ec205..764519862a6 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -2217,10 +2217,16 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i', '', get_class($this))); + $version = $this->getVersion(0); + $versiontrans = ''; + if (preg_match('/development/i', $version)) $versiontrans .= 'warning'; + if (preg_match('/experimental/i', $version)) $versiontrans .= 'warning'; + if (preg_match('/deprecated/i', $version)) $versiontrans .= 'warning'; + print '
-
'; +
'; $alttext = ''; //if (is_array($objMod->need_dolibarr_version)) $alttext.=($alttext?' - ':'').'Dolibarr >= '.join('.',$objMod->need_dolibarr_version); @@ -2233,39 +2239,19 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it print img_object($alttext, 'generic', 'class="inline-block valignmiddle"'); } - $version = $this->getVersion(0); - $versiontrans = ''; - if (preg_match('/development/i', $version)) $versiontrans .= 'warning'; - if (preg_match('/experimental/i', $version)) $versiontrans .= 'warning'; - if (preg_match('/deprecated/i', $version)) $versiontrans .= 'warning'; if ($this->isCoreOrExternalModule() == 'external' || preg_match('/development|experimental|deprecated/i', $version)) { print 'getVersion(1).'">'; print $this->getVersion(1); print ''; } - /*print ''; - print '
'; - print '
'; - print $codeenabledisable; - print '
'; - print '
'; - print $codetoconfig; - print '
'; - print '
'; - print '
'; - */ - print '
-
+
'.$this->getName().' '.nl2br($this->getDesc()).''; - /*print 'getVersion(1).'">'; - print $this->getVersion(1); - print ''; */ - print '
'; + //if ($versiontrans) print img_warning($langs->trans("Version").' '.$this->getVersion(1)).' '; print ''.img_picto(($this->isCoreOrExternalModule() == 'external' ? $langs->trans("ExternalModule").' - ' : '').$langs->trans("ClickToShowDescription"), $imginfo).''; print '

'; diff --git a/htdocs/core/modules/bank/doc/pdf_ban.modules.php b/htdocs/core/modules/bank/doc/pdf_ban.modules.php index 3aa46add2ac..51dea857f61 100644 --- a/htdocs/core/modules/bank/doc/pdf_ban.modules.php +++ b/htdocs/core/modules/bank/doc/pdf_ban.modules.php @@ -292,7 +292,7 @@ class pdf_ban extends ModeleBankAccountDoc /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Project $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -377,7 +377,7 @@ class pdf_ban extends ModeleBankAccountDoc /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Project $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text diff --git a/htdocs/core/modules/cheque/doc/pdf_blochet.class.php b/htdocs/core/modules/cheque/doc/pdf_blochet.class.php index ec6f52dfec7..264c32e4234 100644 --- a/htdocs/core/modules/cheque/doc/pdf_blochet.class.php +++ b/htdocs/core/modules/cheque/doc/pdf_blochet.class.php @@ -213,7 +213,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Generate Header * - * @param PDF $pdf Pdf object + * @param TCPDF $pdf Pdf object * @param int $page Current page number * @param int $pages Total number of pages * @param Translate $outputlangs Object language for output @@ -321,7 +321,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Output array * - * @param PDF $pdf PDF object + * @param TCPDF $pdf PDF object * @param int $pagenb Page nb * @param int $pages Pages * @param Translate $outputlangs Object lang @@ -390,7 +390,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text diff --git a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php index 5fbec0b2c68..bf54298d264 100644 --- a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php @@ -438,7 +438,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -480,7 +480,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text @@ -509,7 +509,7 @@ class pdf_merou extends ModelePdfExpedition /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index dc29b6411f5..391b8d0e3bf 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -662,7 +662,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Montant deja regle * @param int $posy Position depart @@ -769,7 +769,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y @@ -857,7 +857,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1100,7 +1100,7 @@ class pdf_rouget extends ModelePdfExpedition /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text diff --git a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php index 6d3bc5e8e65..3c0ae6890e3 100644 --- a/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/expensereport/doc/pdf_standard.modules.php @@ -381,7 +381,7 @@ class pdf_standard extends ModeleExpenseReport $pdf->setPage($pageposafter + 1); $showpricebeforepagebreak = 1; $nexY = $tab_top_newpage; - $nexY += ($pdf->getFontSize() * 1.3); // Passe espace entre les lignes + $nexY += ($pdf->getFontSize() * 1.3); // Add space between lines $pdf->SetFont('', '', $default_font_size - 2); // Into loop to work with multipage $pdf->SetTextColor(0, 0, 0); diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index cd2f711d23a..96cdf62a53b 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -780,7 +780,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show payments table * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object invoice * @param int $posy Position y in PDF * @param Translate $outputlangs Object langs for output @@ -965,7 +965,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show miscellaneous information (payment mode, payment term, ...) * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $posy Y * @param Translate $outputlangs Langs object @@ -1139,7 +1139,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show total to pay * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Facture $object Object invoice * @param int $deja_regle Amount already paid (in the currency of invoice) * @param int $posy Position depart @@ -1464,7 +1464,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show table for lines * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param string $tab_top Top position of table * @param string $tab_height Height of table (rectangle) * @param int $nexY Y (not used) @@ -1586,7 +1586,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show top header of page. * - * @param PDF $pdf Object PDF + * @param TCPDF $pdf Object PDF * @param Object $object Object to show * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output @@ -1889,7 +1889,7 @@ class pdf_crabe extends ModelePDFFactures /** * Show footer of page. Need this->emetteur object * - * @param PDF $pdf PDF + * @param TCPDF $pdf PDF * @param Object $object Object to show * @param Translate $outputlangs Object lang for output * @param int $hidefreetext 1=Hide free text diff --git a/htdocs/core/modules/modPaymentByBankTransfer.class.php b/htdocs/core/modules/modPaymentByBankTransfer.class.php index d68274e2dee..9ea1bf00f29 100644 --- a/htdocs/core/modules/modPaymentByBankTransfer.class.php +++ b/htdocs/core/modules/modPaymentByBankTransfer.class.php @@ -54,7 +54,7 @@ class modPaymentByBankTransfer extends DolibarrModules $this->description = "Management of payment by bank transfer"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'development'; + $this->version = 'dolibarr'; $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Name of png file (without png) used for this module diff --git a/htdocs/core/modules/modRecruitment.class.php b/htdocs/core/modules/modRecruitment.class.php index c9093c34272..0cbe9da017b 100644 --- a/htdocs/core/modules/modRecruitment.class.php +++ b/htdocs/core/modules/modRecruitment.class.php @@ -62,7 +62,7 @@ class modRecruitment extends DolibarrModules // Used only if file README.md and README-LL.md not found. $this->descriptionlong = "Manage and follow recruitment campaign for new job positions"; // Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z' - $this->version = 'development'; + $this->version = 'experimental'; // Url to the file with your last numberversion of this module //$this->url_last_version = 'http://www.example.com/versionmodule.txt'; diff --git a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php index 3a1cf3667aa..23b71244cbd 100644 --- a/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php +++ b/htdocs/core/modules/security/generate/modGeneratePassStandard.class.php @@ -59,7 +59,7 @@ class modGeneratePassStandard extends ModeleGenPassword public function __construct($db, $conf, $langs, $user) { $this->id = "standard"; - $this->length = 8; + $this->length = 10; $this->db = $db; $this->conf = $conf; diff --git a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php index 2905bfd6b26..5340f33f450 100644 --- a/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php +++ b/htdocs/core/modules/stock/doc/pdf_stdmovement.modules.php @@ -183,7 +183,7 @@ class pdf_stdmovement extends ModelePDFMovement /** * Function to build a document on disk using the generic odt module. * - * @param StockMovements $object Object source to build document + * @param MouvementStock $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file * @param int $hidedetails Do not show line details 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 a4f9bc93823..2140d13400f 100644 --- a/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php +++ b/htdocs/core/modules/supplier_payment/doc/pdf_standard.modules.php @@ -552,7 +552,6 @@ class pdf_standard extends ModelePDFSuppliersPayments $pdf->MultiCell(35, 4, str_pad(price($object->amount).' '.$currency, 18, '*', STR_PAD_LEFT), 0, 'R', 1); $posy += 10; - // City $pdf->SetXY($this->page_largeur - $this->marge_droite - 30, $posy); $pdf->MultiCell(150, 4, $mysoc->town, 0, 'L', 1); @@ -592,9 +591,9 @@ class pdf_standard extends ModelePDFSuppliersPayments $pdf->SetTextColor(0, 0, 0); $pdf->SetFont('', '', $default_font_size - 2); - $titre = strtoupper($mysoc->town).', le '.date("d").' '.$outputlangs->transnoentitiesnoconv(date("F")).' '.date("Y"); + /*$titre = strtoupper($mysoc->town).' - '.dol_print_date(dol_now(), 'day', 'tzserver', $outputlangs); $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3) - 60, $tab_top - 6); - $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre); + $pdf->MultiCell(($pdf->GetStringWidth($titre) + 3), 2, $titre);*/ $titre = $outputlangs->transnoentities("AmountInCurrency", $outputlangs->transnoentitiesnoconv("Currency".$currency)); $pdf->SetXY($this->page_largeur - $this->marge_droite - ($pdf->GetStringWidth($titre) + 3), $tab_top); @@ -754,7 +753,9 @@ class pdf_standard extends ModelePDFSuppliersPayments $carac_client_name = pdfBuildThirdpartyName($thirdparty, $outputlangs); - $carac_client = pdf_build_address($outputlangs, $this->emetteur, $mysoc, ((!empty($object->contact)) ? $object->contact : null), $usecontact, 'target', $object); + $usecontact = 0; + + $carac_client = pdf_build_address($outputlangs, $this->emetteur, $object->thirdparty, ((!empty($object->contact)) ? $object->contact : null), $usecontact, 'target', $object); // Show recipient $widthrecbox = 90; diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index eaf2c58eb4b..f677197e3df 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -185,8 +185,10 @@ if ((($type == 'select') || ($type == 'checkbox') || ($type == 'radio')) && is_a ?> trans("LabelOrTranslationKey"); ?> + trans("AttributeCode"); ?> + trans("Type"); ?> array('varchar', 'phone', 'mail', 'url', 'select'), 'select'=>array('varchar', 'phone', 'mail', 'url', 'select') ); +/* Disabled because text is text on several lines, when varchar is text on 1 line, we should not be able to convert +if ($size <= 255 && in_array($type, array('text', 'html'))) { + $typewecanchangeinto['text'][] = 'varchar'; +}*/ if (in_array($type, array_keys($typewecanchangeinto))) { @@ -222,8 +228,10 @@ if (in_array($type, array_keys($typewecanchangeinto))) } ?> + trans("Size"); ?> + @@ -244,33 +252,44 @@ if (in_array($type, array_keys($typewecanchangeinto))) + trans("Position"); ?> + trans("LanguageFile"); ?> + global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { ?> textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc"), 1, 'help', '', 0, 2, 'tooltipcompute'); ?> textwithpicto($langs->trans("ComputedFormula"), $langs->trans("ComputedFormulaDesc")).$form->textwithpicto($langs->trans("Computedpersistent"), $langs->trans("ComputedpersistentDesc"), 1, 'warning'); ?> + trans("DefaultValue").' ('.$langs->trans("Database").')'; ?> + trans("Unique"); ?>> + trans("Required"); ?>> + trans("AlwaysEditable"); ?>> + textwithpicto($langs->trans("Visibility"), $langs->trans("VisibleDesc")); ?> + textwithpicto($langs->trans("DisplayOnPdf"), $langs->trans("DisplayOnPdfDesc")); ?> textwithpicto($langs->trans("Totalizable"), $langs->trans("TotalizableDesc")); ?>> + textwithpicto($langs->trans("HelpOnTooltip"), $langs->trans("HelpOnTooltipDesc")); ?> + multicompany->enabled) { ?> trans("AllEntities"); ?>> diff --git a/htdocs/core/tpl/extrafields_list_search_input.tpl.php b/htdocs/core/tpl/extrafields_list_search_input.tpl.php index 8d09f6840b3..22a6135cd13 100644 --- a/htdocs/core/tpl/extrafields_list_search_input.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_input.tpl.php @@ -40,7 +40,7 @@ if (!empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_e } else { // for the type as 'checkbox', 'chkbxlst', 'sellist' we should use code instead of id (example: I declare a 'chkbxlst' to have a link with dictionnairy, I have to extend it with the 'code' instead 'rowid') $morecss = ''; - if (in_array($typeofextrafield, array('link', 'sellist'))) $morecss = 'maxwidth200'; + if (in_array($typeofextrafield, array('link', 'sellist', 'text', 'html'))) $morecss = 'maxwidth200'; echo $extrafields->showInputField($key, $search_array_options[$search_options_pattern.$tmpkey], '', '', $search_options_pattern, $morecss, 0, $extrafieldsobjectkey, 1); } print ''; diff --git a/htdocs/core/tpl/extrafields_list_search_title.tpl.php b/htdocs/core/tpl/extrafields_list_search_title.tpl.php index bb231424396..7ba2c284d39 100644 --- a/htdocs/core/tpl/extrafields_list_search_title.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_title.tpl.php @@ -27,6 +27,10 @@ if (!empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_e if ($extrafields->attributes[$extrafieldsobjectkey]['type'][$key] == 'separate') { print ''; } else { + if (! empty($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]) && is_object($langs)) { + $langs->load($extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key]); + } + $tooltip = empty($extrafields->attributes[$extrafieldsobjectkey]['help'][$key]) ? '' : $extrafields->attributes[$extrafieldsobjectkey]['help'][$key]; print getTitleFieldOfList($extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align ? 'align="'.$align.'" data-titlekey="'.$key.'"' : 'data-titlekey="'.$key.'"'), $sortfield, $sortorder, '', $disablesortlink, $tooltip)."\n"; diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index f387725bece..e646be4842a 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -87,17 +87,14 @@ else $typeofdata = 'textarea:12:95%'; print ''."\n"; print '
'."\n"; -if ($module != 'product') { - // No public note yet on products - print '
'."\n"; - 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"; -} +print '
'."\n"; +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"; diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 4bc56c4cd71..e6dbf827fce 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2463,6 +2463,7 @@ class Expedition extends CommonObject global $conf, $langs; $langs->load("sendings"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'rouget'; diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 6b165c1042e..a21ed4d6612 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -109,7 +109,7 @@ $hookmanager->initHooks(array('expensereportlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('expensereport'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index 679d231d6a8..66475f83edf 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -197,8 +197,6 @@ class FichinterRec extends Fichinter */ $num = count($fichintsrc->lines); for ($i = 0; $i < $num; $i++) { - //$result=$fichintlignesrc->fetch($fichintsrc->lines[$i]->id); - //var_dump($fichintsrc->lines[$i]); $result_insert = $this->addline( $fichintsrc->lines[$i]->desc, @@ -243,7 +241,7 @@ class FichinterRec extends Fichinter /** - * Recupere l'objet facture et ses lignes de factures + * Get the template of intervention object and lines * * @param int $rowid Id of object to load * @param string $ref Reference of fichinter @@ -295,9 +293,7 @@ class FichinterRec extends Fichinter $this->brouillon = 1; - /* - * Lines - */ + // Lines $result = $this->fetch_lines(); if ($result < 0) { $this->error = $this->db->error(); @@ -318,9 +314,9 @@ class FichinterRec extends Fichinter // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Recupere les lignes de factures predefinies dans this->lines - * @param int $sall sall + * Load all lines of template of intervention into this->lines * + * @param int $sall sall * @return int 1 if OK, < 0 if KO */ public function fetch_lines($sall = 0) @@ -441,15 +437,15 @@ class FichinterRec extends Fichinter * @param integer $duration Durée * @param string $datei Date * @param int $rang Position of line - * @param double $pu_ht Prix unitaire HT (> 0 even for credit note) - * @param double $qty Quantite - * @param double $txtva Taux de tva force, sinon -1 - * @param int $fk_product Id du produit/service predefini - * @param double $remise_percent Pourcentage de remise de la ligne + * @param double $pu_ht Unit price without tax (> 0 even for credit note) + * @param double $qty Quantity + * @param double $txtva Forced VAT rate, otherwise -1 + * @param int $fk_product Id of predefined product/service + * @param double $remise_percent Percentage of discount on line * @param string $price_base_type HT or TTC - * @param int $info_bits Bits de type de lignes - * @param int $fk_remise_except Id remise - * @param double $pu_ttc Prix unitaire TTC (> 0 even for credit note) + * @param int $info_bits Bits for type of lines + * @param int $fk_remise_except Id discount + * @param double $pu_ttc Unit price with tax (> 0 even for credit note) * @param int $type Type of line (0=product, 1=service) * @param int $special_code Special code * @param string $label Label of the line diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 993dd0f3fa4..0204689b9b0 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -85,7 +85,7 @@ $hookmanager->initHooks(array('interventionlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('fichinter'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 5ec2b6f49a6..501f0c48977 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -293,9 +293,9 @@ class SupplierInvoices extends DolibarrApi } /** - * Validate an order + * Validate an invoice * - * @param int $id Order ID + * @param int $id Invoice ID * @param int $idwarehouse Warehouse ID * @param int $notrigger 1=Does not execute triggers, 0= execute triggers * @@ -325,7 +325,7 @@ class SupplierInvoices extends DolibarrApi $result = $this->invoice->validate(DolibarrApiAccess::$user, '', $idwarehouse, $notrigger); if ($result == 0) { - throw new RestException(304, 'Error nothing done. May be object is already validated'); + throw new RestException(304, 'Error nothing done. The invoice is already validated'); } if ($result < 0) { throw new RestException(500, 'Error when validating Invoice: '.$this->invoice->error); @@ -454,6 +454,7 @@ class SupplierInvoices extends DolibarrApi $paiement->multicurrency_amounts = $multicurrency_amounts; // Array with all payments dispatching $paiement->paiementid = $paiementid; $paiement->paiementcode = dol_getIdFromCode($this->db, $paiementid, 'c_paiement', 'id', 'code', 1); + $paiement->oper = $paiement->paiementcode; // For backward compatibility $paiement->num_payment = $num_payment; $paiement->note_public = $comment; diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index bee6346386b..b180016bdd9 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -187,6 +187,8 @@ class SupplierOrders extends DolibarrApi /** * Create supplier order object * + * Example: {"ref": "auto", "ref_supplier": "1234", "socid": "1", "multicurrency_code": "SEK", "multicurrency_tx": 1, "tva_tx": 25, "note": "Imported via the REST API"} + * * @param array $request_data Request datas * @return int ID of supplier order */ diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index c483206fd1f..f6d506a28be 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -2966,6 +2966,7 @@ class CommandeFournisseur extends CommonOrder global $conf, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'muscadet'; diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index 518c6885411..d85a4e0941a 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -290,7 +290,9 @@ class CommandeFournisseurDispatch extends CommonObject $this->batch = $obj->batch; $this->eatby = $this->db->jdate($obj->eatby); $this->sellby = $this->db->jdate($obj->sellby); - $this->fetch_optionals(); + $this->fk_reception = $obj->fk_reception; + + $this->fetch_optionals(); } $this->db->free($resql); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 48ecb3de70f..04525afa04d 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1259,7 +1259,7 @@ class FactureFournisseur extends CommonInvoice $this->db->begin(); $sql = 'UPDATE '.MAIN_DB_PREFIX.'facture_fourn'; - $sql .= ' SET paye = 1, fk_statut=2'; + $sql .= ' SET paye = 1, fk_statut = '.self::STATUS_CLOSED; $sql .= ' WHERE rowid = '.$this->id; dol_syslog("FactureFournisseur::set_paid", LOG_DEBUG); @@ -2267,7 +2267,8 @@ class FactureFournisseur extends CommonInvoice $result = ''; - if ($option == 'document') $url = DOL_URL_ROOT.'/fourn/facture/document.php?facid='.$this->id; + if ($option == 'withdraw') $url = DOL_URL_ROOT.'/compta/facture/prelevement.php?facid='.$this->id.'&type=bank-transfer'; + elseif ($option == 'document') $url = DOL_URL_ROOT.'/fourn/facture/document.php?facid='.$this->id; else $url = DOL_URL_ROOT.'/fourn/facture/card.php?facid='.$this->id; if ($short) return $url; @@ -2641,6 +2642,7 @@ class FactureFournisseur extends CommonInvoice global $conf, $user, $langs; $langs->load("suppliers"); + $outputlangs->load("products"); // Set the model on the model name to use if (empty($modele)) diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 4168656d05f..7a50a189e44 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -463,11 +463,26 @@ if (empty($reshook)) if ($idprod > 0) { $label = $productsupplier->label; - + // Define output language + if (!empty($conf->global->MAIN_MULTILANGS) && !empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { + $outputlangs = $langs; + $newlang = ''; + if (empty($newlang) && GETPOST('lang_id', 'aZ09')) + $newlang = GETPOST('lang_id', 'aZ09'); + if (empty($newlang)) + $newlang = $object->thirdparty->default_lang; + if (!empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + $desc = (!empty($productsupplier->multilangs [$outputlangs->defaultlang] ["description"])) ? $productsupplier->multilangs [$outputlangs->defaultlang] ["description"] : $productsupplier->description; + } else { + $desc = $productsupplier->description; + } // if we use supplier description of the products if (!empty($productsupplier->desc_supplier) && !empty($conf->global->PRODUIT_FOURN_TEXTS)) { $desc = $productsupplier->desc_supplier; - } else $desc = $productsupplier->description; + } if (trim($product_desc) != trim($desc)) $desc = dol_concatdesc($desc, $product_desc, '', !empty($conf->global->MAIN_CHANGE_ORDER_CONCAT_DESCRIPTION)); diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index 6f665a381df..c64d158ac2c 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -743,7 +743,8 @@ if ($id > 0 || !empty($ref)) { print ''.$langs->trans("SupplierRef").''; print ''.$langs->trans("QtyOrdered").''; print ''.$langs->trans("QtyDispatchedShort").''; - print ''.$langs->trans("QtyToDispatchShort").''; + print ' '.$langs->trans("QtyToDispatchShort"); + print '
'.$langs->trans("Reset").''; print ''; if (!empty($conf->global->SUPPLIER_ORDER_CAN_UPDATE_BUYINGPRICE_DURING_RECEIPT)) { @@ -971,7 +972,7 @@ if ($id > 0 || !empty($ref)) { // Discount print ''; - print ''; + print ''; print ''; // Save price @@ -1068,7 +1069,16 @@ if ($id > 0 || !empty($ref)) { $("select[name=fk_default_warehouse]").change(function() { var fk_default_warehouse = $("option:selected", this).val(); $("select[name^=entrepot_]").val(fk_default_warehouse).change(); - }); + }); + + jQuery("#autoreset").click(function() {'; + $i = 0; + while ($i < $nbproduct) { + print ' jQuery("#qty_0_'.$i.'").val("");'; + $i++; + } + print ' + }); }); '; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index 8ffc6be6c05..a792d68fc6b 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -120,7 +120,7 @@ $hookmanager->initHooks(array('supplierorderlist')); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -$extrafields->fetch_name_optionals_label('commande_fournisseur'); +$extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 80301dcdc43..7e8796e44f6 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1724,6 +1724,9 @@ if ($action == 'create') $mode_reglement_id = GETPOST("mode_reglement_id"); } + $note_public = $object->getDefaultCreateValueFor('note_public', ((! empty($origin) && ! empty($originid) && is_object($objectsrc) && !empty($conf->global->FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM))?$objectsrc->note_public:null)); + $note_private = $object->getDefaultCreateValueFor('note_private', ((! empty($origin) && ! empty($originid) && is_object($objectsrc) && !empty($conf->global->FACTUREFOURN_REUSE_NOTES_ON_CREATE_FROM))?$objectsrc->note_private:null)); + print '
'; print ''; print ''; @@ -2048,8 +2051,6 @@ if ($action == 'create') // Public note print ''.$langs->trans('NotePublic').''; print ''; - $note_public = $object->getDefaultCreateValueFor('note_public'); - if (empty($note_public))$note_public = $objectsrc->note_public; $doleditor = new DolEditor('note_public', (GETPOSTISSET('note_public') ?GETPOST('note_public', 'none') : $note_public), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); print ''; @@ -2059,9 +2060,6 @@ if ($action == 'create') // Private note print ''.$langs->trans('NotePrivate').''; print ''; - $note_private = $object->getDefaultCreateValueFor('note_private'); - if (empty($note_private))$note_private = $objectsrc->note_private; - $doleditor = new DolEditor('note_private', (GETPOSTISSET('note_private') ?GETPOST('note_private', 'none') : $note_private), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, '90%'); print $doleditor->Create(1); print ''; diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 8801d400afc..28020e40811 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -27,10 +27,10 @@ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -require DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; -require DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; -require DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; -require DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; $langs->loadLangs(array('bills', 'banks', 'companies', 'suppliers')); diff --git a/htdocs/index.php b/htdocs/index.php index efa4de3890d..4668da1a6db 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -356,7 +356,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { $dashboardlines[$board->element] = $board->load_board($user); } - // Number of commercial proposals opened (expired) + // Number of commercial proposals open (expired) if (!empty($conf->propal->enabled) && $user->rights->propale->lire) { include_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; $board = new Propal($db); @@ -365,7 +365,7 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { $dashboardlines[$board->element.'_signed'] = $board->load_board($user, "signed"); } - // Number of commercial proposals opened (expired) + // Number of commercial proposals open (expired) if (!empty($conf->supplier_proposal->enabled) && $user->rights->supplier_proposal->lire) { include_once DOL_DOCUMENT_ROOT.'/supplier_proposal/class/supplier_proposal.class.php'; $board = new SupplierProposal($db); @@ -407,14 +407,14 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { //$dashboardlines[$board->element.'_active'] = $board->load_board($user, "active"); } - // Number of invoices customers (has paid) + // Number of invoices customers (paid) if (!empty($conf->facture->enabled) && $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 (has paid) + // Number of supplier invoices (paid) if (!empty($conf->supplier_invoice->enabled) && !empty($user->rights->fournisseur->facture->lire)) { include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; $board = new FactureFournisseur($db); @@ -715,21 +715,35 @@ if (empty($conf->global->MAIN_DISABLE_GLOBAL_WORKBOARD)) { $textLate = ''; if ($board->nbtodolate > 0) { - $textLate .= ' '; + $textLate .= ''; $textLate .= ' '.$board->nbtodolate; $textLate .= ''; } + $openedDashBoard .= '
'; + $nbtodClass = ''; if ($board->nbtodo > 0) { $nbtodClass = 'badge badge-info'; } - $openedDashBoard .= ' '.$infoName.' : '.$board->nbtodo.''.$textLate.''."\n"; + $openedDashBoard .= ' '.$infoName.' : '.$board->nbtodo.''; + if ($textLate) { + if ($board->url_late) { + $openedDashBoard .= ''; + $openedDashBoard .= ' '; + } else { + $openedDashBoard .= ' '; + } + $openedDashBoard .= $textLate; + } + $openedDashBoard .= ''."\n"; if ($board->total > 0 && !empty($conf->global->MAIN_WORKBOARD_SHOW_TOTAL_WO_TAX)) { $openedDashBoard .= ''.$langs->trans('Total').' : '.price($board->total).''; } + + $openedDashBoard .= '
'; } $openedDashBoard .= '
'."\n"; diff --git a/htdocs/install/mysql/data/llx_c_prospectcontactlevel.sql b/htdocs/install/mysql/data/llx_c_prospectcontactlevel.sql new file mode 100644 index 00000000000..b45239ca992 --- /dev/null +++ b/htdocs/install/mysql/data/llx_c_prospectcontactlevel.sql @@ -0,0 +1,31 @@ +-- Copyright (C) 2020 Open-Dsi +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- + +-- +-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors +-- de l'install et tous les sigles '--' sont supprimés. +-- + +-- +-- Prospect level for contacts +-- + +--delete from llx_c_prospectcontactlevel; +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_NONE', 'None', 1); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_LOW', 'Low', 2); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_MEDIUM', 'Medium', 3); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_HIGH', 'High', 4); diff --git a/htdocs/install/mysql/data/llx_c_stcommcontact.sql b/htdocs/install/mysql/data/llx_c_stcommcontact.sql new file mode 100644 index 00000000000..53e6aad1cca --- /dev/null +++ b/htdocs/install/mysql/data/llx_c_stcommcontact.sql @@ -0,0 +1,32 @@ +-- Copyright (C) 2020 Open-Dsi +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- + +-- +-- Ne pas placer de commentaire en fin de ligne, ce fichier est parsé lors +-- de l'install et tous les sigles '--' sont supprimés. +-- + +-- +-- Types action st for contacts +-- + +delete from llx_c_stcommcontact; +insert into llx_c_stcommcontact (id,code,libelle) values (-1, 'ST_NO', 'Do not contact'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 0, 'ST_NEVER', 'Never contacted'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 1, 'ST_TODO', 'To contact'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 2, 'ST_PEND', 'Contact in progress'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 3, 'ST_DONE', 'Contacted'); diff --git a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql index 2a7a8963e9f..83a502dbbff 100644 --- a/htdocs/install/mysql/migration/10.0.0-11.0.0.sql +++ b/htdocs/install/mysql/migration/10.0.0-11.0.0.sql @@ -98,7 +98,7 @@ ALTER TABLE llx_bom_bomline ADD COLUMN position integer NOT NULL DEFAULT 0; ALTER TABLE llx_bom_bomline ADD COLUMN qty_frozen smallint DEFAULT 0; ALTER TABLE llx_bom_bomline ADD COLUMN disable_stock_change smallint DEFAULT 0; -ALTER TABLE llx_bom_bomline DROP COLUMN rank; +ALTER TABLE llx_bom_bomline DROP COLUMN `rank`; create table llx_categorie_warehouse ( diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 7f2cc35451c..df4a3e45c75 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -305,7 +305,6 @@ ALTER TABLE llx_categorie ADD COLUMN fk_user_modif integer; ALTER TABLE llx_commandedet ADD CONSTRAINT fk_commandedet_fk_commandefourndet FOREIGN KEY (fk_commandefourndet) REFERENCES llx_commande_fournisseurdet (rowid); - -- VMYSQL4.3 ALTER TABLE llx_prelevement_facture_demande MODIFY COLUMN fk_facture INTEGER NULL; -- VPGSQL8.2 ALTER TABLE llx_prelevement_facture_demande ALTER COLUMN fk_facture DROP NOT NULL; ALTER TABLE llx_prelevement_facture_demande ADD COLUMN fk_facture_fourn INTEGER NULL; 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 cf4339f56b9..469550dbbe7 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 @@ -81,6 +81,7 @@ ALTER TABLE llx_c_incoterms ADD COLUMN label varchar(100) NULL; CREATE TABLE llx_recruitment_recruitmentjobposition( rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, ref varchar(128) DEFAULT '(PROV)' NOT NULL, + entity INTEGER DEFAULT 1 NOT NULL, label varchar(255) NOT NULL, qty integer DEFAULT 1 NOT NULL, fk_soc integer, @@ -89,6 +90,7 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( fk_user_supervisor integer, fk_establishment integer, date_planned date, + remuneration_suggested varchar(255), description text, note_public text, note_private text, @@ -112,6 +114,10 @@ ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitmen ALTER TABLE llx_recruitment_recruitmentjobposition ADD CONSTRAINT llx_recruitment_recruitmentjobposition_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); ALTER TABLE llx_recruitment_recruitmentjobposition ADD INDEX idx_recruitment_recruitmentjobposition_status (status); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN email_recruiter varchar(255); +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN entity INTEGER DEFAULT 1 NOT NULL; +ALTER TABLE llx_recruitment_recruitmentjobposition ADD COLUMN remuneration_suggested varchar(255); + create table llx_recruitment_recruitmentjobposition_extrafields ( rowid integer AUTO_INCREMENT PRIMARY KEY, @@ -123,6 +129,52 @@ create table llx_recruitment_recruitmentjobposition_extrafields ALTER TABLE llx_recruitment_recruitmentjobposition_extrafields ADD INDEX idx_fk_object(fk_object); + +CREATE TABLE llx_recruitment_recruitmentcandidature( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + fk_recruitmentjobposition INTEGER NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + 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), + model_pdf varchar(255), + status smallint NOT NULL, + firstname varchar(128), + lastname varchar(128), + remuneration_requested integer, + remuneration_proposed integer, + fk_recruitment_origin INTEGER NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; + +ALTER TABLE llx_recruitment_recruitmentcandidature ADD COLUMN fk_recruitment_origin INTEGER NULL; + +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_rowid (rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_ref (ref); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD CONSTRAINT llx_recruitment_recruitmentcandidature_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_status (status); + + + +create table llx_recruitment_recruitmentcandidature_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_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_fk_object(fk_object); + + + + CREATE TABLE llx_product_attribute_combination_price_level ( rowid INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT, @@ -133,3 +185,47 @@ CREATE TABLE llx_product_attribute_combination_price_level )ENGINE=innodb; ALTER TABLE llx_product_attribute_combination_price_level ADD UNIQUE( fk_product_attribute_combination, fk_price_level); + + + +-- Add dictionary for prospect level and action commercial on contacts (Using this is not recommanded) + +create table llx_c_prospectcontactlevel +( + code varchar(12) PRIMARY KEY, + label varchar(30), + sortorder smallint, + active smallint DEFAULT 1 NOT NULL, + module varchar(32) NULL +) ENGINE=innodb; +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_NONE', 'None', 1); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_LOW', 'Low', 2); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_MEDIUM', 'Medium', 3); +insert into llx_c_prospectcontactlevel (code,label,sortorder) values ('PL_HIGH', 'High', 4); + +create table llx_c_stcommcontact +( + id integer PRIMARY KEY, + code varchar(12) NOT NULL, + libelle varchar(30), + picto varchar(128), + active tinyint default 1 NOT NULL +)ENGINE=innodb; +ALTER TABLE llx_c_stcommcontact ADD UNIQUE INDEX uk_c_stcommcontact(code); + +insert into llx_c_stcommcontact (id,code,libelle) values (-1, 'ST_NO', 'Do not contact'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 0, 'ST_NEVER', 'Never contacted'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 1, 'ST_TODO', 'To contact'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 2, 'ST_PEND', 'Contact in progress'); +insert into llx_c_stcommcontact (id,code,libelle) values ( 3, 'ST_DONE', 'Contacted'); + +ALTER TABLE llx_socpeople ADD COLUMN fk_prospectcontactlevel varchar(12) AFTER priv; +ALTER TABLE llx_socpeople ADD COLUMN fk_stcommcontact integer DEFAULT 0 NOT NULL AFTER fk_prospectcontactlevel; + +create table llx_c_recruitment_origin +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(32) NOT NULL, + label varchar(64) NOT NULL, + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_c_prospectcontactlevel.sql b/htdocs/install/mysql/tables/llx_c_prospectcontactlevel.sql new file mode 100644 index 00000000000..421b3452371 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_prospectcontactlevel.sql @@ -0,0 +1,27 @@ +-- =================================================================== +-- Copyright (C) 2020 Open-Dsi +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- =================================================================== + +create table llx_c_prospectcontactlevel +( + code varchar(12) PRIMARY KEY, + label varchar(30), + sortorder smallint, + active smallint DEFAULT 1 NOT NULL, + module varchar(32) NULL +) ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_c_recruitment_origin.sql b/htdocs/install/mysql/tables/llx_c_recruitment_origin.sql new file mode 100644 index 00000000000..b18f7eb383c --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_recruitment_origin.sql @@ -0,0 +1,33 @@ +-- ======================================================================== +-- Copyright (C) 2005-2016 Laurent Destailleur +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- 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 . +-- +-- Defini les types de contact d'un element sert de reference pour +-- la table llx_element_contact +-- +-- element est le nom de la table utilisant le type de contact. +-- i.e. contact, facture, projet, societe (sans le llx_ devant). +-- Libelle est un texte decrivant le type de contact. +-- active precise si cette valeur est 'active' ou 'archive'. +-- +-- ======================================================================== + +create table llx_c_recruitment_origin +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + code varchar(32) NOT NULL, + label varchar(64) NOT NULL, + active tinyint DEFAULT 1 NOT NULL +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_c_stcommcontact.key.sql b/htdocs/install/mysql/tables/llx_c_stcommcontact.key.sql new file mode 100644 index 00000000000..12402658a65 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_stcommcontact.key.sql @@ -0,0 +1,19 @@ +-- ======================================================================== +-- Copyright (C) 2020 Open-Dsi +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- ======================================================================== + +ALTER TABLE llx_c_stcommcontact ADD UNIQUE INDEX uk_c_stcommcontact(code); diff --git a/htdocs/install/mysql/tables/llx_c_stcommcontact.sql b/htdocs/install/mysql/tables/llx_c_stcommcontact.sql new file mode 100644 index 00000000000..c906e4f5103 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_c_stcommcontact.sql @@ -0,0 +1,27 @@ +-- ======================================================================== +-- Copyright (C) 2020 Open-Dsi +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- ======================================================================== + +create table llx_c_stcommcontact +( + id integer PRIMARY KEY, + code varchar(12) NOT NULL, + libelle varchar(30), + picto varchar(128), + active tinyint default 1 NOT NULL +)ENGINE=innodb; + diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql new file mode 100644 index 00000000000..8f92832c2a3 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.key.sql @@ -0,0 +1,27 @@ +-- 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 https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_rowid (rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_ref (ref); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD CONSTRAINT llx_recruitment_recruitmentcandidature_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid); +ALTER TABLE llx_recruitment_recruitmentcandidature ADD INDEX idx_recruitment_recruitmentcandidature_status (status); +-- END MODULEBUILDER INDEXES + +--ALTER TABLE llx_mymodule_myobject ADD UNIQUE INDEX uk_mymodule_myobject_fieldxy(fieldx, fieldy); + +--ALTER TABLE llx_mymodule_myobject ADD CONSTRAINT llx_mymodule_myobject_fk_field FOREIGN KEY (fk_field) REFERENCES llx_mymodule_myotherobject(rowid); + diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql new file mode 100644 index 00000000000..43bdb14e7bd --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature.sql @@ -0,0 +1,38 @@ +-- 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 https://www.gnu.org/licenses/. + + +CREATE TABLE llx_recruitment_recruitmentcandidature( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + fk_recruitmentjobposition INTEGER NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + 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), + model_pdf varchar(255), + status smallint NOT NULL, + firstname varchar(128), + lastname varchar(128), + remuneration_requested integer, + remuneration_proposed integer, + fk_recruitment_origin INTEGER NULL + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql new file mode 100644 index 00000000000..fb1522bf6f1 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.key.sql @@ -0,0 +1,19 @@ +-- 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 https://www.gnu.org/licenses/. + + +-- BEGIN MODULEBUILDER INDEXES +ALTER TABLE llx_recruitment_recruitmentcandidature_extrafields ADD INDEX idx_fk_object(fk_object); +-- END MODULEBUILDER INDEXES diff --git a/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql new file mode 100644 index 00000000000..d0fb92fead9 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentcandidature_extrafields.sql @@ -0,0 +1,23 @@ +-- 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 https://www.gnu.org/licenses/. + +create table llx_recruitment_recruitmentcandidature_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_recruitment_recruitmentjobposition.sql b/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql index c527409862d..b342156ccd1 100644 --- a/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql +++ b/htdocs/install/mysql/tables/llx_recruitment_recruitmentjobposition.sql @@ -17,15 +17,18 @@ CREATE TABLE llx_recruitment_recruitmentjobposition( -- BEGIN MODULEBUILDER FIELDS rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, - ref varchar(128) DEFAULT '(PROV)' NOT NULL, + ref varchar(128) DEFAULT '(PROV)' NOT NULL, + entity INTEGER DEFAULT 1 NOT NULL, label varchar(255) NOT NULL, qty integer DEFAULT 1 NOT NULL, fk_soc integer, fk_project integer, - fk_user_recruiter integer, + fk_user_recruiter integer, + email_recruiter varchar(255), fk_user_supervisor integer, fk_establishment integer, - date_planned date, + date_planned date, + remuneration_suggested varchar(255), description text, note_public text, note_private text, diff --git a/htdocs/install/mysql/tables/llx_socpeople.sql b/htdocs/install/mysql/tables/llx_socpeople.sql index fceb2044649..2a1b551beb9 100644 --- a/htdocs/install/mysql/tables/llx_socpeople.sql +++ b/htdocs/install/mysql/tables/llx_socpeople.sql @@ -2,6 +2,7 @@ -- Copyright (C) 2001-2004 Rodolphe Quiedeville -- Copyright (C) 2008 Laurent Destailleur -- Copyright (C) 2005-2010 Regis Houssin +-- Copyright (C) 2020 Open-Dsi -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -57,6 +58,8 @@ create table llx_socpeople photo varchar(255), no_email smallint NOT NULL DEFAULT 0, -- deprecated. Use table llx_mailing_unsubscribe instead priv smallint NOT NULL DEFAULT 0, + fk_prospectcontactlevel varchar(12), -- prospect level (in llx_c_prospectcontactlevel) + fk_stcommcontact integer DEFAULT 0 NOT NULL, -- commercial statut fk_user_creat integer DEFAULT 0, -- user qui a creel'enregistrement fk_user_modif integer, note_private text, diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index e27ac19c15a..b49feba85d6 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -85,7 +85,7 @@ create table llx_user openid varchar(255), statut tinyint DEFAULT 1, photo varchar(255), -- filename or url of photo - lang varchar(6), + lang varchar(6), -- default language for communication. Note that language selected by user as interface language is savec into llx_user_param. color varchar(6), barcode varchar(255) DEFAULT NULL, fk_barcode_type integer DEFAULT 0, diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index d427e529a8d..ef4e3b82a9d 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -996,7 +996,7 @@ if ($ok && GETPOST('clean_product_stock_batch', 'alpha')) $resql2 = $db->query($sql2); if ($resql2) { - // We update product_stock, so we must field stock into product too. + // We update product_stock, so we must fill p.stock into product too. $sql3 = '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)'; $resql3 = $db->query($sql3); if (!$resql3) diff --git a/htdocs/langs/de_AT/main.lang b/htdocs/langs/de_AT/main.lang index 545ae518ec7..124392e3512 100644 --- a/htdocs/langs/de_AT/main.lang +++ b/htdocs/langs/de_AT/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias NoRecordFound=Kein Eintrag gefunden NoRecordDeleted=Kein Eintrag gelöscht NoError=Kein Fehler diff --git a/htdocs/langs/de_CH/main.lang b/htdocs/langs/de_CH/main.lang index 60ec3c2adff..ba91e452a89 100644 --- a/htdocs/langs/de_CH/main.lang +++ b/htdocs/langs/de_CH/main.lang @@ -21,7 +21,6 @@ FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M NoTemplateDefined=Für diesen Emailtyp habe ich keine Vorlage.. AvailableVariables=Verfügbare Ersatzvariablen -EmptySearchString=Enter non empty search criterias NoRecordDeleted=Es wurde kein Datensatz gelöscht NotEnoughDataYet=Nicht genügend Daten NoError=Kein Fehler diff --git a/htdocs/langs/de_CH/stocks.lang b/htdocs/langs/de_CH/stocks.lang index a7776df946c..fc51f5818de 100644 --- a/htdocs/langs/de_CH/stocks.lang +++ b/htdocs/langs/de_CH/stocks.lang @@ -14,7 +14,6 @@ StockLimit=Sicherungsbestand für autom. Benachrichtigung RealStock=Realer Lagerbestand VirtualStock=Theoretisches Warenlager AverageUnitPricePMPShort=Gewichteter Durchschnitts-Einstandspreis -AverageUnitPricePMP=Gewichteter Durchschnittpreis bei Erwerb DesiredStockDesc=Dieser Bestand wird für die Nachbestellfunktion verwendet. UseVirtualStockByDefault=Nutze theoretische Lagerbestände anstatt des physischem Bestands für die Nachbestellungsfunktion UseVirtualStock=theoretisches Warenlager verwenden diff --git a/htdocs/langs/en_AU/admin.lang b/htdocs/langs/en_AU/admin.lang index 50add47a7d4..0980facb414 100644 --- a/htdocs/langs/en_AU/admin.lang +++ b/htdocs/langs/en_AU/admin.lang @@ -1,5 +1,4 @@ # Dolibarr language file - Source file is en_US - admin -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. OldVATRates=Old GST rate NewVATRates=New GST rate DictionaryVAT=GST Rates or Sales Tax Rates diff --git a/htdocs/langs/en_AU/main.lang b/htdocs/langs/en_AU/main.lang index f51ad592766..dac6a875c2d 100644 --- a/htdocs/langs/en_AU/main.lang +++ b/htdocs/langs/en_AU/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %I:%M %p FormatDateHourSecShort=%d/%m/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias ErrorNoVATRateDefinedForSellerCountry=Error, no GST rates defined for country '%s'. Quadri=Quarter PriceUTTC=U.P. (incl GST) diff --git a/htdocs/langs/en_AU/website.lang b/htdocs/langs/en_AU/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/en_AU/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_CA/admin.lang b/htdocs/langs/en_CA/admin.lang index a7c6cc9d271..62dd510c5e0 100644 --- a/htdocs/langs/en_CA/admin.lang +++ b/htdocs/langs/en_CA/admin.lang @@ -1,5 +1,4 @@ # Dolibarr language file - Source file is en_US - admin -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. LocalTax1Management=PST Management CompanyZip=Postal code LDAPFieldZip=Postal code diff --git a/htdocs/langs/en_CA/main.lang b/htdocs/langs/en_CA/main.lang index 7ce3e998978..6d4ce6e30f2 100644 --- a/htdocs/langs/en_CA/main.lang +++ b/htdocs/langs/en_CA/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d.%m.%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias ErrorNoVATRateDefinedForSellerCountry=Error, no vat rate defined for country '%s'. AmountVAT=Amount GST AmountLT1=Amount PST diff --git a/htdocs/langs/en_CA/website.lang b/htdocs/langs/en_CA/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/en_CA/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_GB/admin.lang b/htdocs/langs/en_GB/admin.lang index 1d26334c78d..11a52c3a368 100644 --- a/htdocs/langs/en_GB/admin.lang +++ b/htdocs/langs/en_GB/admin.lang @@ -20,7 +20,6 @@ ImportPostgreSqlDesc=To import a backup file, you must use the pg_restore comman CommandsToDisableForeignKeysForImportWarning=This is mandatory if you want to restore your sql dumps later ModulesMarketPlaceDesc=You can find more modules to download from external websites on the Internet... ModulesMarketPlaces=Find external applications and 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. AvailableOnlyIfJavascriptAndAjaxNotDisabled=Available only if JavaScript is enabled InstrucToEncodePass=To have password encoded into the conf.php file, replace the line
$dolibarr_main_db_pass="...";
with
$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:...";
with
$dolibarr_main_db_pass="%s"; diff --git a/htdocs/langs/en_GB/main.lang b/htdocs/langs/en_GB/main.lang index b712cacaa69..5617fe77778 100644 --- a/htdocs/langs/en_GB/main.lang +++ b/htdocs/langs/en_GB/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias ErrorNoVATRateDefinedForSellerCountry=Error, no VAT rates defined for country '%s'. NotAuthorized=You are not authorised to do that. BackgroundColorByDefault=Default background colour diff --git a/htdocs/langs/en_GB/website.lang b/htdocs/langs/en_GB/website.lang index f2cfbf3456c..ef8e16da6ad 100644 --- a/htdocs/langs/en_GB/website.lang +++ b/htdocs/langs/en_GB/website.lang @@ -1,3 +1,2 @@ # Dolibarr language file - Source file is en_US - website PageNameAliasHelp=Name or alias of the page.
This alias is also used to forge an SEO URL when the website is run from a Virtual host of a Web server (like Apache, Nginx, ...). Use the button "%s" to edit this alias. -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_IN/admin.lang b/htdocs/langs/en_IN/admin.lang index ebfc7deb6d3..4b3c42b80b1 100644 --- a/htdocs/langs/en_IN/admin.lang +++ b/htdocs/langs/en_IN/admin.lang @@ -1,5 +1,4 @@ # Dolibarr language file - Source file is en_US - admin -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. Module20Name=Quotations Module20Desc=Management of quotations Permission21=Read quotations diff --git a/htdocs/langs/en_IN/main.lang b/htdocs/langs/en_IN/main.lang index 15902ff1c4d..46aef779403 100644 --- a/htdocs/langs/en_IN/main.lang +++ b/htdocs/langs/en_IN/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %I:%M %p FormatDateHourSecShort=%d/%m/%Y %I:%M:%S %p FormatDateHourTextShort=%b %d, %Y, %I:%M %p FormatDateHourText=%B %d, %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias CommercialProposalsShort=Quotations LinkToProposal=Link to quotation SearchIntoCustomerProposals=Quotations diff --git a/htdocs/langs/en_IN/website.lang b/htdocs/langs/en_IN/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/en_IN/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_SG/admin.lang b/htdocs/langs/en_SG/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/en_SG/admin.lang +++ b/htdocs/langs/en_SG/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -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. 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. 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. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/en_SG/main.lang b/htdocs/langs/en_SG/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/en_SG/main.lang +++ b/htdocs/langs/en_SG/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/en_SG/website.lang b/htdocs/langs/en_SG/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/en_SG/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index 36098ab54c1..07961cadde4 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -409,7 +409,9 @@ 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 @@ -544,9 +546,9 @@ Module54Desc=Management of contracts (services or recurring subscriptions) Module55Name=Barcodes Module55Desc=Barcode 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=Bank Direct Debit payments -Module57Desc=Management of Direct Debit payment orders. It includes generation of SEPA file for European countries. +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, ...) Module59Name=Bookmark4u @@ -948,7 +950,8 @@ Permission63003=Delete resources Permission63004=Link resources to agenda events DictionaryCompanyType=Third-party types DictionaryCompanyJuridicalType=Third-party legal entities -DictionaryProspectLevel=Prospect potential +DictionaryProspectLevel=Prospect potential level for companies +DictionaryProspectContactLevel=Prospect potential level for contacts DictionaryCanton=States/Provinces DictionaryRegion=Regions DictionaryCountry=Countries @@ -978,7 +981,8 @@ DictionaryEMailTemplates=Email Templates DictionaryUnits=Units DictionaryMeasuringUnits=Measuring Units DictionarySocialNetworks=Social Networks -DictionaryProspectStatus=Prospect status +DictionaryProspectStatus=Prospect status for companies +DictionaryProspectContactStatus=Prospect status for contacts DictionaryHolidayTypes=Types of leave DictionaryOpportunityStatus=Lead status for project/lead DictionaryExpenseTaxCat=Expense report - Transportation categories @@ -1680,7 +1684,7 @@ AGENDA_USE_EVENT_TYPE=Use events types (managed in menu Setup -> Dictionaries -> 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 tab do you want to open by default when selecting menu Agenda +AGENDA_DEFAULT_VIEW=Which view do you want to open by default when selecting menu Agenda AGENDA_REMINDER_EMAIL=Enable event reminder by emails (remind option/delay can be defined on each event). Note: Module %s must be enabled and correctly setup to have reminder sent at the correct frequency. AGENDA_REMINDER_BROWSER=Enable event reminder on user's browser (when event date is reached, each user is able to refuse this from the browser confirmation question) AGENDA_REMINDER_BROWSER_SOUND=Enable sound notification @@ -1819,6 +1823,7 @@ EnterAnyCode=This field contains a reference to identify line. Enter any value o 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. @@ -1845,6 +1850,7 @@ MailToSendSupplierRequestForQuotation=Quotation request MailToSendSupplierOrder=Purchase orders MailToSendSupplierInvoice=Vendor invoices MailToSendContract=Contracts +MailToSendReception=Receptions MailToThirdparty=Third parties MailToMember=Members MailToUser=Users @@ -2008,3 +2014,6 @@ RssNote=Note: Each RSS feed definition provides a widget that you must enable to 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 \ No newline at end of file diff --git a/htdocs/langs/en_US/boxes.lang b/htdocs/langs/en_US/boxes.lang index bd62684421a..69025458630 100644 --- a/htdocs/langs/en_US/boxes.lang +++ b/htdocs/langs/en_US/boxes.lang @@ -83,6 +83,7 @@ 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 jobs ForCustomersInvoices=Customers invoices ForCustomersOrders=Customers orders ForProposals=Proposals diff --git a/htdocs/langs/en_US/cashdesk.lang b/htdocs/langs/en_US/cashdesk.lang index c7d7dd95cb7..73d8bdaa0df 100644 --- a/htdocs/langs/en_US/cashdesk.lang +++ b/htdocs/langs/en_US/cashdesk.lang @@ -117,3 +117,6 @@ HideCategoryImages=Hide Category Images HideProductImages=Hide Product Images NumberOfLinesToShow=Number of lines of images to show DefineTablePlan=Define tables plan +GiftReceiptButton=Gift receipt button +GiftReceipt=Gift receipt +ModuleReceiptPrinterMustBeEnabled=Module Receipt printer must have been enabled first diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index d52478dbbdb..61f936ad827 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -688,6 +688,7 @@ Method=Method Receive=Receive CompleteOrNoMoreReceptionExpected=Complete or nothing more expected ExpectedValue=Expected Value +ExpectedQty=Expected Qty PartialWoman=Partial TotalWoman=Total NeverReceived=Never received @@ -944,6 +945,39 @@ 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. diff --git a/htdocs/langs/en_US/other.lang b/htdocs/langs/en_US/other.lang index 5dc70fa068f..4555d3a6bc5 100644 --- a/htdocs/langs/en_US/other.lang +++ b/htdocs/langs/en_US/other.lang @@ -280,7 +280,9 @@ 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 the type of object to analyze... diff --git a/htdocs/langs/en_US/recruitment.lang b/htdocs/langs/en_US/recruitment.lang index 4e20a42fbb5..b4a7abbe825 100644 --- a/htdocs/langs/en_US/recruitment.lang +++ b/htdocs/langs/en_US/recruitment.lang @@ -51,4 +51,7 @@ ListOfPositionsToBeFilled=List of job offers to be filled NewPositionToBeFilled=New job offers to be filled JobOfferToBeFilled=Job offer to be filled -ThisIsInformationOnJobPosition=Information of the job position to be filled \ No newline at end of file +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 \ No newline at end of file diff --git a/htdocs/langs/en_US/stocks.lang b/htdocs/langs/en_US/stocks.lang index 994eae20e04..4098024f651 100644 --- a/htdocs/langs/en_US/stocks.lang +++ b/htdocs/langs/en_US/stocks.lang @@ -236,4 +236,5 @@ 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 future -CurrentStock=Current stock \ No newline at end of file +CurrentStock=Current stock +InventoryRealQtyHelp=Set value to 0 to reset qty
Keep field empty, or remove line, to keep unchanged \ No newline at end of file diff --git a/htdocs/langs/en_US/users.lang b/htdocs/langs/en_US/users.lang index aea757e4a15..37ad1c0fc0d 100644 --- a/htdocs/langs/en_US/users.lang +++ b/htdocs/langs/en_US/users.lang @@ -117,3 +117,4 @@ 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 \ No newline at end of file diff --git a/htdocs/langs/en_US/withdrawals.lang b/htdocs/langs/en_US/withdrawals.lang index 662c587108a..553e3ac0eaa 100644 --- a/htdocs/langs/en_US/withdrawals.lang +++ b/htdocs/langs/en_US/withdrawals.lang @@ -63,7 +63,9 @@ 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 @@ -77,13 +79,13 @@ 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 (all) +CreateFileForPaymentByBankTransfer=Create file for credit transfer CreateSepaFileForPaymentByBankTransfer=Create credit transfer file (SEPA) CreateGuichet=Only office CreateBanque=Only bank OrderWaiting=Waiting for treatment -NotifyTransmision=File transmission -NotifyCredit=Withdrawal Credit +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 @@ -143,3 +145,4 @@ 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. \ No newline at end of file diff --git a/htdocs/langs/es_AR/main.lang b/htdocs/langs/es_AR/main.lang index 7f068578411..6bcf44704f7 100644 --- a/htdocs/langs/es_AR/main.lang +++ b/htdocs/langs/es_AR/main.lang @@ -22,7 +22,6 @@ FormatDateHourText=%B %d, %Y, %I:%M %p DatabaseConnection=Conexión de base de datos NoTemplateDefined=No hay plantilla para este tipo de email AvailableVariables=Variables disponibles de substitución -EmptySearchString=Enter non empty search criterias NoRecordFound=Sin registros NoRecordDeleted=Sin registros eliminados NotEnoughDataYet=Sin datos suficientes diff --git a/htdocs/langs/es_BO/main.lang b/htdocs/langs/es_BO/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/es_BO/main.lang +++ b/htdocs/langs/es_BO/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_CL/main.lang b/htdocs/langs/es_CL/main.lang index 0c12ed62b34..e6342fa3f44 100644 --- a/htdocs/langs/es_CL/main.lang +++ b/htdocs/langs/es_CL/main.lang @@ -22,7 +22,6 @@ FormatDateHourText=%d %B %Y %H:%M DatabaseConnection=Conexión a la base NoTemplateDefined=No hay plantilla disponible para este tipo de correo electrónico AvailableVariables=Variables de sustitución disponibles -EmptySearchString=Enter non empty search criterias NoRecordFound=Ningún record fue encontrado NoRecordDeleted=No se eliminó ningún registro NoError=No hay error diff --git a/htdocs/langs/es_CL/stocks.lang b/htdocs/langs/es_CL/stocks.lang index ffd436fb51a..ba63c7f81bf 100644 --- a/htdocs/langs/es_CL/stocks.lang +++ b/htdocs/langs/es_CL/stocks.lang @@ -66,7 +66,6 @@ IdWarehouse=Id almacén LieuWareHouse=Almacén de localización WarehousesAndProductsBatchDetail=Almacenes y productos (con detalle por lote / serie) AverageUnitPricePMPShort=Precio de entrada promedio ponderado -AverageUnitPricePMP=Precio de entrada promedio ponderado SellPriceMin=Precio unitario de venta EstimatedStockValueSellShort=Valor para la venta EstimatedStockValueSell=Valor para la venta diff --git a/htdocs/langs/es_CO/main.lang b/htdocs/langs/es_CO/main.lang index 038f333d9ea..8db201ad380 100644 --- a/htdocs/langs/es_CO/main.lang +++ b/htdocs/langs/es_CO/main.lang @@ -21,7 +21,6 @@ FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M NoTemplateDefined=No hay plantilla disponible para este tipo de correo electrónico. AvailableVariables=Variables de sustitución disponibles -EmptySearchString=Enter non empty search criterias NoRecordFound=No se encontraron registros NoRecordDeleted=Ningún registro eliminado Errors=Los errores diff --git a/htdocs/langs/es_DO/main.lang b/htdocs/langs/es_DO/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/es_DO/main.lang +++ b/htdocs/langs/es_DO/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_EC/main.lang b/htdocs/langs/es_EC/main.lang index 2dd7a66de05..3227c745a02 100644 --- a/htdocs/langs/es_EC/main.lang +++ b/htdocs/langs/es_EC/main.lang @@ -22,7 +22,6 @@ FormatDateHourText=%d %B %Y %H:%M DatabaseConnection=Conexión con la base de datos NoTemplateDefined=No hay plantilla disponible para este tipo de correo electrónico AvailableVariables=Variables de sustitución disponibles -EmptySearchString=Enter non empty search criterias NoRecordFound=Ningún registro encontrado NoRecordDeleted=Ningún registro eliminado NoError=No hay error diff --git a/htdocs/langs/es_EC/stocks.lang b/htdocs/langs/es_EC/stocks.lang index 88ed5a7e742..c8f3a1758af 100644 --- a/htdocs/langs/es_EC/stocks.lang +++ b/htdocs/langs/es_EC/stocks.lang @@ -72,7 +72,6 @@ DescWareHouse=Descripción de almacén LieuWareHouse=Almacén de localización WarehousesAndProductsBatchDetail=Almacenes y productos (con detalle por lote / serie) AverageUnitPricePMPShort=Precio medio ponderado de los insumos -AverageUnitPricePMP=Precio medio ponderado de los insumos SellPriceMin=Precio unitario de venta EstimatedStockValueSellShort=Valor para la venta EstimatedStockValueSell=Valor para la venta diff --git a/htdocs/langs/es_GT/main.lang b/htdocs/langs/es_GT/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/es_GT/main.lang +++ b/htdocs/langs/es_GT/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_HN/main.lang b/htdocs/langs/es_HN/main.lang index 7579f1f4693..0d6b013ca18 100644 --- a/htdocs/langs/es_HN/main.lang +++ b/htdocs/langs/es_HN/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_MX/main.lang b/htdocs/langs/es_MX/main.lang index 7405807c6c8..1b7e397c375 100644 --- a/htdocs/langs/es_MX/main.lang +++ b/htdocs/langs/es_MX/main.lang @@ -20,7 +20,6 @@ FormatDateHourSecShort=%I:%M:%S %p %d/%m/%Y FormatDateHourTextShort=%I:%M %p, %d %b %Y FormatDateHourText=%I:%M %p, %d %B %Y AvailableVariables=Variables de sustitución disponibles -EmptySearchString=Enter non empty search criterias NoRecordFound=Ningún registro fue encontrado NoError=No hay error ErrorFieldFormat=El campo '%s' contiene un valor incorrecto diff --git a/htdocs/langs/es_PA/main.lang b/htdocs/langs/es_PA/main.lang index bcdd3f914eb..1602d6a7ffa 100644 --- a/htdocs/langs/es_PA/main.lang +++ b/htdocs/langs/es_PA/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_PE/main.lang b/htdocs/langs/es_PE/main.lang index 7140f0a388b..aa60b7d10cc 100644 --- a/htdocs/langs/es_PE/main.lang +++ b/htdocs/langs/es_PE/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias NoError=Sin error ErrorNoVATRateDefinedForSellerCountry=Error, no hay tipos de IGV definidos para el país '%s'. NotClosed=No se ha cerrado diff --git a/htdocs/langs/es_PY/main.lang b/htdocs/langs/es_PY/main.lang index bcdd3f914eb..1602d6a7ffa 100644 --- a/htdocs/langs/es_PY/main.lang +++ b/htdocs/langs/es_PY/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_US/main.lang b/htdocs/langs/es_US/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/es_US/main.lang +++ b/htdocs/langs/es_US/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_UY/main.lang b/htdocs/langs/es_UY/main.lang index bcdd3f914eb..1602d6a7ffa 100644 --- a/htdocs/langs/es_UY/main.lang +++ b/htdocs/langs/es_UY/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/es_VE/main.lang b/htdocs/langs/es_VE/main.lang index 1785d537814..1de75d20c42 100644 --- a/htdocs/langs/es_VE/main.lang +++ b/htdocs/langs/es_VE/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias DateEnd=Fecha finalización AmountLT1ES=Importe de retención AmountLT2ES=Importe ISLR diff --git a/htdocs/langs/fr_BE/admin.lang b/htdocs/langs/fr_BE/admin.lang index 3d058e6b61d..5d24a311ccd 100644 --- a/htdocs/langs/fr_BE/admin.lang +++ b/htdocs/langs/fr_BE/admin.lang @@ -14,7 +14,6 @@ WarningModuleNotActive=Le module %s doit être activé WarningOnlyPermissionOfActivatedModules=Seules les permissions liées à des modules activés sont montrées ici. Vous pouvez activer d'autres modules sur la page Accueil->Configuration->Modules. FormToTestFileUploadForm=Formulaire pour tester l'upload de fichiers (selon la configuration) IfModuleEnabled=Note: oui ne fonctionne que si le module %s est activé -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. Module20Name=Propales Module30Name=Factures Target=Objectif diff --git a/htdocs/langs/fr_BE/main.lang b/htdocs/langs/fr_BE/main.lang index e425c275844..3042af1642f 100644 --- a/htdocs/langs/fr_BE/main.lang +++ b/htdocs/langs/fr_BE/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d/%m/%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias Update=Mise à jour DateStart=Date de début DateEnd=Date de fin diff --git a/htdocs/langs/fr_BE/website.lang b/htdocs/langs/fr_BE/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_BE/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_CA/admin.lang b/htdocs/langs/fr_CA/admin.lang index 09df3da74ad..88e376626be 100644 --- a/htdocs/langs/fr_CA/admin.lang +++ b/htdocs/langs/fr_CA/admin.lang @@ -39,7 +39,6 @@ CompatibleAfterUpdate=Ce module nécessite une mise à jour de votre Dolibarr %s SeeInMarkerPlace=Voir dans Market place Updated=Mis à jour AchatTelechargement=Acheter / Télécharger -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. DevelopYourModuleDesc=Quelques solutions pour développer votre propre module ... InstrucToEncodePass=Pour chiffrer le mot de passe de la base dans le fichier de configuration conf.php, remplacer la ligne
$dolibarr_main_db_pass="...";
par
$dolibarr_main_db_pass="crypted:%s"; InstrucToClearPass=Pour avoir le mot de passe de la base décodé (en clair) dans le fichier de configuration conf.php, remplacer dans ce fichier la ligne
$dolibarr_main_db_pass="crypted:..."
par
$dolibarr_main_db_pass="%s" diff --git a/htdocs/langs/fr_CA/main.lang b/htdocs/langs/fr_CA/main.lang index 0da76b0aab2..6914f73c3a7 100644 --- a/htdocs/langs/fr_CA/main.lang +++ b/htdocs/langs/fr_CA/main.lang @@ -20,7 +20,6 @@ FormatDateHourSecShort=%d/%m/%Y %H:%M:%S FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M DatabaseConnection=Connexion à la base de donnée -EmptySearchString=Enter non empty search criterias ErrorCanNotCreateDir=Impossible de créer le dir %s ErrorCanNotReadDir=Impossible de lire le dir %s ErrorNoSocialContributionForSellerCountry=Erreur, aucun type de charges défini pour le pays '%s'. diff --git a/htdocs/langs/fr_CA/stocks.lang b/htdocs/langs/fr_CA/stocks.lang index 8c85ddc91fd..b94830980a7 100644 --- a/htdocs/langs/fr_CA/stocks.lang +++ b/htdocs/langs/fr_CA/stocks.lang @@ -36,7 +36,6 @@ IdWarehouse=Id entrepôt LieuWareHouse=Entrepôt de localisation WarehousesAndProductsBatchDetail=Entrepôts et produits (avec détail par lot / série) AverageUnitPricePMPShort=Prix ​​moyen pondéré des intrants -AverageUnitPricePMP=Prix ​​moyen pondéré des intrants SellPriceMin=Prix ​​unitaire de vente EstimatedStockValueSellShort=Valeur à vendre EstimatedStockValueSell=Valeur à vendre diff --git a/htdocs/langs/fr_CA/website.lang b/htdocs/langs/fr_CA/website.lang index f6c1b71c174..5255b2f9da5 100644 --- a/htdocs/langs/fr_CA/website.lang +++ b/htdocs/langs/fr_CA/website.lang @@ -7,4 +7,3 @@ EditMenu=Menu Edition ViewSiteInNewTab=Afficher le site dans un nouvel onglet ViewPageInNewTab=Afficher la page dans un nouvel onglet ViewWebsiteInProduction=Afficher le site Web à l'aide d'URL d'accueil -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_CH/admin.lang b/htdocs/langs/fr_CH/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/fr_CH/admin.lang +++ b/htdocs/langs/fr_CH/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -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. 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. 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. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/fr_CH/main.lang b/htdocs/langs/fr_CH/main.lang index 75d787bb95c..65f49b2ef5e 100644 --- a/htdocs/langs/fr_CH/main.lang +++ b/htdocs/langs/fr_CH/main.lang @@ -19,4 +19,3 @@ FormatDateHourShort=%d/%m/%Y %I:%M %p FormatDateHourSecShort=%d/%m/%Y %I:%M:%S %p FormatDateHourTextShort=%d %b %Y, %I:%M %p FormatDateHourText=%d %B %Y, %I:%M %p -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/fr_CH/website.lang b/htdocs/langs/fr_CH/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_CH/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_CI/admin.lang b/htdocs/langs/fr_CI/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/fr_CI/admin.lang +++ b/htdocs/langs/fr_CI/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -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. 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. 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. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/fr_CI/main.lang b/htdocs/langs/fr_CI/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/fr_CI/main.lang +++ b/htdocs/langs/fr_CI/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/fr_CI/website.lang b/htdocs/langs/fr_CI/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_CI/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_CM/admin.lang b/htdocs/langs/fr_CM/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/fr_CM/admin.lang +++ b/htdocs/langs/fr_CM/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -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. 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. 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. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/fr_CM/main.lang b/htdocs/langs/fr_CM/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/fr_CM/main.lang +++ b/htdocs/langs/fr_CM/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/fr_CM/website.lang b/htdocs/langs/fr_CM/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_CM/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index c4025fb1577..236b4c61bd9 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -300,8 +300,9 @@ MAIN_MAIL_DEFAULT_FROMTYPE=Expéditeur par défaut des e-mails pour les envois m UserEmail=Email utilisateur CompanyEmail=Email organization FeatureNotAvailableOnLinux=Fonctionnalité non disponible sous systèmes Unix. Tester votre sendmail localement. +FixOnTransifex=Corriger la traduction sur la plate-forme en ligne de traduction du projet SubmitTranslation=Si la traduction de cette langue est incomplète ou si vous trouvez des erreurs, vous pouvez corriger cela en éditant les fichiers dans le répertoire langs/%s et soumettre vos changements sur www.transifex.com/dolibarr-association/dolibarr/ -SubmitTranslationENUS=Si la traduction pour cette langue est incomplète ou si vous trouvez des erreurs, vous pouvez les corriger en éditant les fichiers dans le répertoire langs/%s et soumettre les modifications sur le forum dolibarr.org/forum ou pour les développeurs sur github.com/Dolibarr/dolibarr. +SubmitTranslationENUS=Si la traduction pour cette langue est incomplète ou si vous trouvez des erreurs, vous pouvez les corriger en éditant les fichiers dans le dossier langs/%s et soumettre les fichiers modifiés sur le forum dolibarr.org/forum ou, pour les développeurs, via une PR sur github.com/Dolibarr/dolibarr ModuleSetup=Configuration du module ModulesSetup=Configuration Modules/Application ModuleFamilyBase=Système @@ -387,7 +388,7 @@ SecurityToken=Clé de sécurisation des URLs NoSmsEngine=Aucun gestionnaire d'envoi de SMS n'est disponible. Les gestionnaires d'envois SMS ne sont pas installés en standard, car dépendent d'un fournisseur externe, mais vous pourrez en trouver depuis la plateforme %s PDF=PDF PDFDesc=Options globales sur la génération des PDF -PDFAddressForging=Règles de fabrication des zones adresses +PDFAddressForging=Règles pour le contenu des sections Adresse HideAnyVATInformationOnPDF=Masquer toutes les informations relatives à la Taxe de vente / TVA sur les PDF générés PDFRulesForSalesTax=Règles pour la taxe de vente / TVA PDFLocaltax=Règles pour %s @@ -947,7 +948,8 @@ Permission63003=Supprimer les ressources Permission63004=Lier les ressources aux événements de l'agenda DictionaryCompanyType=Type de Tiers DictionaryCompanyJuridicalType=Formes juridiques des Tiers -DictionaryProspectLevel=Niveau de potentiel des prospects +DictionaryProspectLevel=Niveau de potentiel des prospects pour les tiers +DictionaryProspectContactLevel=Niveau de potentiel des prospects pour les contacts DictionaryCanton=Etats/Province DictionaryRegion=Régions DictionaryCountry=Pays @@ -977,7 +979,8 @@ DictionaryEMailTemplates=Modèles des courriels DictionaryUnits=Unités DictionaryMeasuringUnits=Unités de mesure DictionarySocialNetworks=Réseaux sociaux -DictionaryProspectStatus=Statut prospect +DictionaryProspectStatus=Statuts de prospection des tiers +DictionaryProspectContactStatus=Statuts de prospection des contacts DictionaryHolidayTypes=Type de congés DictionaryOpportunityStatus=Statut d'opportunités pour les affaires/projets DictionaryExpenseTaxCat=Note de frais - catégories de déplacement @@ -1240,6 +1243,7 @@ WarningAtLeastKeyOrTranslationRequired=Un critère de recherche est nécessaire NewTranslationStringToShow=Nouvelle traduction à afficher OriginalValueWas=La traduction d'origine est écrasée. La valeur initiale était:

%s TransKeyWithoutOriginalValue=Vous avez forcé une nouvelle traduction pour la clé de traduction '%s' qui n'existe dans aucun fichier de langue +TitleNumberOfActivatedModules=Modules activés TotalNumberOfActivatedModules=Modules activés : %s / %s YouMustEnableOneModule=Vous devez activer au moins une fonctionnalité ClassNotFoundIntoPathWarning=La classe %s n'a pas été trouvée dans le chemin PHP @@ -1686,8 +1690,8 @@ AGENDA_SHOW_LINKED_OBJECT=Afficher l'objet lié dans la vue agenda ##### Clicktodial ##### 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. Un clic sur cette icône appellera votre téléphone à composer le numéro de téléphone. Cela peut être utilisé pour appeler un système de centre d'appels de Dolibarr qui peut appeler le numéro de téléphone d'un système SIP, par exemple. -ClickToDialUseTelLink=Utiliser un lien «Tel.» sur les numéros de téléphone +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=Utilisez cette méthode si vos utilisateurs ont un softphone ou une interface de logiciel installé sur un même ordinateur que le navigateur, et a appelé lorsque vous cliquez sur un lien dans votre navigateur qui commencent par "tel:". Si vous avez besoin d'une solution de serveur complet (pas besoin d'installation locale du logiciel), vous devez définir ceci à "Non" et remplir le champ suivant. ##### Point Of Sale (CashDesk) ##### CashDesk=Point de Vente @@ -1817,6 +1821,7 @@ EnterAnyCode=Ce champ contient une référence pour identifier le champ. Entrez Enter0or1=Saisir 0 ou 1  UnicodeCurrency=Saisissez ici entre accolades, la liste du numéro des octets qui représentent le symbole de la monnaie. Pour exemple: pour $, entrez [36] - pour le Real Brésilien R$ [82,36] - pour l'euro €, entrez [8364] ColorFormat=La couleur RVB au format HEX est, par exemple: FF0000 +PictoHelp=Nom de l'icone au format dolibarr ('image.png' si mise dans le répertoire du thème actuel, 'image.png@nom_du_module' si mise dans le repertoire /img/ d'un module) PositionIntoComboList=Position de la ligne dans des listes déroulantes 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. @@ -1881,7 +1886,7 @@ UrlToGetKeyToUseAPIs=Url pour obtenir le jeton pour utiliser l'API (une fois le ListOfAvailableAPIs=Liste des APIs disponibles activateModuleDependNotSatisfied=Le module "%s" dépend du module "%s" qui est manquant, aussi le module "%1$s" peut ne pas fonctionner correctement. Merci d'installer le module "%2$s" ou désactiver le module "%1$s" si vous ne souhaitez pas avoir de mauvaise surprise CommandIsNotInsideAllowedCommands=La commande que vous essayez d'exécuter ne figure pas dans la liste des commandes autorisées définies dans le paramètre $dolibarr_main_restrict_os_commands du fichier conf.php . -LandingPage=Page cible +LandingPage=Page d'accueil SamePriceAlsoForSharedCompanies=Si vous utilisez un module multi-société, avec le choix «prix unique», le prix sera aussi le même pour toutes les sociétés si les produits sont partagés entre les environnements ModuleEnabledAdminMustCheckRights=Le module a été activé. Les permissions pour le(s) module(s) activé(s) ont été donnés aux utilisateurs admin uniquement. Vous devrez peut-être accorder des autorisations aux autres utilisateurs ou groupes manuellement si nécessaire. UserHasNoPermissions=Cet utilisateur n'a pas de permission définie @@ -1894,6 +1899,7 @@ MAIN_PDF_MARGIN_LEFT=Marge gauche sur les PDF MAIN_PDF_MARGIN_RIGHT=Marge droite sur les PDF 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 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 EnterCalculationRuleIfPreviousFieldIsYes=Entrez la règle de calcul si le champ précédent a été défini sur Oui (par exemple, 'CODEGRP1 + CODEGRP2') diff --git a/htdocs/langs/fr_FR/agenda.lang b/htdocs/langs/fr_FR/agenda.lang index 2e0ac6e5ed1..6da45f7976d 100644 --- a/htdocs/langs/fr_FR/agenda.lang +++ b/htdocs/langs/fr_FR/agenda.lang @@ -14,7 +14,7 @@ EventsNb=Nombre d'événements ListOfActions=Liste des événements EventReports=Rapport des évènements Location=Lieu -ToUserOfGroup=à tout utilisateur du groupe +ToUserOfGroup=Assigné à tout utilisateur du groupe EventOnFullDay=Événement sur la(les) journée(s) MenuToDoActions=Événements incomplets MenuDoneActions=Événements terminés @@ -121,10 +121,10 @@ MRP_MO_CANCELInDolibarr=OF annulé AgendaModelModule=Modèle de document pour les événements DateActionStart=Date de début DateActionEnd=Date de fin -AgendaUrlOptions1=Vous pouvez aussi ajouter les paramètres suivants pour filtrer les réponses : +AgendaUrlOptions1=Vous pouvez aussi ajouter les paramètres suivants pour filtrer les réponses : AgendaUrlOptions3=logina=%s pour limiter l'export aux actions dont l'utilisateur %s est propriétaire. -AgendaUrlOptionsNotAdmin=logina=!%s pour limiter l'export aux actions non assignées à l'utilisateur %s. -AgendaUrlOptions4=logint=%s pour limiter l'export aux actions assignées à l'utilisateur %s (propriétaire et autres). +AgendaUrlOptionsNotAdmin=logina=!%s pour limiter l'export aux actions n'appartenant pas à l'utilisateur %s. +AgendaUrlOptions4=logint=%spour limiter l'export aux actions assignées à l'utilisateur %s (propriétaire et autres). AgendaUrlOptionsProject=project=__PROJECT_ID__ pour restreindre aux événements associés au projet __PROJECT_ID__. AgendaUrlOptionsNotAutoEvent=notactiontype=systemauto pour exclure les événements automatiques. AgendaUrlOptionsIncludeHolidays=includeholidays=1 pour inclure les événements de type congé. diff --git a/htdocs/langs/fr_FR/cashdesk.lang b/htdocs/langs/fr_FR/cashdesk.lang index 8ed5994e3f3..2ab64973e1a 100644 --- a/htdocs/langs/fr_FR/cashdesk.lang +++ b/htdocs/langs/fr_FR/cashdesk.lang @@ -115,5 +115,5 @@ ScanToOrder=Scannez le code QR pour commander Appearance=Apparence HideCategoryImages=Masquer les images de catégorie HideProductImages=Masquer les images de produits -NumberOfLinesToShow=Nombre de lignes d'image à afficher +NumberOfLinesToShow=Nombre de lignes d'images à afficher DefineTablePlan=Définir le plan des tables diff --git a/htdocs/langs/fr_FR/compta.lang b/htdocs/langs/fr_FR/compta.lang index 6245901d321..bc79d32d709 100644 --- a/htdocs/langs/fr_FR/compta.lang +++ b/htdocs/langs/fr_FR/compta.lang @@ -69,6 +69,7 @@ SocialContribution=Charge sociale ou fiscale SocialContributions=Charges fiscales ou sociales SocialContributionsDeductibles=Charge ou taxe déductible SocialContributionsNondeductibles=Charge ou taxe non déductible +DateOfSocialContribution=Date de la charge fiscale ou sociale LabelContrib=Libellé de la dépense TypeContrib=Type de la charge MenuSpecialExpenses=Dépenses spéciales diff --git a/htdocs/langs/fr_FR/contracts.lang b/htdocs/langs/fr_FR/contracts.lang index f2910a8e76e..1d6a99378d3 100644 --- a/htdocs/langs/fr_FR/contracts.lang +++ b/htdocs/langs/fr_FR/contracts.lang @@ -99,6 +99,6 @@ TypeContact_contrat_internal_SALESREPFOLL=Commercial suivi du contrat TypeContact_contrat_external_BILLING=Contact client facturation contrat TypeContact_contrat_external_CUSTOMER=Contact client suivi contrat TypeContact_contrat_external_SALESREPSIGN=Contact client signataire contrat -HideClosedServiceByDefault=Cacher les services fermés sur les contrats par défaut +HideClosedServiceByDefault=Masquer les services fermés par défaut ShowClosedServices=Afficher les services fermés -HideClosedServices=Cacher les services fermés +HideClosedServices=Masquer les services fermés diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index 5bfcd36ce0b..4080466f427 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -136,7 +136,8 @@ ErrorNewValueCantMatchOldValue=La nouvelle valeur ne peut être égale à l'anci ErrorFailedToValidatePasswordReset=Echec de la réinitialisation du mot de passe. Il est possible que ce lien ait déjà été utilisé (l'utilisation de ce lien ne fonctionne qu'une fois). Si ce n'est pas le cas, essayez de recommencer le processus de réinitialisation de mot de passe depuis le début. ErrorToConnectToMysqlCheckInstance=Echec de la connection au serveur de base de données. Vérifier que votre serveur est bien lancé (par exemple, avec MySQL/MariaDB, vous pouvez le lancer depuis la ligne de commande avec 'sudo service mysql start'). ErrorFailedToAddContact=Echec à l'ajout du contact -ErrorDateMustBeBeforeToday=La date ne peut pas être supérieure à aujourd'hui +ErrorDateMustBeBeforeToday=La date doit être inférieure à la date courante +ErrorDateMustBeInFuture=La date doit être postérieure à la date courante ErrorPaymentModeDefinedToWithoutSetup=Un mode de paiement a été défini de type %s mais la configuration du module Facture n'a pas été complétée pour définir les informations affichées pour ce mode de paiement. ErrorPHPNeedModule=Erreur, votre PHP doit avoir le module %s installé pour utiliser cette fonctionnalité. ErrorOpenIDSetupNotComplete=Vous avez configuré Dolibarr pour accepter l'authentication OpenID, mais l'URL du service OpenID n'est pas défini dans la constante %s diff --git a/htdocs/langs/fr_FR/languages.lang b/htdocs/langs/fr_FR/languages.lang index 9da1ef41151..9a980afffe8 100644 --- a/htdocs/langs/fr_FR/languages.lang +++ b/htdocs/langs/fr_FR/languages.lang @@ -1,8 +1,11 @@ # Dolibarr language file - Source file is en_US - languages +Language_am_ET=Ethiopien Language_ar_AR=Arabe Language_ar_EG=Arabe (Egypte) Language_ar_SA=Arabe +Language_az_AZ=Azerbaïdjanais Language_bn_BD=Bengalais +Language_bn_IN=Bengali (Inde) Language_bg_BG=Bulgare Language_bs_BA=Bosniaque Language_ca_ES=Catalan @@ -20,6 +23,7 @@ Language_en_GB=Anglais (Royaume-Uni) Language_en_IN=Anglais (Inde) Language_en_NZ=Anglais (Nouvelle Zeland) Language_en_SA=Anglais (Arabie Saoudite) +Language_en_SG=Anglais (Singapour) Language_en_US=Anglais (Etats-Unis) Language_en_ZA=Anglais (Afrique du Sud) Language_es_ES=Espagnol @@ -29,6 +33,7 @@ Language_es_CL=Espagnol (Chili) Language_es_CO=Espagnol (Colombie) Language_es_DO=Espagnol (République dominicaine) Language_es_EC=Espagnol (Équateur) +Language_es_GT=Espagnol (Guatemala) Language_es_HN=Espagnol (Honduras) Language_es_MX=Espagnol (Mexique) Language_es_PA=Espagnol (Panama) @@ -36,6 +41,7 @@ Language_es_PY=Espagnol (Paraguay) Language_es_PE=Espagnol (Peru) Language_es_PR=Espagnol (Puerto Rico) Language_es_UY=Espagnol (Uruguay) +Language_es_GT=Espagnol (Guatemala) Language_es_VE=Espagnol (Venezuela) Language_et_EE=Estonien Language_eu_ES=Basque @@ -44,15 +50,21 @@ Language_fi_FI=Finlandais Language_fr_BE=Français (Belgique) Language_fr_CA=Français (Canada) Language_fr_CH=Français (Suisse) +Language_fr_CI=Français (Cote d'Ivoire) +Language_fr_CM=Français (Cameroun) Language_fr_FR=Français +Language_fr_GA=Français (Gabon) Language_fr_NC=Français (Nouvelle Calédonie) Language_fy_NL=Frisian +Language_gl_ES=Galicien Language_he_IL=Hébreux +Language_hi_IN=Hindi (Inde) Language_hr_HR=Croate Language_hu_HU=Hongrois Language_id_ID=Indonésien Language_is_IS=Islandais Language_it_IT=Italien +Language_it_CH=Italien (Suisse) Language_ja_JP=Japonais Language_ka_GE=Géorgien Language_km_KH=Khmer @@ -64,8 +76,9 @@ Language_lv_LV=Léton Language_mk_MK=Macédonien Language_mn_MN=Mongol Language_nb_NO=Norvégien (Bokmal) +Language_ne_NP=Népalais Language_nl_BE=Néerlandais (Belgique) -Language_nl_NL=Dutch +Language_nl_NL=Néerlandais Language_pl_PL=Polonais Language_pt_BR=Portugais (Brésil) Language_pt_PT=Portugais @@ -86,4 +99,5 @@ Language_uz_UZ=Ouzbek Language_vi_VN=Vietnamien Language_zh_CN=Chinois Language_zh_TW=Chinois (Traditionel) +Language_zh_HK=Chinois (Hong-Kong) Language_bh_MY=Malais diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang index 670a486345c..bea3097d2ff 100644 --- a/htdocs/langs/fr_FR/main.lang +++ b/htdocs/langs/fr_FR/main.lang @@ -485,6 +485,7 @@ Categories=Tags/catégories Category=Tag/catégorie By=Par From=Du +FromDate=A partir du FromLocation=A partir du to=au To=au @@ -703,6 +704,7 @@ MenuECM=Documents MenuAWStats=AWStats MenuMembers=Adhérents MenuAgendaGoogle=Agenda Google +MenuTaxesAndSpecialExpenses=Charges | Dépenses spéciales ThisLimitIsDefinedInSetup=Limite Dolibarr (Menu accueil-configuration-sécurité): %s Ko, Limite PHP: %s Ko NoFileFound=Pas de documents stockés dans cette rubrique CurrentUserLanguage=Langue utilisateur actuelle @@ -1039,3 +1041,6 @@ SwitchInEditModeToAddTranslation=Passer en mode édition pour ajouter des traduc NotUsedForThisCustomer=Non utilisé pour ce client AmountMustBePositive=Le montant doit être positif. ByStatus=Par statut +InformationMessage=Information +ASAP=Dès que possible + diff --git a/htdocs/langs/fr_FR/other.lang b/htdocs/langs/fr_FR/other.lang index 09c378008f3..bd75f6c9035 100644 --- a/htdocs/langs/fr_FR/other.lang +++ b/htdocs/langs/fr_FR/other.lang @@ -280,7 +280,9 @@ LinesToImport=Lignes à importer MemoryUsage=Utilisation de la mémoire RequestDuration=Durée de la demande +ProductsPerPopularity=Produits / services par popularité PopuProp=Produits / services par popularité dans les propositions PopuCom=Produits/services par popularité dans les commandes ProductStatistics=Statistiques sur les produits / services NbOfQtyInOrders=Qté en commandes +SelectTheTypeOfObjectToAnalyze=Sélectionnez le type d'objet à analyser ... diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 8366e029c2f..09c470552e5 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -169,6 +169,8 @@ SuppliersPricesOfProductsOrServices=Prix fournisseurs (des produits ou services) CustomCode=Nomenclature douanière / Code SH CountryOrigin=Pays d'origine Nature=Nature du produit (matière première / produit fini) +NatureOfProductShort=Nature de produit +NatureOfProductDesc=Matière première ou produit fini ShortLabel=Libellé court Unit=Unité p=u. diff --git a/htdocs/langs/fr_FR/projects.lang b/htdocs/langs/fr_FR/projects.lang index c521a0a965a..fda884c6203 100644 --- a/htdocs/langs/fr_FR/projects.lang +++ b/htdocs/langs/fr_FR/projects.lang @@ -178,6 +178,7 @@ TypeContact_project_task_internal_TASKCONTRIBUTOR=Contributeur TypeContact_project_task_external_TASKCONTRIBUTOR=Contributeur SelectElement=Séléctionnez l'élément AddElement=Associer l'élément +LinkToElementShort=Lier à # Documents models DocumentModelBeluga=Modèle de document project pour l'aperçu des objets liées DocumentModelBaleine=Modèles de document de rapport de tâches de projets diff --git a/htdocs/langs/fr_FR/recruitment.lang b/htdocs/langs/fr_FR/recruitment.lang new file mode 100644 index 00000000000..d95d76cd421 --- /dev/null +++ b/htdocs/langs/fr_FR/recruitment.lang @@ -0,0 +1,54 @@ +# 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 = Recrutement +# Module description 'ModuleRecruitmentDesc' +ModuleRecruitmentDesc = Gestion et suivi des campagnes de recrutement + +# +# Admin page +# +RecruitmentSetup = Paramétrages du recrutement +Settings = Paramétrages +RecruitmentSetupPage = Entrez ici la configuration des principales options du module de recrutement +RecruitmentArea=Espace recrutement +PublicInterfaceRecruitmentDesc=L'interface publique est une URL publique pour afficher et répondre aux postes en cours de recrutement. Il existe un lien différent pour chaque poste. +EnablePublicRecruitmentPages=Activer les pages de recrutement publiques + +# +# About page +# +About = À propos +RecruitmentAbout = À propos du module Recrutement +RecruitmentAboutPage = À propos du module Recrutement +NbOfEmployeesExpected=Nombre de postes disponibles +JobLabel=Intitulé du poste +WorkPlace=Poste de travail +DateExpected=Date souhaitée +FutureManager=Responsable futur +ResponsibleOfRecruitement=Responsable du recrutement +IfJobIsLocatedAtAPartner=Si le poste est localisé chez un partenaire +PositionToBeFilled=Poste à pourvoir +PositionsToBeFilled=Postes à pourvoir +ListOfPositionsToBeFilled=Liste des postes à pourvoir +NewPositionToBeFilled=Nouveau poste à pourvoir + +JobOfferToBeFilled=Poste à pourvoir +ThisIsInformationOnJobPosition=Informations sur le poste à pourvoir diff --git a/htdocs/langs/fr_FR/stocks.lang b/htdocs/langs/fr_FR/stocks.lang index fa44e8e1172..dc1428b6e19 100644 --- a/htdocs/langs/fr_FR/stocks.lang +++ b/htdocs/langs/fr_FR/stocks.lang @@ -95,14 +95,16 @@ RealStock=Stock réel RealStockDesc=Le stock physique ou réel est le stock présent dans les entrepôts. RealStockWillAutomaticallyWhen=Le stock réel sera modifié selon ces règles (voir la configuration du module Stock) : VirtualStock=Stock virtuel -VirtualStockDesc=Le stock virtuel est la quantité de produit en stock après que les opération affectant les stock sont terminées (réceptions de commandes fournisseurs, expéditions de commandes clients,...) +VirtualStockAtDate=Stock virtuel à date +VirtualStockAtDateDesc=Stock virtuel une fois que toutes les commandes en attente qui doivent être effectuées avant la date seront terminées +VirtualStockDesc=Le stock virtuel est la quantité de produit en stock après que les opérations en cours (et qui affectent les stocks) soient terminées (réceptions de commandes fournisseurs, expéditions de commandes clients, production des ordres de fabrications, etc) IdWarehouse=Identifiant entrepôt DescWareHouse=Description entrepôt LieuWareHouse=Lieu entrepôt WarehousesAndProducts=Entrepôts et produits WarehousesAndProductsBatchDetail=Entrepôts et produits (avec détail par lot/série) AverageUnitPricePMPShort=Prix moyen pondéré (PMP) -AverageUnitPricePMP=Prix moyen pondéré (PMP) d'acquisition +AverageUnitPricePMPDesc=Le prix unitaire moyen d'entrée que nous avons dû payer aux fournisseurs pour intégrer le produit dans notre stock. SellPriceMin=Prix de vente unitaire EstimatedStockValueSellShort=Valeur à la vente EstimatedStockValueSell=Valeur vente @@ -141,7 +143,7 @@ Replenishments=Réapprovisionnement NbOfProductBeforePeriod=Quantité du produit %s en stock avant la période sélectionnée (< %s) NbOfProductAfterPeriod=Quantité du produit %s en stock après la période sélectionnée (> %s) MassMovement=Mouvement en masse -SelectProductInAndOutWareHouse=Sélectionner un produit, une quantité à transférer, un entrepôt source et destination et cliquer sur "%s". Une fois tous les mouvements choisis, cliquer sur "%s". +SelectProductInAndOutWareHouse=Sélectionner un entrepôt source et destination, un produit et une quantité à transférer, puis cliquer sur "%s". Une fois tous les mouvements choisis, cliquer sur "%s". RecordMovement=Enregistrer transfert ReceivingForSameOrder=Réceptions pour cette commande StockMovementRecorded=Mouvement de stocks enregistré diff --git a/htdocs/langs/fr_FR/suppliers.lang b/htdocs/langs/fr_FR/suppliers.lang index 81860c25a45..2b4ab9dcf70 100644 --- a/htdocs/langs/fr_FR/suppliers.lang +++ b/htdocs/langs/fr_FR/suppliers.lang @@ -1,4 +1,4 @@ -# Dolibarr language file - Source file is en_US - suppliers +# Dolibarr language file - Source file is en_US - vendors Suppliers=Fournisseurs SuppliersInvoice=Facture fournisseur ShowSupplierInvoice=Montrer la facture fournisseur @@ -15,7 +15,7 @@ SomeSubProductHaveNoPrices=Certains sous-produits n'ont pas de prix définis AddSupplierPrice=Ajouter un prix d'achat ChangeSupplierPrice=Modifier un prix d'achat SupplierPrices=Prix fournisseurs -ReferenceSupplierIsAlreadyAssociatedWithAProduct=Cette référence fournisseur est déjà associée à la référence : %s +ReferenceSupplierIsAlreadyAssociatedWithAProduct=Cette référence fournisseur est déjà associée à un produit : %s NoRecordedSuppliers=Pas de fournisseur enregistré SupplierPayment=Paiement fournisseur SuppliersArea=Espace fournisseurs diff --git a/htdocs/langs/fr_FR/users.lang b/htdocs/langs/fr_FR/users.lang index 1ed6c956e66..5e951464dff 100644 --- a/htdocs/langs/fr_FR/users.lang +++ b/htdocs/langs/fr_FR/users.lang @@ -108,6 +108,7 @@ DisabledInMonoUserMode=Désactivé en mode maintenance UserAccountancyCode=Code comptable de l'utilisateur UserLogoff=Déconnexion de l'utilisateur UserLogged=Utilisateur connecté +DateOfEmployment=Date d'embauche DateEmployment=Date d'embauche DateEmploymentEnd=Date de fin d'emploi CantDisableYourself=Vous ne pouvez pas désactiver votre propre compte utilisateur diff --git a/htdocs/langs/fr_FR/withdrawals.lang b/htdocs/langs/fr_FR/withdrawals.lang index 446de9e09d3..6cb4796acd6 100644 --- a/htdocs/langs/fr_FR/withdrawals.lang +++ b/htdocs/langs/fr_FR/withdrawals.lang @@ -10,7 +10,7 @@ PaymentByBankTransferReceipts=Ordres de virement bancaire PaymentByBankTransferLines=Lignes d'ordre de virement bancaire WithdrawalsReceipts=Bons de prélèvements WithdrawalReceipt=Bon de prélèvement -BankTransferReceipts=Ordres de virement +BankTransferReceipts=Ordres de virement bancaire BankTransferReceipt=Ordre de virement LatestBankTransferReceipts=Les %s derniers ordres de virement bancaire LastWithdrawalReceipts=Les %s derniers bons de prélèvements @@ -77,12 +77,12 @@ StatusMotif8=Autre motif CreateForSepaFRST=Créer fichier de prélèvement (SEPA FRST) CreateForSepaRCUR=Créer fichier de prélèvement (SEPA RCUR) CreateAll=Créer le fichier de prélèvement (tout) -CreateFileForPaymentByBankTransfer=Créer un virement (tout) +CreateFileForPaymentByBankTransfer=Créer un fichier de virement CreateSepaFileForPaymentByBankTransfer=Créer un fichier de virement (SEPA) CreateGuichet=Seulement guichet CreateBanque=Seulement banque OrderWaiting=En attente de traitement -NotifyTransmision=Transmission du bon +NotifyTransmision=Transmission du fichier NotifyCredit=Crédit du bon NumeroNationalEmetter=Numéro National Émetteur WithBankUsingRIB=Pour les comptes bancaires utilisant le RIB @@ -93,9 +93,10 @@ CreditDate=Crédité le WithdrawalFileNotCapable=Impossible de générer le fichier de reçu des prélèvement pour votre pays %s (Votre pays n'est pas supporté) ShowWithdraw=Afficher ordre de prélèvement IfInvoiceNeedOnWithdrawPaymentWontBeClosed=Toutefois, si la facture a au moins une demande de prélèvement non traité, elle ne sera pas classée payée afin de permettre le prélèvement d'abord. -DoStandingOrdersBeforePayments=Cet onglet vous permet de demander un prélèvement. Une fois la demande faite, allez dans le menu Banque->Paiement par prélèvement pour gérer l'ordre de prélèvement. Lorsque l'ordre de paiement est clos, le paiement sur la facture sera automatiquement enregistrée, et la facture fermée si le reste à payer est nul. -DoCreditTransferBeforePayments=Cet onglet vous permet de demander un ordre de virement. Une fois fait, allez dans le menu Banque -> Paiements par virement pour gérer l'ordre de virement. Lorsque le virement est clôturé, le paiement des factures sera automatiquement enregistré et les factures clôturées si le solde à payer est nul. +DoStandingOrdersBeforePayments=Cet onglet vous permet de demander un prélèvement. Une fois la demande faite, allez dans le menu Banque->Paiement par prélèvement pour générer l'ordre de prélèvement. Lorsque l'ordre de paiement est clos, le paiement sur les factures seront automatiquement enregistrés, et les factures fermées si le reste à payer est nul. +DoCreditTransferBeforePayments=Cet onglet vous permet de demander un ordre de virement. Une fois fait, allez dans le menu Banque ->Paiements par virement pour gérer l'ordre de virement. Lorsque le virement est clôturé, le paiement des factures fournisseurs sera automatiquement enregistré et les factures clôturées si le solde à payer est nul. WithdrawalFile=Fichier de prélèvement +CreditTransferFile=Fichier de virement SetToStatusSent=Mettre au statut "Fichier envoyé" ThisWillAlsoAddPaymentOnInvoice=Cette action enregistrera aussi les règlements des factures et les classera au statut "Payé" si le solde est nul StatisticsByLineStatus=Statistiques par statut des lignes @@ -121,6 +122,7 @@ SEPAFrstOrRecur=Type de paiement ModeRECUR=Payment récurrent ModeFRST=Paiement unitaire PleaseCheckOne=Cocher un choix uniquement +CreditTransferOrderCreated=Ordre de virement %s créé DirectDebitOrderCreated=Ordre de prélèvement %s créé AmountRequested=Montant réclamé SEPARCUR=SEPA RCUR diff --git a/htdocs/langs/fr_GA/admin.lang b/htdocs/langs/fr_GA/admin.lang index bdc794e1b31..c1d306ec390 100644 --- a/htdocs/langs/fr_GA/admin.lang +++ b/htdocs/langs/fr_GA/admin.lang @@ -1,4 +1,3 @@ # Dolibarr language file - Source file is en_US - admin -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. 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. 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. In the parameter field you can use for example 'EXTRACT:BODY:Name:\\s([^\\s]*)' if you want to extract the name of the thirdparty from a string 'Name: name to find' found into the body. diff --git a/htdocs/langs/fr_GA/main.lang b/htdocs/langs/fr_GA/main.lang index 0f9be27b22f..2e691473326 100644 --- a/htdocs/langs/fr_GA/main.lang +++ b/htdocs/langs/fr_GA/main.lang @@ -19,4 +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 -EmptySearchString=Enter non empty search criterias diff --git a/htdocs/langs/fr_GA/website.lang b/htdocs/langs/fr_GA/website.lang deleted file mode 100644 index ff992a2be9e..00000000000 --- a/htdocs/langs/fr_GA/website.lang +++ /dev/null @@ -1,2 +0,0 @@ -# Dolibarr language file - Source file is en_US - website -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/nl_BE/admin.lang b/htdocs/langs/nl_BE/admin.lang index 009d9292997..0b0d5b0e10f 100644 --- a/htdocs/langs/nl_BE/admin.lang +++ b/htdocs/langs/nl_BE/admin.lang @@ -67,7 +67,6 @@ SeeInMarkerPlace=Zie Marktplaats AchatTelechargement=Kopen / Downloaden GoModuleSetupArea=Ga naar het gedeelte Module-instellingen om een nieuwe module te implementeren / installeren: %s . DoliStoreDesc=DoliStore, de officiële markt voor externe Dolibarr ERP / CRM 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=Externe websites voor meer add-on (niet-basis) modules ... BoxesActivated=Geactiveerde widgets DoNotStoreClearPassword=Versleutel wachtwoorden opgeslagen in database (NIET als platte tekst). Het wordt sterk aanbevolen om deze optie te activeren. diff --git a/htdocs/langs/nl_BE/main.lang b/htdocs/langs/nl_BE/main.lang index 34b534324fb..05ff5191d8f 100644 --- a/htdocs/langs/nl_BE/main.lang +++ b/htdocs/langs/nl_BE/main.lang @@ -19,7 +19,6 @@ FormatDateHourShort=%d-%m-%Y %H:%M FormatDateHourSecShort=%d/%m/%Y %I:%M:%S %p FormatDateHourTextShort=%d %b %Y %H:%M FormatDateHourText=%d %B %Y %H:%M -EmptySearchString=Enter non empty search criterias NoRecordFound=Geen record gevonden ErrorCanNotCreateDir=Kan dir %s niet maken ErrorCanNotReadDir=Kan dir %s niet lezen diff --git a/htdocs/langs/nl_BE/website.lang b/htdocs/langs/nl_BE/website.lang index 05a97bd129a..e8f0a2d4af0 100644 --- a/htdocs/langs/nl_BE/website.lang +++ b/htdocs/langs/nl_BE/website.lang @@ -7,4 +7,3 @@ ViewSiteInNewTab=Bekijk de site in een nieuwe tab ViewPageInNewTab=Bekijk de pagina in een nieuwe tab SetAsHomePage=Zet als Homepagina ViewWebsiteInProduction=Bekijk website via de home URL's -YouTryToAccessToAFileThatIsNotAWebsitePage=You try to access to a page that is not available.
(ref=%s, type=%s, status=%s) diff --git a/htdocs/langs/pt_BR/stocks.lang b/htdocs/langs/pt_BR/stocks.lang index a04e49809f8..3315b8f6924 100644 --- a/htdocs/langs/pt_BR/stocks.lang +++ b/htdocs/langs/pt_BR/stocks.lang @@ -54,7 +54,6 @@ DescWareHouse=Descrição do armazém LieuWareHouse=Localização do armazenamento WarehousesAndProducts=Armazenamento de produtos AverageUnitPricePMPShort=Preço médio de entrada -AverageUnitPricePMP=Preço médio de entrada SellPriceMin=Venda Preço unitário EstimatedStockValueSellShort=Valor para venda EstimatedStockValueSell=Valor para venda diff --git a/htdocs/livraison/class/livraison.class.php b/htdocs/livraison/class/livraison.class.php index 6199bc4ec88..1429e39be8e 100644 --- a/htdocs/livraison/class/livraison.class.php +++ b/htdocs/livraison/class/livraison.class.php @@ -1035,6 +1035,7 @@ class Livraison extends CommonObject global $conf, $user, $langs; $langs->load("deliveries"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'typhon'; diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1084c07f755..90db6718a3b 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -644,6 +644,11 @@ if (!defined('NOLOGIN')) if (GETPOST('lang', 'aZ09')) $paramsurl[] = 'lang='.GETPOST('lang', 'aZ09'); header('Location: '.DOL_URL_ROOT.'/index.php'.(count($paramsurl) ? '?'.implode('&', $paramsurl) : '')); exit; + } else { + // User is loaded, we may need to change language for him according to its choice + if (! empty($user->conf->MAIN_LANG_DEFAULT)) { + $langs->setDefaultLang($user->conf->MAIN_LANG_DEFAULT); + } } } else { // We are already into an authenticated session @@ -850,13 +855,13 @@ if (GETPOST('theme', 'alpha')) } // Set javascript option -if (!GETPOST('nojs', 'int')) // If javascript was not disabled on URL -{ - if (!empty($user->conf->MAIN_DISABLE_JAVASCRIPT)) - { +if (GETPOST('nojs', 'int')) { // If javascript was not disabled on URL + $conf->use_javascript_ajax = 0; +} else { + if (!empty($user->conf->MAIN_DISABLE_JAVASCRIPT)) { $conf->use_javascript_ajax = !$user->conf->MAIN_DISABLE_JAVASCRIPT; } -} else $conf->use_javascript_ajax = 0; +} // Set MAIN_OPTIMIZEFORTEXTBROWSER for user (must be after login part) if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && !empty($user->conf->MAIN_OPTIMIZEFORTEXTBROWSER)) { @@ -1233,6 +1238,7 @@ function top_htmlhead($head, $title = '', $disablejs = 0, $disablehead = 0, $arr if (GETPOSTISSET('dol_optimize_smallscreen')) { $themeparam .= '&dol_optimize_smallscreen='.GETPOST('dol_optimize_smallscreen', 'int'); } if (GETPOSTISSET('dol_no_mouse_hover')) { $themeparam .= '&dol_no_mouse_hover='.GETPOST('dol_no_mouse_hover', 'int'); } if (GETPOSTISSET('dol_use_jmobile')) { $themeparam .= '&dol_use_jmobile='.GETPOST('dol_use_jmobile', 'int'); $conf->dol_use_jmobile = GETPOST('dol_use_jmobile', 'int'); } + if (GETPOSTISSET('THEME_DARKMODEENABLED')) { $themeparam .= '&THEME_DARKMODEENABLED='.GETPOST('THEME_DARKMODEENABLED', 'int'); } if (GETPOSTISSET('THEME_SATURATE_RATIO')) { $themeparam .= '&THEME_SATURATE_RATIO='.GETPOST('THEME_SATURATE_RATIO', 'int'); } if (!defined('DISABLE_JQUERY') && !$disablejs && $conf->use_javascript_ajax) diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index df9e58e9b31..c8274a8f8dd 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -95,6 +95,85 @@ $result = restrictedArea($user, 'modulebuilder', null); $error = 0; +// Define $listofmodules +$dirsrootforscan = array($dirread); +// Add also the core modules into the list of modules to show/edit +if ($dirread != DOL_DOCUMENT_ROOT && ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->MODULEBUILDER_ADD_DOCUMENT_ROOT))) { $dirsrootforscan[] = DOL_DOCUMENT_ROOT; } + +// Search modules to edit +$textforlistofdirs = ''."\n"; +$listofmodules = array(); +$i = 0; +foreach ($dirsrootforscan as $dirread) +{ + $moduletype = 'external'; + if ($dirread == DOL_DOCUMENT_ROOT) { + $moduletype = 'internal'; + } + + $dirsincustom = dol_dir_list($dirread, 'directories'); + if (is_array($dirsincustom) && count($dirsincustom) > 0) { + foreach ($dirsincustom as $dircustomcursor) { + $fullname = $dircustomcursor['fullname']; + if (dol_is_file($fullname.'/'.$FILEFLAG)) + { + // Get real name of module (MyModule instead of mymodule) + $dirtoscanrel = basename($fullname).'/core/modules/'; + + $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$'); + if (empty($descriptorfiles)) // If descriptor not found into module dir, we look into main module dir. + { + $dirtoscanrel = 'core/modules/'; + $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$'); + } + $modulenamewithcase = ''; + $moduledescriptorrelpath = ''; + $moduledescriptorfullpath = ''; + + foreach ($descriptorfiles as $descriptorcursor) { + $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']); + $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase); + $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name']; + $moduledescriptorfullpath = $descriptorcursor['fullname']; + //var_dump($descriptorcursor); + } + if ($modulenamewithcase) + { + $listofmodules[$dircustomcursor['name']] = array( + 'modulenamewithcase'=>$modulenamewithcase, + 'moduledescriptorrelpath'=> $moduledescriptorrelpath, + 'moduledescriptorfullpath'=>$moduledescriptorfullpath, + 'moduledescriptorrootpath'=>$dirread, + 'moduletype'=>$moduletype + ); + } + //var_dump($listofmodules); + } + } + } + + if ($forceddirread && empty($listofmodules)) // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir + { + $listofmodules[strtolower($module)] = array( + 'modulenamewithcase'=>$module, + 'moduledescriptorrelpath'=> 'notyetimplemented', + 'moduledescriptorfullpath'=> 'notyetimplemented', + 'moduledescriptorrootpath'=> 'notyetimplemented', + ); + } + + // Show description of content + $newdircustom = $dirins; + if (empty($newdircustom)) $newdircustom = img_warning(); + // If dirread was forced to somewhere else, by using URL + // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product + if (empty($i)) $textforlistofdirs .= $langs->trans("DirScanned").' : '; + else $textforlistofdirs .= ', '; + $textforlistofdirs .= ''.$dirread.''; + $i++; +} + + /* * Actions */ @@ -214,7 +293,6 @@ if ($dirins && $action == 'initmodule' && $modulename) } $result = dolReplaceInFile($phpfileval['fullname'], $arrayreplacement); - //var_dump($result); if ($result < 0) { @@ -769,6 +847,9 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { $objectname = ucfirst($objectname); + $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $moduletype = $listofmodules[strtolower($module)]['moduletype']; + if (preg_match('/[^a-z0-9_]/i', $objectname)) { $error++; @@ -1076,6 +1157,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) $objectname = $tabobj; + $dirins = $dirread = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $moduletype = $listofmodules[strtolower($module)]['moduletype']; + $srcdir = $dirread.'/'.strtolower($module); $destdir = $dirins.'/'.strtolower($module); dol_mkdir($destdir); @@ -1125,7 +1209,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) // Edit the class file to write properties if (!$error) { - $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry); + $moduletype = 'external'; + + $object = rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry, $moduletype); if (is_numeric($object) && $object <= 0) { $error++; @@ -1135,7 +1221,9 @@ if ($dirins && $action == 'addproperty' && !empty($module) && !empty($tabobj)) // Edit sql with new properties if (!$error) { - $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object); + $moduletype = 'external'; + + $result = rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object, $moduletype); if ($result <= 0) { $error++; @@ -1477,79 +1565,11 @@ print load_fiche_titre($text, '', 'title_setup'); print ''.$langs->trans("ModuleBuilderDesc", 'https://wiki.dolibarr.org/index.php/Module_development#Create_your_module').'
'; -$dirsrootforscan = array($dirread); -// Add also the core modules into the list of modules to show/edit -if ($dirread != DOL_DOCUMENT_ROOT && ($conf->global->MAIN_FEATURES_LEVEL >= 2 || !empty($conf->global->MODULEBUILDER_ADD_DOCUMENT_ROOT))) { $dirsrootforscan[] = DOL_DOCUMENT_ROOT; } - -// Search modules to edit -print ''."\n"; -$listofmodules = array(); -$i = 0; -foreach ($dirsrootforscan as $dirread) -{ - $dirsincustom = dol_dir_list($dirread, 'directories'); - if (is_array($dirsincustom) && count($dirsincustom) > 0) { - foreach ($dirsincustom as $dircustomcursor) { - $fullname = $dircustomcursor['fullname']; - if (dol_is_file($fullname.'/'.$FILEFLAG)) - { - // Get real name of module (MyModule instead of mymodule) - $dirtoscanrel = basename($fullname).'/core/modules/'; - - $descriptorfiles = dol_dir_list(dirname($fullname).'/'.$dirtoscanrel, 'files', 0, 'mod.*\.class\.php$'); - if (empty($descriptorfiles)) // If descriptor not found into module dir, we look into main module dir. - { - $dirtoscanrel = 'core/modules/'; - $descriptorfiles = dol_dir_list($fullname.'/../'.$dirtoscanrel, 'files', 0, 'mod'.strtoupper(basename($fullname)).'\.class\.php$'); - } - $modulenamewithcase = ''; - $moduledescriptorrelpath = ''; - $moduledescriptorfullpath = ''; - - foreach ($descriptorfiles as $descriptorcursor) { - $modulenamewithcase = preg_replace('/^mod/', '', $descriptorcursor['name']); - $modulenamewithcase = preg_replace('/\.class\.php$/', '', $modulenamewithcase); - $moduledescriptorrelpath = $dirtoscanrel.$descriptorcursor['name']; - $moduledescriptorfullpath = $descriptorcursor['fullname']; - //var_dump($descriptorcursor); - } - if ($modulenamewithcase) - { - $listofmodules[$dircustomcursor['name']] = array( - 'modulenamewithcase'=>$modulenamewithcase, - 'moduledescriptorrelpath'=> $moduledescriptorrelpath, - 'moduledescriptorfullpath'=>$moduledescriptorfullpath, - 'moduledescriptorrootpath'=>$dirread - ); - } - //var_dump($listofmodules); - } - } - } - - if ($forceddirread && empty($listofmodules)) // $forceddirread is 1 if we forced dir to read with dirins=... or with module=...@mydir - { - $listofmodules[strtolower($module)] = array( - 'modulenamewithcase'=>$module, - 'moduledescriptorrelpath'=> 'notyetimplemented', - 'moduledescriptorfullpath'=> 'notyetimplemented', - 'moduledescriptorrootpath'=> 'notyetimplemented', - ); - } - - // Show description of content - $newdircustom = $dirins; - if (empty($newdircustom)) $newdircustom = img_warning(); - // If dirread was forced to somewhere else, by using URL - // htdocs/modulebuilder/index.php?module=Inventory@/home/ldestailleur/git/dolibarr/htdocs/product - if (empty($i)) print $langs->trans("DirScanned").' : '; - else print ', '; - print ''.$dirread.''; - $i++; -} +print $textforlistofdirs; print '
'; //var_dump($listofmodules); + $message = ''; if (!$dirins) { @@ -1583,7 +1603,6 @@ $error = 0; $moduleobj = null; - if (!empty($module) && $module != 'initmodule' && $module != 'deletemodule') { $modulelowercase = strtolower($module); @@ -1835,6 +1854,8 @@ if ($module == 'initmodule') print '
'; + // Note module is inside $dirread + if ($tab == 'description') { $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; @@ -2315,29 +2336,31 @@ if ($module == 'initmodule') $pathtopicto = strtolower($module).'/img/object_'.strtolower($tabobj).'.png'; $pathtoscript = strtolower($module).'/scripts/'.strtolower($tabobj).'.php'; - //var_dump($pathtolib); - $realpathtoclass = dol_buildpath($pathtoclass, 0, 2); - $realpathtoapi = dol_buildpath($pathtoapi, 0, 2); - $realpathtoagenda = dol_buildpath($pathtoagenda, 0, 2); - $realpathtocard = dol_buildpath($pathtocard, 0, 2); - $realpathtodocument = dol_buildpath($pathtodocument, 0, 2); - $realpathtolist = dol_buildpath($pathtolist, 0, 2); - $realpathtonote = dol_buildpath($pathtonote, 0, 2); - $realpathtophpunit = dol_buildpath($pathtophpunit, 0, 2); - $realpathtosql = dol_buildpath($pathtosql, 0, 2); - $realpathtosqlextra = dol_buildpath($pathtosqlextra, 0, 2); - $realpathtosqlkey = dol_buildpath($pathtosqlkey, 0, 2); - $realpathtosqlextrakey = dol_buildpath($pathtosqlextrakey, 0, 2); - $realpathtolib = dol_buildpath($pathtolib, 0, 2); - $realpathtoobjlib = dol_buildpath($pathtoobjlib, 0, 2); - $realpathtopicto = dol_buildpath($pathtopicto, 0, 2); - $realpathtoscript = dol_buildpath($pathtoscript, 0, 2); + //var_dump($pathtoclass); var_dump($dirread); + $realpathtoclass = $dirread.'/'.$pathtoclass; + $realpathtoapi = $dirread.'/'.$pathtoapi; + $realpathtoagenda = $dirread.'/'.$pathtoagenda; + $realpathtocard = $dirread.'/'.$pathtocard; + $realpathtodocument = $dirread.'/'.$pathtodocument; + $realpathtolist = $dirread.'/'.$pathtolist; + $realpathtonote = $dirread.'/'.$pathtonote; + $realpathtophpunit = $dirread.'/'.$pathtophpunit; + $realpathtosql = $dirread.'/'.$pathtosql; + $realpathtosqlextra = $dirread.'/'.$pathtosqlextra; + $realpathtosqlkey = $dirread.'/'.$pathtosqlkey; + $realpathtosqlextrakey = $dirread.'/'.$pathtosqlextrakey; + $realpathtolib = $dirread.'/'.$pathtolib; + $realpathtoobjlib = $dirread.'/'.$pathtoobjlib; + $realpathtopicto = $dirread.'/'.$pathtopicto; + $realpathtoscript = $dirread.'/'.$pathtoscript; if (empty($realpathtoapi)) // For compatibility with some old modules { $pathtoapi = strtolower($module).'/class/api_'.strtolower($module).'s.class.php'; - $realpathtoapi = dol_buildpath($pathtoapi, 0, 2); + $realpathtoapi = $dirread.'/'.$pathtoapi; } + $urloflist = $dirread.'/'.$pathtolist; + $urlofcard = $dirread.'/'.$pathtocard; print '
'; print ' '.$langs->trans("ClassFile").' : '.($realpathtoclass ? '' : '').$pathtoclass.($realpathtoclass ? '' : '').''; @@ -2423,9 +2446,6 @@ if ($module == 'initmodule') print '
'; print '
'; - $urloflist = dol_buildpath($pathtolist, 1); - $urlofcard = dol_buildpath($pathtocard, 1); - print '
'; print ' '.$langs->trans("PageForList").' : '.($realpathtolist ? '' : '').$pathtolist.($realpathtolist ? '' : '').''; print ' '.img_picto($langs->trans("Edit"), 'edit').''; @@ -2472,7 +2492,7 @@ if ($module == 'initmodule') if (function_exists('opcache_invalidate')) opcache_invalidate($dirread.'/'.$pathtoclass, true); // remove the include cache hell ! - if (empty($forceddirread)) + if (empty($forceddirread) && empty($dirread)) { $result = dol_include_once($pathtoclass); } else { diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 455f0a3e3d1..457e5f3f7d5 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -310,7 +310,7 @@ class MyObject extends CommonObject foreach ($object->array_options as $key => $option) { $shortkey = preg_replace('/options_/', '', $key); - if (!empty($extrafields->attributes[$this->element]['unique'][$shortkey])) + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { //var_dump($key); var_dump($clonedObj->array_options[$key]); exit; unset($object->array_options[$key]); diff --git a/htdocs/modulebuilder/template/modulebuilder.txt b/htdocs/modulebuilder/template/modulebuilder.txt index 24ea0d6eac5..670a1774929 100644 --- a/htdocs/modulebuilder/template/modulebuilder.txt +++ b/htdocs/modulebuilder/template/modulebuilder.txt @@ -1,3 +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. Use ModuleBuilder if you want to delete module. \ No newline at end of file +# 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/modulebuilder/template/mymoduleindex.php b/htdocs/modulebuilder/template/mymoduleindex.php index 4a3356f1d7e..91eb5eca8da 100644 --- a/htdocs/modulebuilder/template/mymoduleindex.php +++ b/htdocs/modulebuilder/template/mymoduleindex.php @@ -106,7 +106,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print ''; print ''; - print ''; + print ''; $var = true; if ($num > 0) @@ -117,22 +117,17 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) $obj = $db->fetch_object($resql); print ''; print ''; print ''; $i++; @@ -171,14 +166,12 @@ $max = 3; // Last modified myobject if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) { - $sql = "SELECT s.rowid, s.nom as name, s.client, s.datec, s.tms, s.canvas"; - $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.client IN (1, 2, 3)"; - $sql.= " AND s.entity IN (".getEntity($companystatic->element).")"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND s.rowid = $socid"; + $sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms"; + $sql.= " FROM ".MAIN_DB_PREFIX."mymodule_myobject as s"; + //if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE s.entity IN (".getEntity($myobjectstatic->element).")"; + //if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + //if ($socid) $sql.= " AND s.rowid = $socid"; $sql .= " ORDER BY s.tms DESC"; $sql .= $db->plimit($max, 0); @@ -191,9 +184,7 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) print '
'.$langs->trans("DraftOrders").($num?''.$num.'':'').'
'.$langs->trans("DraftMyObjects").($num?''.$num.'':'').'
'; - $orderstatic->id=$obj->rowid; - $orderstatic->ref=$obj->ref; - $orderstatic->ref_client=$obj->ref_client; - $orderstatic->total_ht = $obj->total_ht; - $orderstatic->total_tva = $obj->total_tva; - $orderstatic->total_ttc = $obj->total_ttc; - print $orderstatic->getNomUrl(1); + + $myobjectstatic->id=$obj->rowid; + $myobjectstatic->ref=$obj->ref; + $myobjectstatic->ref_client=$obj->ref_client; + $myobjectstatic->total_ht = $obj->total_ht; + $myobjectstatic->total_tva = $obj->total_tva; + $myobjectstatic->total_ttc = $obj->total_ttc; + + print $myobjectstatic->getNomUrl(1); print ''; - $companystatic->id=$obj->socid; - $companystatic->name=$obj->name; - $companystatic->client=$obj->client; - $companystatic->code_client = $obj->code_client; - $companystatic->code_fournisseur = $obj->code_fournisseur; - $companystatic->canvas=$obj->canvas; - print $companystatic->getNomUrl(1,'customer',16); print ''.price($obj->total_ttc).'
'; print ''; print ''; print ''; print ''; @@ -202,28 +193,23 @@ if (! empty($conf->mymodule->enabled) && $user->rights->mymodule->read) while ($i < $num) { $objp = $db->fetch_object($resql); - $companystatic->id=$objp->rowid; - $companystatic->name=$objp->name; - $companystatic->client=$objp->client; - $companystatic->code_client = $objp->code_client; - $companystatic->code_fournisseur = $objp->code_fournisseur; - $companystatic->canvas=$objp->canvas; + + $myobjectstatic->id=$objp->rowid; + $myobjectstatic->ref=$objp->ref; + $myobjectstatic->label=$objp->label; + $myobjectstatic->status = $objp->status; + print ''; - print ''; + print ''; print '"; - print '"; + print '"; print ''; $i++; - - } $db->free($resql); - } - else - { + } else { print ''; } print "
'; - if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastCustomersOrProspects",$max); - else if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastModifiedProspects",$max); - else print $langs->trans("BoxTitleLastModifiedCustomers",$max); + print $langs->trans("BoxTitleLatestModifiedMyObjects", $max); print ''.$langs->trans("DateModificationShort").'
'.$companystatic->getNomUrl(1,'customer',48).''.$myobjectstatic->getNomUrl(1).''; - print $companystatic->getLibCustProspStatut(); print "'.dol_print_date($db->jdate($objp->tms),'day')."'.dol_print_date($db->jdate($objp->tms), 'day')."
'.$langs->trans("None").'

"; diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 20d6588f3d6..a85f84a50ba 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -287,13 +287,11 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $formconfirm = ''; // Confirmation to delete - if ($action == 'delete') - { + if ($action == 'delete') { $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMyObject'), $langs->trans('ConfirmDeleteObject'), 'confirm_delete', '', 0, 1); } // Confirmation to delete line - if ($action == 'deleteline') - { + 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 @@ -345,19 +343,19 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea if (! empty($conf->projet->enabled)) { $langs->load("projects"); - $morehtmlref.='
'.$langs->trans('Project') . ' '; + $morehtmlref .= '
'.$langs->trans('Project') . ' '; if ($permissiontoadd) { //if ($action != 'classify') $morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' '; - $morehtmlref.=' : '; + $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.=''; + //$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); } @@ -470,27 +468,22 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_VALIDATED) { + if ($permissiontoadd) { print ''.$langs->trans("SetToDraft").''; } } // Modify - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } // Validate - if ($object->status == $object::STATUS_DRAFT) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_DRAFT) { + if ($permissiontoadd) { if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { print ''.$langs->trans("Validate").''; @@ -502,31 +495,24 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Clone - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("ToClone").''."\n"; } /* if ($permissiontoadd) { - if ($object->status == $object::STATUS_ENABLED) - { + if ($object->status == $object::STATUS_ENABLED) { print ''.$langs->trans("Disable").''."\n"; - } - else - { + } else { print ''.$langs->trans("Enable").''."\n"; } } if ($permissiontoadd) { - if ($object->status == $object::STATUS_VALIDATED) - { + if ($object->status == $object::STATUS_VALIDATED) { print ''.$langs->trans("Cancel").''."\n"; - } - else - { + } else { print ''.$langs->trans("Re-Open").''."\n"; } } diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 67e6e9e70f3..0327456615c 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -2082,35 +2082,45 @@ if ($result > 0) $tmpcode = ''; if (!empty($modCodeProduct->code_auto)) $tmpcode = $modCodeProduct->getNextValue($object, $object->type); -// Define confirmation messages -$formquestionclone = array( - 'text' => $langs->trans("ConfirmClone"), - array('type' => 'text', 'name' => 'clone_ref', 'label' => $langs->trans("NewRefForClone"), 'value' => empty($tmpcode) ? $langs->trans("CopyOf").' '.$object->ref : $tmpcode, 'size'=>24), - array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneContentProduct"), 'value' => 1), - array('type' => 'checkbox', 'name' => 'clone_categories', 'label' => $langs->trans("CloneCategoriesProduct"), 'value' => 1), -); -if (!empty($conf->global->PRODUIT_MULTIPRICES)) { - $formquestionclone[] = array('type' => 'checkbox', 'name' => 'clone_prices', 'label' => $langs->trans("ClonePricesProduct").' ('.$langs->trans("CustomerPrices").')', 'value' => 0); -} -if (!empty($conf->global->PRODUIT_SOUSPRODUITS)) -{ - $formquestionclone[] = array('type' => 'checkbox', 'name' => 'clone_composition', 'label' => $langs->trans('CloneCompositionProduct'), 'value' => 1); -} +$formconfirm=''; // Confirm delete product if (($action == 'delete' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) // Output when action = clone if jmobile or no js || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) // Always output when not jmobile nor js { - print $form->formconfirm("card.php?id=".$object->id, $langs->trans("DeleteProduct"), $langs->trans("ConfirmDeleteProduct"), "confirm_delete", '', 0, "action-delete"); + $formconfirm = $form->formconfirm("card.php?id=".$object->id, $langs->trans("DeleteProduct"), $langs->trans("ConfirmDeleteProduct"), "confirm_delete", '', 0, "action-delete"); } // Clone confirmation if (($action == 'clone' && (empty($conf->use_javascript_ajax) || !empty($conf->dol_use_jmobile))) // Output when action = clone if jmobile or no js || (!empty($conf->use_javascript_ajax) && empty($conf->dol_use_jmobile))) // Always output when not jmobile nor js { - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneProduct', $object->ref), 'confirm_clone', $formquestionclone, 'yes', 'action-clone', 350, 600); + // Define confirmation messages + $formquestionclone = array( + 'text' => $langs->trans("ConfirmClone"), + array('type' => 'text', 'name' => 'clone_ref', 'label' => $langs->trans("NewRefForClone"), 'value' => empty($tmpcode) ? $langs->trans("CopyOf").' '.$object->ref : $tmpcode, 'size'=>24), + array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneContentProduct"), 'value' => 1), + array('type' => 'checkbox', 'name' => 'clone_categories', 'label' => $langs->trans("CloneCategoriesProduct"), 'value' => 1), + ); + if (!empty($conf->global->PRODUIT_MULTIPRICES)) { + $formquestionclone[] = array('type' => 'checkbox', 'name' => 'clone_prices', 'label' => $langs->trans("ClonePricesProduct").' ('.$langs->trans("CustomerPrices").')', 'value' => 0); + } + if (!empty($conf->global->PRODUIT_SOUSPRODUITS)) + { + $formquestionclone[] = array('type' => 'checkbox', 'name' => 'clone_composition', 'label' => $langs->trans('CloneCompositionProduct'), 'value' => 1); + } + + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneProduct', $object->ref), 'confirm_clone', $formquestionclone, 'yes', 'action-clone', 350, 600); } +// Call Hook formConfirm +$parameters = array('formConfirm' => $formconfirm, 'object' => $object); +$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; /* ************************************************************************** */ /* */ diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 1f4bbf870f3..89c9a78ddaa 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -286,6 +286,9 @@ class Products extends DolibarrApi foreach ($request_data as $field => $value) { if ($field == 'id') { continue; + } + if ($field == 'stock_reel') { + throw new RestException(400, 'Stock reel cannot be updated here. Use the /stockmovements endpoint instead'); } $this->product->$field = $value; } diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 39634c11302..996a9ae2e83 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -563,7 +563,7 @@ class Product extends CommonObject return -1; } - if (empty($this->ref)) { + if (empty($this->ref) || $this->ref == 'auto') { // Load object modCodeProduct $module = (!empty($conf->global->PRODUCT_CODEPRODUCT_ADDON) ? $conf->global->PRODUCT_CODEPRODUCT_ADDON : 'mod_codeproduct_leopard'); if ($module != 'mod_codeproduct_leopard') // Do not load module file for leopard @@ -2025,7 +2025,7 @@ class Product extends CommonObject return -1; } - $sql = "SELECT rowid, ref, ref_ext, label, description, url, note as note_private, customcode, fk_country, price, price_ttc,"; + $sql = "SELECT rowid, ref, ref_ext, label, description, url, note_public, note as note_private, customcode, fk_country, price, price_ttc,"; $sql .= " price_min, price_min_ttc, price_base_type, cost_price, default_vat_code, tva_tx, recuperableonly as tva_npr, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, tosell,"; $sql .= " tobuy, fk_product_type, duration, fk_default_warehouse, seuil_stock_alerte, canvas, net_measure, net_measure_units, weight, weight_units,"; $sql .= " length, length_units, width, width_units, height, height_units,"; @@ -2061,8 +2061,9 @@ class Product extends CommonObject $this->label = $obj->label; $this->description = $obj->description; $this->url = $obj->url; - $this->note_private = $obj->note_private; - $this->note = $obj->note_private; // deprecated + $this->note_public = $obj->note_public; + $this->note_private = $obj->note_private; + $this->note = $obj->note_private; // deprecated $this->type = $obj->fk_product_type; $this->status = $obj->tosell; @@ -2209,7 +2210,7 @@ class Product extends CommonObject } }*/ } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } @@ -2254,12 +2255,12 @@ class Product extends CommonObject } $this->prices_by_qty_list[0] = $resultat; } else { - dol_print_error($this->db); - return -1; + $this->error=$this->db->lasterror; + return -1; } } } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES) && empty($ignore_price_load)) // prices per customer and quantity @@ -2313,12 +2314,12 @@ class Product extends CommonObject } $this->prices_by_qty_list[$i] = $resultat; } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } @@ -2345,7 +2346,7 @@ class Product extends CommonObject return 0; } } else { - dol_print_error($this->db); + $this->error=$this->db->lasterror; return -1; } } @@ -3490,7 +3491,7 @@ class Product extends CommonObject $sql = "SELECT sum(d.qty), date_format(d.date_valid, '%Y%m')"; if ($mode == 'bynumber') { - $sql .= ", count(DISTINCT c.rowid)"; + $sql .= ", count(DISTINCT d.rowid)"; } $sql .= " FROM ".MAIN_DB_PREFIX."mrp_mo as d LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON d.fk_soc = s.rowid"; if ($filteronproducttype >= 0) { @@ -4427,6 +4428,7 @@ class Product extends CommonObject global $conf, $user, $langs; $langs->load("products"); + $outputlangs->load("products"); // Positionne le modele sur le nom du modele a utiliser if (!dol_strlen($modele)) { diff --git a/htdocs/product/inventory/card.php b/htdocs/product/inventory/card.php index 9f3afa55738..6a2406d74b5 100644 --- a/htdocs/product/inventory/card.php +++ b/htdocs/product/inventory/card.php @@ -22,9 +22,11 @@ */ require '../../main.inc.php'; -include_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; -include_once DOL_DOCUMENT_ROOT.'/product/inventory/class/inventory.class.php'; -include_once DOL_DOCUMENT_ROOT.'/product/inventory/lib/inventory.lib.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.'/product/inventory/class/inventory.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/inventory/lib/inventory.lib.php'; // Load translation files required by the page $langs->loadLangs(array("stocks", "other")); @@ -49,7 +51,7 @@ if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) $object = new Inventory($db); $extrafields = new ExtraFields($db); $diroutputmassaction = $conf->stock->dir_output.'/temp/massgeneration/'.$user->id; -$hookmanager->initHooks(array('inventorycard')); // Note that conf->hooks_modules contains array +$hookmanager->initHooks(array('inventorycard', 'globalcard')); // Note that conf->hooks_modules contains array // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); @@ -76,11 +78,19 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be includ if (empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { + $permissiontoread = $user->rights->stock->lire; $permissiontoadd = $user->rights->stock->creer; $permissiontodelete = $user->rights->stock->supprimer; + $permissionnote = $user->rights->stock->creer; // Used by the include of actions_setnotes.inc.php + $permissiondellink = $user->rights->stock->creer; // Used by the include of actions_dellink.inc.php + $upload_dir = $conf->stock->multidir_output[isset($object->entity) ? $object->entity : 1]; } else { + $permissiontoread = $user->rights->stock->inventory_advance->read; $permissiontoadd = $user->rights->stock->inventory_advance->write; $permissiontodelete = $user->rights->stock->inventory_advance->write; + $permissionnote = $user->rights->stock->inventory_advance->write; // Used by the include of actions_setnotes.inc.php + $permissiondellink = $user->rights->stock->inventory_advance->write; // Used by the include of actions_dellink.inc.php + $upload_dir = $conf->stock->multidir_output[isset($object->entity) ? $object->entity : 1]; } @@ -98,7 +108,15 @@ if (empty($reshook)) $backurlforlist = DOL_URL_ROOT.'/product/inventory/list.php'; - // Actions cancel, add, update, delete or clone + 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('/product/inventory/card.php', 1).'?id='.($id > 0 ? $id : '__ID__'); + } + } + $triggermodname = 'STOCK_INVENTORY_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 @@ -107,11 +125,26 @@ if (empty($reshook)) // 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, 'MYOBJECT_MODIFY'); + }*/ + if ($action == 'classin' && $permissiontoadd) + { + $object->setProject(GETPOST('projectid', 'int')); + } + // Actions to send emails - /*$triggersendname = 'MYOBJECT_SENTBYMAIL'; - $autocopy='MAIN_MAIL_AUTOCOPY_MYOBJECT_TO'; - $trackid='myobject'.$object->id; - include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';*/ + $triggersendname = 'INVENTORY_SENTBYMAIL'; + $autocopy='MAIN_MAIL_AUTOCOPY_INVENTORY_TO'; + $trackid='stockinv'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; } @@ -122,8 +155,12 @@ if (empty($reshook)) */ $form = new Form($db); +$formfile = new FormFile($db); +$formproject = new FormProjets($db); -llxHeader('', $langs->trans('Inventory'), ''); +$title = $langs->trans("Inventory"); +$help_url = ''; +llxHeader('', $title, $help_url); // Example : Adding jquery code print ''; - print load_fiche_titre($langs->trans("StockCorrection"), '', 'generic'); +print load_fiche_titre($langs->trans("StockCorrection"), '', 'generic'); - print '
'."\n"; +print ''."\n"; - dol_fiche_head(); +dol_fiche_head(); - print ''; - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; +print '
'; - // Warehouse or product - print ''; -if ($object->element == 'product') -{ +// Warehouse or product +print ''; +if ($object->element == 'product') { print ''; print ''; } -if ($object->element == 'stock') -{ +if ($object->element == 'stock') { print ''; print ''; } - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; - // Purchase price - print ''; - print ''; - print ''; -if (!empty($conf->projet->enabled)) -{ - print ''; - print ''; -} - print ''; - - // Serial / Eat-by date +// Serial / Eat-by date if (!empty($conf->productbatch->enabled) && - (($object->element == 'product' && $object->hasbatch()) - || ($object->element == 'stock')) - ) +(($object->element == 'product' && $object->hasbatch()) +|| ($object->element == 'stock')) +) { print ''; print 'element == 'stock' ? '' : ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; } - // Label of mouvement of id of inventory - $valformovementlabel = ((GETPOST("label") && (GETPOST('label') != $langs->trans("MovementCorrectStock", ''))) ? GETPOST("label") : $langs->trans("MovementCorrectStock", $productref)); - print ''; - print ''; - print ''; - print ''; - print ''; +// Purchase price and project +print ''; +print ''; +print ''; +if (!empty($conf->projet->enabled)) +{ + print ''; + print ''; +} +print ''; - print '
'.$langs->trans("Warehouse").''; $ident = (GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ? GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))); if (empty($ident) && !empty($conf->global->MAIN_DEFAULT_WAREHOUSE)) $ident = $conf->global->MAIN_DEFAULT_WAREHOUSE; print $formproduct->selectWarehouses($ident, 'id_entrepot', 'warehouseopen,warehouseinternal', 1, 0, 0, '', 0, 0, null, 'minwidth100'); - print '   '; print ''; print ''; print ''; print ''.$langs->trans("Product").''; $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); - print '   '; print ''; print ''; print ''; print ''.$langs->trans("NumberOfUnit").'
'.$langs->trans("NumberOfUnit").'
'.$langs->trans("UnitPurchaseValue").''.$langs->trans('Project').''; - $formproject->select_projects(-1, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); - print '
'; @@ -130,26 +114,39 @@ if (!empty($conf->productbatch->enabled) && print '
'.$langs->trans("MovementLabel").''; - print ''; - print ''.$langs->trans("InventoryCode").'
'.$langs->trans("UnitPurchaseValue").''.$langs->trans('Project').''; + $formproject->select_projects(-1, '', 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, 'maxwidth300'); + print '
'; +// Label of mouvement of id of inventory +$valformovementlabel = ((GETPOST("label") && (GETPOST('label') != $langs->trans("MovementCorrectStock", ''))) ? GETPOST("label") : $langs->trans("MovementCorrectStock", $productref)); +print ''; +print ''.$langs->trans("MovementLabel").''; +print ''; +print ''; +print ''; +print ''.$langs->trans("InventoryCode").''; +print ''; - dol_fiche_end(); +print ''; - print '
'; - print ''; - print '     '; - print ''; - print '
'; +dol_fiche_end(); - print '
'; +print '
'; +print ''; +print '     '; +print ''; +print '
'; + +print ''; ?> diff --git a/htdocs/product/stock/tpl/stocktransfer.tpl.php b/htdocs/product/stock/tpl/stocktransfer.tpl.php index 097f1d2c84b..f725a5ebbfe 100644 --- a/htdocs/product/stock/tpl/stocktransfer.tpl.php +++ b/htdocs/product/stock/tpl/stocktransfer.tpl.php @@ -29,16 +29,16 @@ if (empty($conf) || !is_object($conf)) { element == 'product') $productref = $object->ref; +$productref = ''; +if ($object->element == 'product') $productref = $object->ref; - $langs->load("productbatch"); +$langs->load("productbatch"); - if (empty($id)) $id = $object->id; +if (empty($id)) $id = $object->id; - $pdluoid = GETPOST('pdluoid', 'int'); +$pdluoid = GETPOST('pdluoid', 'int'); - $pdluo = new Productbatch($db); +$pdluo = new Productbatch($db); if ($pdluoid > 0) { @@ -51,49 +51,47 @@ if ($pdluoid > 0) } } - print load_fiche_titre($langs->trans("StockTransfer"), '', 'generic'); +print load_fiche_titre($langs->trans("StockTransfer"), '', 'generic'); - print '
'."\n"; +print ''."\n"; - dol_fiche_head(); +dol_fiche_head(); - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; if ($pdluoid) { print ''; } - print ''; +print '
'; - // Source warehouse or product - print ''; -if ($object->element == 'product') -{ +// Source warehouse or product +print ''; +if ($object->element == 'product') { print ''; print ''; } -if ($object->element == 'stock') -{ +if ($object->element == 'stock') { print ''; print ''; } - print ''; - print ''; - print ''; +print ''; +print ''; +print ''; - // Serial / Eat-by date +// Serial / Eat-by date if (!empty($conf->productbatch->enabled) && - (($object->element == 'product' && $object->hasbatch()) - || ($object->element == 'stock')) - ) +(($object->element == 'product' && $object->hasbatch()) +|| ($object->element == 'stock')) +) { print ''; print 'element == 'stock' ? '' : ' class="fieldrequired"').'>'.$langs->trans("batch_number").''; } - // Label - $valformovementlabel = (GETPOST("label") ?GETPOST("label") : $langs->trans("MovementTransferStock", $productref)); - print ''; - print ''; - print ''; - print ''; - print ''; +// Label +$valformovementlabel = (GETPOST("label") ?GETPOST("label") : $langs->trans("MovementTransferStock", $productref)); +print ''; +print ''; +print ''; +print ''; +print ''; - print '
'.$langs->trans("WarehouseSource").''; print $formproduct->selectWarehouses((GETPOST("dwid") ?GETPOST("dwid", 'int') : (GETPOST('id_entrepot') ?GETPOST('id_entrepot', 'int') : ($object->element == 'product' && $object->fk_default_warehouse ? $object->fk_default_warehouse : 'ifone'))), 'id_entrepot', 'warehouseopen,warehouseinternal', 1); print ''.$langs->trans("Product").''; $form->select_produits(GETPOST('product_id', 'int'), 'product_id', (empty($conf->global->STOCK_SUPPORTS_SERVICES) ? '0' : ''), 0, 0, -1, 2, '', 0, null, 0, 1, 0, 'maxwidth500'); print ''.$langs->trans("WarehouseTarget").''; - print $formproduct->selectWarehouses(GETPOST('id_entrepot_destination'), 'id_entrepot_destination', 'warehouseopen,warehouseinternal', 1); - print '
'.$langs->trans("NumberOfUnit").'
'.$langs->trans("WarehouseTarget").''; +print $formproduct->selectWarehouses(GETPOST('id_entrepot_destination'), 'id_entrepot_destination', 'warehouseopen,warehouseinternal', 1); +print '
'.$langs->trans("NumberOfUnit").'
'; @@ -118,26 +116,26 @@ if (!empty($conf->productbatch->enabled) && print '
'.$langs->trans("MovementLabel").''; - print ''; - print ''.$langs->trans("InventoryCode").'
'.$langs->trans("MovementLabel").''; +print ''; +print ''.$langs->trans("InventoryCode").'
'; +print ''; - dol_fiche_end(); +dol_fiche_end(); - print '
'; - print ''; - print '     '; - print ''; - print '
'; +print '
'; +print ''; +print '     '; +print ''; +print '
'; - print '
'; +print ''; ?> diff --git a/htdocs/product/traduction.php b/htdocs/product/traduction.php index 4e5c7b13458..055e3cbefc7 100644 --- a/htdocs/product/traduction.php +++ b/htdocs/product/traduction.php @@ -73,11 +73,11 @@ $cancel != $langs->trans("Cancel") && $current_lang = $langs->getDefaultLang(); // update de l'objet - if ($_POST["forcelangprod"] == $current_lang) - { + if ($_POST["forcelangprod"] == $current_lang) { $object->label = $_POST["libelle"]; $object->description = dol_htmlcleanlastbr($_POST["desc"]); $object->other = dol_htmlcleanlastbr($_POST["other"]); + $object->update($object->id, $user); } else { $object->multilangs[$_POST["forcelangprod"]]["label"] = $_POST["libelle"]; $object->multilangs[$_POST["forcelangprod"]]["description"] = dol_htmlcleanlastbr($_POST["desc"]); @@ -85,8 +85,7 @@ $cancel != $langs->trans("Cancel") && } // sauvegarde en base - if ($object->setMultiLangs($user) > 0) - { + if ($object->setMultiLangs($user) > 0) { $action = ''; } else { $action = 'add'; diff --git a/htdocs/projet/activity/perweek.php b/htdocs/projet/activity/perweek.php index f3a68dd979f..437c5934c81 100644 --- a/htdocs/projet/activity/perweek.php +++ b/htdocs/projet/activity/perweek.php @@ -119,8 +119,7 @@ $object = new Task($db); $extrafields = new ExtraFields($db); // fetch optionals attributes and labels -//$extrafields->fetch_name_optionals_label('projet'); -$extrafields->fetch_name_optionals_label('projet_task'); +$extrafields->fetch_name_optionals_label($object->table_element); $arrayfields = array(); /*$arrayfields=array( diff --git a/htdocs/projet/card.php b/htdocs/projet/card.php index bf28eda4edf..e3331fcec74 100644 --- a/htdocs/projet/card.php +++ b/htdocs/projet/card.php @@ -178,12 +178,12 @@ if (empty($reshook)) if ($result < 0) { $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); $error++; } } else { $langs->load("errors"); - setEventMessages($langs->trans($object->error), null, 'errors'); + setEventMessages($object->error, $object->errors, 'errors'); $error++; } if (!$error && !empty($object->id) > 0) diff --git a/htdocs/projet/graph_opportunities.inc.php b/htdocs/projet/graph_opportunities.inc.php index a18b2dc54a5..5a2febe5a33 100644 --- a/htdocs/projet/graph_opportunities.inc.php +++ b/htdocs/projet/graph_opportunities.inc.php @@ -1,4 +1,22 @@ + * + * 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 . + */ + +// variable $listofopplabel and $listofoppstatus should be defined + if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { $sql = "SELECT p.fk_opp_status as opp_status, cls.code, COUNT(p.rowid) as nb, SUM(p.opp_amount) as opp_amount, SUM(p.opp_amount * p.opp_percent) as ponderated_opp_amount"; @@ -54,7 +72,7 @@ if (!empty($conf->global->PROJECT_USE_OPPORTUNITIES)) $labelStatus = ''; $code = dol_getIdFromCode($db, $status, 'c_lead_status', 'rowid', 'code'); - if ($code) $labelStatus = $langs->trans("OppStatus".$code); + if ($code) $labelStatus = $langs->transnoentitiesnoconv("OppStatus".$code); if (empty($labelStatus)) $labelStatus = $listofopplabel[$status]; //$labelStatus .= ' ('.$langs->trans("Coeff").': '.price2num($listofoppstatus[$status]).')'; diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index c42677d8b21..4b87cf45b03 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -127,10 +127,12 @@ if (!empty($_SESSION['ipaddress'])) // To avoid to make action twice $ipaddress = $_SESSION['ipaddress']; $errormessage = $_SESSION['errormessage']; - // Call trigger - $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_KO', $user); - if ($result < 0) $error++; - // End call triggers + if (is_object($object) && method_exists($object, 'call_trigger')) { + // Call trigger + $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_KO', $user); + if ($result < 0) $error++; + // End call triggers + } // Send an email $sendemail = ''; diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 4bb899b930e..b316e7c68a8 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -186,7 +186,7 @@ if ($urllogo) } -print '

'; +print '


'; if (!empty($conf->paypal->enabled)) @@ -593,8 +593,8 @@ if ($ispaymentok) { // Record payment include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; - $invoice = new Facture($db); - $result = $invoice->fetch($tmptag['INV']); + $object = new Facture($db); + $result = $object->fetch($tmptag['INV']); if ($result) { $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; @@ -623,9 +623,9 @@ if ($ispaymentok) $paiement->datepaye = $now; if ($currencyCodeType == $conf->currency) { - $paiement->amounts = array($invoice->id => $FinalPaymentAmt); // Array with all payments dispatching with invoice id + $paiement->amounts = array($object->id => $FinalPaymentAmt); // Array with all payments dispatching with invoice id } else { - $paiement->multicurrency_amounts = array($invoice->id => $FinalPaymentAmt); // Array with all payments dispatching + $paiement->multicurrency_amounts = array($object->id => $FinalPaymentAmt); // Array with all payments dispatching $postactionmessages[] = 'Payment was done in a different currency that currency expected of company'; $ispostactionok = -1; @@ -662,7 +662,7 @@ if ($ispaymentok) if ($bankaccountid > 0) { $label = '(CustomerInvoicePayment)'; - if ($invoice->type == Facture::TYPE_CREDIT_NOTE) $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note + if ($object->type == Facture::TYPE_CREDIT_NOTE) $label = '(CustomerInvoicePaymentBack)'; // Refund of a credit note $result = $paiement->addPaymentToBank($user, 'payment', $label, $bankaccountid, '', ''); if ($result < 0) { @@ -709,10 +709,12 @@ if ($ispaymentok) $currencyCodeType = $_SESSION['currencyCodeType']; $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; - // Call trigger - $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_OK', $user); - if ($result < 0) $error++; - // End call triggers + if (is_object($object) && method_exists($object, 'call_trigger')) { + // Call trigger + $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_OK', $user); + if ($result < 0) $error++; + // End call triggers + } print $langs->trans("YourPaymentHasBeenRecorded")."
\n"; if ($TRANSACTIONID) print $langs->trans("ThisIsTransactionId", $TRANSACTIONID)."

\n"; @@ -831,10 +833,12 @@ if ($ispaymentok) $currencyCodeType = $_SESSION['currencyCodeType']; $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; - // Call trigger - $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_KO', $user); - if ($result < 0) $error++; - // End call triggers + if (is_object($object) && method_exists($object, 'call_trigger')) { + // Call trigger + $result = $object->call_trigger('PAYMENTONLINE_PAYMENT_KO', $user); + if ($result < 0) $error++; + // End call triggers + } print $langs->trans('DoExpressCheckoutPaymentAPICallFailed')."
\n"; print $langs->trans('DetailedErrorMessage').": ".$ErrorLongMsg."
\n"; diff --git a/htdocs/public/recruitment/view.php b/htdocs/public/recruitment/view.php index e34908dd0a7..2b07d303aa9 100644 --- a/htdocs/public/recruitment/view.php +++ b/htdocs/public/recruitment/view.php @@ -230,7 +230,8 @@ if (!empty($conf->global->RECRUITMENT_NEWFORM_TEXT)) } if (empty($text)) { - $text .= '
'.$langs->trans("JobOfferToBeFilled", $mysoc->name).''; + $text .= '
'.$langs->trans("JobOfferToBeFilled", $mysoc->name); + $text .= '   -   '.$mysoc->name.''; $text .= '   -   '.dol_print_date($object->date_creation); $text .= ''."\n"; $text .= '

'.$object->label.'


'."\n"; @@ -250,12 +251,10 @@ $found = true; print '
'; // Label - print $langs->trans("Label").' : '; print ''.$object->label.'
'; // Date - print $langs->trans("DateExpected").' : '; print ''; if ($object->date_planned > $now) { @@ -265,6 +264,31 @@ if ($object->date_planned > $now) { } print '
'; +// Remuneration +print $langs->trans("Remuneration").' : '; +print ''; +print $object->remuneration_suggested; +print '
'; + +// Contact +$tmpuser = new User($db); +$tmpuser->fetch($object->fk_user_recruiter); + +print $langs->trans("ContactForRecruitment").' : '; +$emailforcontact = $object->email_recruiter; +if (empty($emailforcontact)) { + $emailforcontact = $tmpuser->email; + if (empty($emailforcontact)) { + $emailforcontact = $mysoc->email; + } +} +print ''; +print $tmpuser->getFullName(-1); +print ' - '.img_picto('', 'email', 'class="paddingrightonly"').dol_print_email($emailforcontact); +print ''; +print '
'; + + print '
'; // Description diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index 60f52838bf6..922cb498c5d 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -201,7 +201,7 @@ if ($action == "view_ticketlist") // fetch optionals attributes and labels $extrafields = new ExtraFields($db); - $extrafields->fetch_name_optionals_label('ticket'); + $extrafields->fetch_name_optionals_label($object->table_element); $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_'); diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php new file mode 100644 index 00000000000..4a18ddf85fb --- /dev/null +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -0,0 +1,1044 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file class/recruitmentcandidature.class.php + * \ingroup recruitment + * \brief This file is a CRUD class file for RecruitmentCandidature (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 RecruitmentCandidature + */ +class RecruitmentCandidature extends CommonObject +{ + /** + * @var string ID to identify managed object. + */ + public $element = 'recruitmentcandidature'; + + /** + * @var string Name of table without prefix where object is stored. This is also the key used for extrafields management. + */ + public $table_element = 'recruitment_recruitmentcandidature'; + + /** + * @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 recruitmentcandidature. Must be the part after the 'object_' into object_recruitmentcandidature.png + */ + public $picto = 'recruitmentcandidature@recruitment'; + + + const STATUS_DRAFT = 0; + const STATUS_VALIDATED = 1; + const STATUS_CANCELED = 9; + + + /** + * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') + * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" + * 'label' the translation key. + * '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' is the CSS style to use on field. For example: 'maxwidth200' + * 'help' is a string visible as a tooltip on field + * '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. + * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") + * '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, '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"), + 'fk_recruitmentjobposition' => array('type'=>'integer:RecruitmentJobPosition:recruitment/class/recruitment_recruitmentjobposition.class.php', 'label'=>'Job', 'enabled'=>'1', 'position'=>15, 'notnull'=>1, 'visible'=>1, 'index'=>1), + '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,), + 'model_pdf' => array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>'1', 'position'=>1010, 'notnull'=>-1, 'visible'=>0,), + 'status' => array('type'=>'smallint', 'label'=>'Status', 'enabled'=>'1', 'position'=>1000, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'arrayofkeyval'=>array('0'=>'Draft', '1'=>'Validated', '9'=>'Canceled'),), + 'firstname' => array('type'=>'varchar(128)', 'label'=>'Firstname', 'enabled'=>'1', 'position'=>20, 'notnull'=>0, 'visible'=>1,), + 'lastname' => array('type'=>'varchar(128)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>21, 'notnull'=>0, 'visible'=>1,), + 'remuneration_requested' => array('type'=>'integer', 'label'=>'RequestedRemuneration', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1,), + 'remuneration_proposed' => array('type'=>'integer', 'label'=>'ProposedRemuneration', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1,), + 'fk_recruitment_origin' => array('type'=>'integer:CRecruitmentOrigin:recruitment/class/recruitment_crecruitmentorigin.class.php', 'label'=>'Origin', 'enabled'=>'1', 'position'=>45, 'visible'=>1, 'index'=>1), + ); + public $rowid; + public $ref; + public $fk_recruitmentjobposition; + 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 $model_pdf; + public $status; + public $firstname; + public $lastname; + public $remuneration_requested; + public $remuneration_proposed; + public $fk_recruitment_origin; + // END MODULEBUILDER PROPERTIES + + + // If this object has a subtable with lines + + /** + * @var int Name of subtable line + */ + //public $table_element_line = 'recruitment_recruitmentcandidatureline'; + + /** + * @var int Field with ID of parent key if this object has a parent + */ + //public $fk_element = 'fk_recruitmentcandidature'; + + /** + * @var int Name of subtable class that manage subtable lines + */ + //public $class_element_line = 'RecruitmentCandidatureline'; + + /** + * @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('recruitment_recruitmentcandidaturedet'); + + /** + * @var RecruitmentCandidatureLine[] 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->recruitment->recruitmentcandidature->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 (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) + { + return $this->createCommon($user, $notrigger); + } + + /** + * 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 + $object->ref = empty($this->fields['ref']['default']) ? "copy_of_".$object->ref : $this->fields['ref']['default']; + $object->label = empty($this->fields['label']['default']) ? $langs->trans("CopyOf")." ".$object->label : $this->fields['label']['default']; + $object->status = self::STATUS_DRAFT; + // ... + // 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, 'socid') && $this->socid == $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(); + $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 (strpos($key, 'date') !== false) { + $sqlwhere[] = $key.' = \''.$this->db->idate($value).'\''; + } elseif ($key == 'customsql') { + $sqlwhere[] = $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->recruitment->recruitmentcandidature->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitmentcandidature->recruitmentcandidature_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 = ".$user->id; + $sql .= " WHERE rowid = ".$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('RECRUITMENTCANDIDATURE_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 = 'recruitmentcandidature/".$this->db->escape($this->newref)."'"; + $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'recruitmentcandidature/".$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->recruitment->dir_output.'/recruitmentcandidature/'.$oldref; + $dirdest = $conf->recruitment->dir_output.'/recruitmentcandidature/'.$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->recruitment->dir_output.'/recruitmentcandidature/'.$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->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_DRAFT, $notrigger, 'RECRUITMENTCANDIDATURE_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->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_CANCELED, $notrigger, 'RECRUITMENTCANDIDATURE_CLOSE'); + } + + /** + * 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->recruitment->write)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->recruitment->recruitment_advance->validate)))) + { + $this->error='Permission denied'; + return -1; + }*/ + + return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'RECRUITMENTCANDIDATURE_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 = ''.$langs->trans("RecruitmentCandidature").''; + $label .= '
'; + $label .= ''.$langs->trans('Ref').': '.$this->ref; + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } + + $url = dol_buildpath('/recruitment/recruitmentcandidature_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("ShowRecruitmentCandidature"); + $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; + $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; + } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + + $linkstart = ''; + $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('recruitmentcandidaturedao')); + $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 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("recruitment@recruitment"); + $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'); + } + + $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 = '.$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() + { + $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 RecruitmentCandidatureLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_recruitmentcandidature = '.$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("recruitment@recruitment"); + + if (empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) { + $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON = 'mod_recruitmentcandidature_standard'; + } + + if (!empty($conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON)) + { + $mybool = false; + + $file = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON.".php"; + $classname = $conf->global->RECRUITMENT_RECRUITMENTCANDIDATURE_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) + { + $dir = dol_buildpath($reldir."core/modules/recruitment/"); + + // Load file with numbering class (if found) + $mybool |= @include_once $dir.$file; + } + + if ($mybool === false) + { + dol_print_error('', "Failed to include file ".$file); + return ''; + } + + if (class_exists($classname)) { + $obj = new $classname(); + $numref = $obj->getNextValue($this); + + if ($numref != '' && $numref != '-1') + { + return $numref; + } else { + $this->error = $obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } else { + print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; + return ""; + } + } else { + print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); + return ""; + } + } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param null|array $moreparams Array to provide more information + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) + { + global $conf, $langs; + + $result = 0; + $includedocgeneration = 1; + + $langs->load("recruitment@recruitment"); + + if (!dol_strlen($modele)) { + $modele = 'standard_recruitmentcandidature'; + + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (!empty($conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF)) { + $modele = $conf->global->RECRUITMENTCANDIDATURE_ADDON_PDF; + } + } + + $modelpath = "core/modules/recruitment/doc/"; + + if ($includedocgeneration) { + $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 RecruitmentCandidatureLine. You can also remove this and generate a CRUD class for lines objects. + */ +class RecruitmentCandidatureLine extends CommonObjectLine +{ + // To complete with content of an object RecruitmentCandidatureLine + // We should have a field rowid, fk_recruitmentcandidature and position + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } +} diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 6d38f47211c..aab39e4e433 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -45,7 +45,7 @@ class RecruitmentJobPosition extends CommonObject * @var int Does this object support multicompany module ? * 0=No test on entity, 1=Test with field entity, 'field@table'=Test with link by field@table */ - public $ismultientitymanaged = 0; + public $ismultientitymanaged = 1; /** * @var int Does object support extrafields ? 0=No, 1=Yes @@ -96,14 +96,17 @@ class RecruitmentJobPosition extends CommonObject public $fields=array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, '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', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1), 'label' => array('type'=>'varchar(255)', 'label'=>'JobLabel', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth500', 'showoncombobox'=>'1', 'autofocusoncreate'=>1), 'qty' => array('type'=>'integer', 'label'=>'NbOfEmployeesExpected', 'enabled'=>'1', 'position'=>45, 'notnull'=>1, 'visible'=>1, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp',), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'1', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), - 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid',), + 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>1, 'foreignkey'=>'user.rowid',), + 'email_recruiter' => array('type'=>'varchar(255)', 'label'=>'EmailRecruiter', 'enabled'=>'1', 'position'=>54, 'notnull'=>0, 'visible'=>-1, 'help'=>'ToUseAGenericEmail'), 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid',), 'fk_establishment' => array('type'=>'integer:Establishment:hrm/class/establishment.class.php', 'label'=>'Establishment', 'enabled'=>'$conf->hrm->enabled', 'position'=>56, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'establishment.rowid',), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'WorkPlace', 'enabled'=>'1', 'position'=>57, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'help'=>"IfJobIsLocatedAtAPartner",), 'date_planned' => array('type'=>'date', 'label'=>'DateExpected', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>1,), + 'remuneration_suggested' => array('type'=>'varchar(255)', 'label'=>'Remuneration', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>1,), 'description' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>65, 'notnull'=>0, 'visible'=>3,), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>101, 'notnull'=>0, 'visible'=>0,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>102, 'notnull'=>0, 'visible'=>0,), @@ -118,11 +121,13 @@ class RecruitmentJobPosition extends CommonObject ); public $rowid; public $ref; + public $entity; public $label; public $qty; public $fk_soc; public $fk_project; public $fk_user_recruiter; + public $email_recruiter; public $fk_user_supervisor; public $fk_establishment; public $date_planned; @@ -799,11 +804,11 @@ class RecruitmentJobPosition extends CommonObject $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated'); $this->labelStatus[self::STATUS_RECRUITED] = $langs->trans('Recruited'); - $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $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_RECRUITED] = $langs->trans('Recruited'); - $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Disabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Canceled'); } $statusType = 'status'.$status; diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index 580b3141d5c..cc28ea8978b 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -358,10 +358,10 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio $pdf->SetDrawColor(128, 128, 128); $pdf->SetTitle($outputlangs->convToOutputCharset($object->ref)); - $pdf->SetSubject($outputlangs->transnoentities("JobPosition")); + $pdf->SetSubject($object->label); $pdf->SetCreator("Dolibarr ".DOL_VERSION); $pdf->SetAuthor($outputlangs->convToOutputCharset($user->getFullName($outputlangs))); - $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$outputlangs->transnoentities("JobPosition")." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); + $pdf->SetKeyWords($outputlangs->convToOutputCharset($object->ref)." ".$object->label." ".$outputlangs->convToOutputCharset($object->thirdparty->name)); if (!empty($conf->global->MAIN_DISABLE_PDF_COMPRESSION)) $pdf->SetCompression(false); // Set certificate @@ -872,11 +872,11 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio $pdf->SetFont('', 'B', $default_font_size + 3); $pdf->SetXY($posx, $posy); $pdf->SetTextColor(0, 0, 60); - $title = $outputlangs->transnoentities("JobPosition"); - if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { + $title = $object->label; + /*if (!empty($conf->global->PDF_USE_ALSO_LANGUAGE_CODE) && is_object($outputlangsbis)) { $title .= ' - '; $title .= $outputlangsbis->transnoentities("JobPosition"); - } + }*/ $pdf->MultiCell($w, 3, $title, '', 'R'); $pdf->SetFont('', 'B', $default_font_size); diff --git a/htdocs/recruitment/modulebuilder.txt b/htdocs/recruitment/modulebuilder.txt index 24ea0d6eac5..670a1774929 100644 --- a/htdocs/recruitment/modulebuilder.txt +++ b/htdocs/recruitment/modulebuilder.txt @@ -1,3 +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. Use ModuleBuilder if you want to delete module. \ No newline at end of file +# 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/recruitment/recruitmentindex.php b/htdocs/recruitment/recruitmentindex.php index 71a4cedcc69..cf1f0e7dee4 100644 --- a/htdocs/recruitment/recruitmentindex.php +++ b/htdocs/recruitment/recruitmentindex.php @@ -24,25 +24,12 @@ * \brief Home page of recruitment top menu */ -// 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 '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/recruitment/class/recruitmentjobposition.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page -$langs->loadLangs(array("recruitment")); +$langs->loadLangs(array("recruitment", "boxes")); $action = GETPOST('action', 'alpha'); @@ -73,6 +60,7 @@ $now = dol_now(); $form = new Form($db); $formfile = new FormFile($db); +$staticrecruitmentjobposition = new RecruitmentJobPosition($db); llxHeader("", $langs->trans("RecruitmentArea")); @@ -81,6 +69,91 @@ print load_fiche_titre($langs->trans("RecruitmentArea"), '', 'object_recruitment print '
'; +/* + * Statistics + */ + +if ($conf->use_javascript_ajax) +{ + $sql = "SELECT COUNT(t.rowid) as nb, status"; + $sql .= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as t"; + $sql .= " GROUP BY t.status"; + $sql .= " ORDER BY t.status ASC"; + $resql = $db->query($sql); + + if ($resql) + { + $num = $db->num_rows($resql); + $i = 0; + + $totalnb = 0; + $dataseries = array(); + $colorseries = array(); + $vals = array(); + + include_once DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php'; + + while ($i < $num) + { + $obj = $db->fetch_object($resql); + if ($obj) + { + $vals[$obj->status] = $obj->nb; + + $totalnb += $obj->nb; + } + $i++; + } + $db->free($resql); + + print '
'; + print ''; + print ''."\n"; + $listofstatus = array(0, 1, 3, 9); + foreach ($listofstatus as $status) + { + $dataseries[] = array($staticrecruitmentjobposition->LibStatut($status, 1), (isset($vals[$status]) ? (int) $vals[$status] : 0)); + if ($status == RecruitmentJobPosition::STATUS_DRAFT) $colorseries[$status] = '-'.$badgeStatus0; + if ($status == RecruitmentJobPosition::STATUS_VALIDATED) $colorseries[$status] = $badgeStatus1; + if ($status == RecruitmentJobPosition::STATUS_RECRUITED) $colorseries[$status] = $badgeStatus4; + if ($status == RecruitmentJobPosition::STATUS_CANCELED) $colorseries[$status] = $badgeStatus9; + + if (empty($conf->use_javascript_ajax)) + { + print ''; + print ''; + print ''; + print "\n"; + } + } + if ($conf->use_javascript_ajax) + { + print ''; + } + print "
'.$langs->trans("Statistics").' - '.$langs->trans("Recruitment").'
'.$staticrecruitmentjobposition->LibStatut($status, 0).''.(isset($vals[$status]) ? $vals[$status] : 0).'
'; + + include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + $dolgraph = new DolGraph(); + $dolgraph->SetData($dataseries); + $dolgraph->SetDataColor(array_values($colorseries)); + $dolgraph->setShowLegend(2); + $dolgraph->setShowPercent(1); + $dolgraph->SetType(array('pie')); + $dolgraph->SetHeight('200'); + $dolgraph->draw('idgraphstatus'); + print $dolgraph->show($totalnb ? 0 : 1); + + print '
"; + print "
"; + + print "
"; + } else { + dol_print_error($db); + } +} + +print '
'; + /* BEGIN MODULEBUILDER DRAFT MYOBJECT // Draft MyObject if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) @@ -89,7 +162,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) $sql = "SELECT c.rowid, c.ref, c.ref_client, c.total_ht, c.tva as total_tva, c.total_ttc, s.rowid as socid, s.nom as name, s.client, s.canvas"; $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."commande as c"; + $sql.= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as c"; $sql.= ", ".MAIN_DB_PREFIX."societe as s"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= " WHERE c.fk_soc = s.rowid"; @@ -167,18 +240,16 @@ print '
'; $NBMAX = 3; $max = 3; -/* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT +/* BEGIN MODULEBUILDER LASTMODIFIED MYOBJECT */ // Last modified myobject -if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) +if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->recruitmentjobposition->read) { - $sql = "SELECT s.rowid, s.nom as name, s.client, s.datec, s.tms, s.canvas"; - $sql.= ", s.code_client"; - $sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; + $sql = "SELECT s.rowid, s.ref, s.label, s.date_creation, s.tms"; + $sql.= " FROM ".MAIN_DB_PREFIX."recruitment_recruitmentjobposition as s"; if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; - $sql.= " WHERE s.client IN (1, 2, 3)"; - $sql.= " AND s.entity IN (".getEntity($companystatic->element).")"; - if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; - if ($socid) $sql.= " AND s.rowid = $socid"; + $sql.= " WHERE s.entity IN (".getEntity($staticrecruitmentjobposition->element).")"; + if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.fk_soc = sc.fk_soc AND sc.fk_user = " .$user->id; + if ($socid) $sql.= " AND s.fk_soc = $socid"; $sql .= " ORDER BY s.tms DESC"; $sql .= $db->plimit($max, 0); @@ -191,9 +262,7 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) print ''; print ''; print ''; print ''; print ''; @@ -202,34 +271,31 @@ if (! empty($conf->recruitment->enabled) && $user->rights->recruitment->read) while ($i < $num) { $objp = $db->fetch_object($resql); - $companystatic->id=$objp->rowid; - $companystatic->name=$objp->name; - $companystatic->client=$objp->client; - $companystatic->code_client = $objp->code_client; - $companystatic->code_fournisseur = $objp->code_fournisseur; - $companystatic->canvas=$objp->canvas; + $staticrecruitmentjobposition->id=$objp->rowid; + $staticrecruitmentjobposition->ref=$objp->ref; + $staticrecruitmentjobposition->label=$objp->label; + $staticrecruitmentjobposition->status = $objp->status; + $staticrecruitmentjobposition->date_creation = $objp->date_creation; + print ''; - print ''; + print ''; print '"; - print '"; + print '"; print ''; $i++; - - } $db->free($resql); - } - else - { + } else { print ''; } print "
'; - if (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) && empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastCustomersOrProspects",$max); - else if (! empty($conf->global->SOCIETE_DISABLE_CUSTOMERS)) print $langs->trans("BoxTitleLastModifiedProspects",$max); - else print $langs->trans("BoxTitleLastModifiedCustomers",$max); + print $langs->trans("BoxTitleLatestModifiedJobPositions", $max); print ''.$langs->trans("DateModificationShort").'
'.$companystatic->getNomUrl(1,'customer',48).''.$staticrecruitmentjobposition->getNomUrl(1, '').''; - print $companystatic->getLibCustProspStatut(); print "'.dol_print_date($db->jdate($objp->tms),'day')."'.dol_print_date($db->jdate($objp->tms), 'day')."
'.$langs->trans("None").'

"; + } else { + dol_print_error($db); } } -*/ + print '
'; diff --git a/htdocs/recruitment/recruitmentjobposition_candidature.php b/htdocs/recruitment/recruitmentjobposition_candidature.php index bf2c766771f..d0e15827c2e 100644 --- a/htdocs/recruitment/recruitmentjobposition_candidature.php +++ b/htdocs/recruitment/recruitmentjobposition_candidature.php @@ -539,52 +539,9 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea print '
'; print ''; // ancre - $includedocgeneration = 1; - - // Documents - if ($includedocgeneration) { - $objref = dol_sanitizeFileName($object->ref); - $relativepath = $objref . '/' . $objref . '.pdf'; - $filedir = $conf->recruitment->dir_output.'/'.$object->element.'/'.$objref; - $urlsource = $_SERVER["PHP_SELF"] . "?id=" . $object->id; - $genallowed = $user->rights->recruitment->recruitmentjobposition->read; // If you can read, you can build the PDF to read content - $delallowed = $user->rights->recruitment->recruitmentjobposition->write; // If you can create/edit, you can remove a file on card - print $formfile->showdocuments('recruitment:RecruitmentJobPosition', $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('recruitmentjobposition')); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - - // Show link to public job page - if ($object->status != RecruitmentJobPosition::STATUS_DRAFT) - { - print '
'."\n"; - // Load translation files required by the page - $langs->loadLangs(array('recruitment')); - - $out = img_picto('', 'globe').' '.$langs->trans("PublicUrl").'
'; - - $url = getPublicJobPositionUrl(0, $object->ref); - $out .= ''; - $out .= ''.img_picto('', 'globe').''; - $out .= ajax_autoselect("recruitmentjobpositionurl", 0); - - print $out; - } 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.'@recruitment', (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlright); print '
'; } diff --git a/htdocs/recruitment/recruitmentjobposition_card.php b/htdocs/recruitment/recruitmentjobposition_card.php index 137afdd597f..0763b5ca749 100644 --- a/htdocs/recruitment/recruitmentjobposition_card.php +++ b/htdocs/recruitment/recruitmentjobposition_card.php @@ -455,8 +455,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Back to draft - if ($object->status == $object::STATUS_VALIDATED) - { + if ($object->status == $object::STATUS_VALIDATED) { if ($permissiontoadd) { print ''.$langs->trans("SetToDraft").''; @@ -464,18 +463,15 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Modify - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("Modify").''."\n"; } else { print ''.$langs->trans('Modify').''."\n"; } // Validate - if ($object->status == $object::STATUS_DRAFT) - { - if ($permissiontoadd) - { + if ($object->status == $object::STATUS_DRAFT) { + if ($permissiontoadd) { if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) { print ''.$langs->trans("Validate").''; @@ -487,39 +483,29 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea } // Clone - if ($permissiontoadd) - { + if ($permissiontoadd) { print ''.$langs->trans("ToClone").''."\n"; } /* - if ($permissiontoadd) - { - if ($object->status == $object::STATUS_ENABLED) - { + if ($permissiontoadd) { + if ($object->status == $object::STATUS_ENABLED) { print ''.$langs->trans("Disable").''."\n"; - } - else - { + } else { print ''.$langs->trans("Enable").''."\n"; } - } + }*/ if ($permissiontoadd) { - if ($object->status == $object::STATUS_VALIDATED) - { - print ''.$langs->trans("Cancel").''."\n"; - } - else - { - print ''.$langs->trans("Re-Open").''."\n"; + if ($object->status == $object::STATUS_VALIDATED) { + print ''.$langs->trans("Cancel").''."\n"; + } else { + print ''.$langs->trans("Re-Open").''."\n"; } } - */ // Delete (need delete permission, or if draft, just need create/modify permission) - if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) - { + if ($permissiontodelete || ($object->status == $object::STATUS_DRAFT && $permissiontoadd)) { print ''.$langs->trans('Delete').''."\n"; } else { print ''.$langs->trans('Delete').''."\n"; diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index 535d4e68967..1efe6287c66 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -490,6 +490,66 @@ class Thirdparties extends DolibarrApi } $this->company->oldcopy = clone $this->company; return $this->company->delete($id); + } + + /** + * Set new price level for the given thirdparty + * + * @param int $id ID of thirdparty + * @param int $priceLevel Price level to apply to thirdparty + * @return object Thirdparty data without useless information + * + * @url PUT {id}/setpricelevel + * + * @throws RestException 400 Price level out of bounds + * @throws RestException 401 Access not allowed for your login + * @throws RestException 404 Thirdparty not found + * @throws RestException 500 Error fetching/setting price level + * @throws RestException 501 Request needs modules "Thirdparties" and "Products" and setting Multiprices activated + */ + public function setThirdpartyPriceLevel($id, $priceLevel) + { + global $conf; + + if (empty($conf->societe->enabled)) { + throw new RestException(501, 'Module "Thirdparties" needed for this request'); + } + + if (empty($conf->product->enabled)) { + throw new RestException(501, 'Module "Products" needed for this request'); + } + + if (empty($conf->global->PRODUIT_MULTIPRICES)) { + throw new RestException(501, 'Multiprices features activation needed for this request'); + } + + if ($priceLevel < 1 || $priceLevel > $conf->global->PRODUIT_MULTIPRICES_LIMIT) { + throw new RestException(400, 'Price level must be between 1 and ' . $conf->global->PRODUIT_MULTIPRICES_LIMIT); + } + + if (empty(DolibarrApiAccess::$user->rights->societe->creer)) { + throw new RestException(401, 'Access to thirdparty ' . $id . ' not allowed for login '. DolibarrApiAccess::$user->login); + } + + $result = $this->company->fetch($id); + if ($result < 0) { + throw new RestException(404, 'Thirdparty ' . $id . ' not found'); + } + + if (empty($result)) { + throw new RestException(500, 'Error fetching thirdparty ' . $id, array_merge(array($this->company->error), $this->company->errors)); + } + + if (empty(DolibarrApi::_checkAccessToResource('societe', $this->company->id))) { + throw new RestException(401, 'Access to thirdparty ' . $id . ' not allowed for login ' . DolibarrApiAccess::$user->login); + } + + $result = $this->company->set_price_level($priceLevel, DolibarrApiAccess::$user); + if ($result <= 0) { + throw new RestException(500, 'Error setting new price level for thirdparty ' . $id, array($this->company->db->lasterror())); + } + + return $this->_cleanObjectDatas($this->company); } /** diff --git a/htdocs/societe/class/client.class.php b/htdocs/societe/class/client.class.php index be1d18836bc..f3cdd3c805b 100644 --- a/htdocs/societe/class/client.class.php +++ b/htdocs/societe/class/client.class.php @@ -1,6 +1,7 @@ * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -100,14 +101,14 @@ class Client extends Societe { global $langs; - $sql = "SELECT id, code, libelle as label FROM ".MAIN_DB_PREFIX."c_stcomm"; + $sql="SELECT id, code, libelle as label, picto FROM ".MAIN_DB_PREFIX."c_stcomm"; if ($active >= 0) $sql .= " WHERE active = ".$active; $resql = $this->db->query($sql); $num = $this->db->num_rows($resql); $i = 0; while ($i < $num) { $obj = $this->db->fetch_object($resql); - $this->cacheprospectstatus[$obj->id] = array('id'=>$obj->id, 'code'=>$obj->code, 'label'=> ($langs->trans("ST_".strtoupper($obj->code)) == "ST_".strtoupper($obj->code)) ? $obj->label : $langs->trans("ST_".strtoupper($obj->code))); + $this->cacheprospectstatus[$obj->id] = array('id'=>$obj->id, 'code'=>$obj->code, 'label'=>($langs->trans("ST_".strtoupper($obj->code))=="ST_".strtoupper($obj->code))?$obj->label:$langs->trans("ST_".strtoupper($obj->code)), 'picto'=>$obj->picto); $i++; } return 1; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 067558c445c..f65daf470e8 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -16,6 +16,7 @@ * Copyright (C) 2018 Philippe Grand * Copyright (C) 2019-2020 Josep Lluís Amador * Copyright (C) 2019 Frédéric France + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -572,6 +573,12 @@ class Societe extends CommonObject */ public $stcomm_id; + /** + * Status prospect picto + * @var string + */ + public $stcomm_picto; + /** * Status prospect label * @var int @@ -1489,7 +1496,7 @@ class Societe extends CommonObject $sql .= ', e.libelle as effectif'; $sql .= ', c.code as country_code, c.label as country'; $sql .= ', d.code_departement as state_code, d.nom as state'; - $sql .= ', st.libelle as stcomm'; + $sql .= ', st.libelle as stcomm, st.picto as stcomm_picto'; $sql .= ', te.code as typent_code'; $sql .= ', i.libelle as label_incoterms'; $sql .= ', sr.remise_client, model_pdf'; @@ -1562,6 +1569,7 @@ class Societe extends CommonObject $label = ($transcode != 'StatusProspect'.$obj->fk_stcomm ? $transcode : $obj->stcomm); $this->stcomm_id = $obj->fk_stcomm; // id status prospect $this->status_prospect_label = $label; // label status prospect + $this->stcomm_picto = $obj->stcomm_picto; // picto statut commercial $this->email = $obj->email; $this->socialnetworks = (array) json_decode($obj->socialnetworks, true); @@ -2734,7 +2742,7 @@ class Societe extends CommonObject * Return bank number property of thirdparty (label or rum) * * @param string $mode 'label' or 'rum' or 'format' - * @return string Bank number + * @return string Bank label or RUM or '' if no bank account found */ public function display_rib($mode = 'label') { @@ -2744,25 +2752,25 @@ class Societe extends CommonObject $bac = new CompanyBankAccount($this->db); $bac->fetch(0, $this->id); - if ($mode == 'label') - { - return $bac->getRibLabel(true); - } elseif ($mode == 'rum') - { - if (empty($bac->rum)) - { - require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; - $prelevement = new BonPrelevement($this->db); - $bac->fetch_thirdparty(); - $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id); + if ($bac->id > 0) { // If a bank account has been found for company $this->id + if ($mode == 'label') { + return $bac->getRibLabel(true); + } elseif ($mode == 'rum') { + if (empty($bac->rum)) { + require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/bonprelevement.class.php'; + $prelevement = new BonPrelevement($this->db); + $bac->fetch_thirdparty(); + $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id); + } + return $bac->rum; + } elseif ($mode == 'format') { + return $bac->frstrecur; + } else { + return 'BadParameterToFunctionDisplayRib'; } - return $bac->rum; - } elseif ($mode == 'format') - { - return $bac->frstrecur; + } else { + return ''; } - - return 'BadParameterToFunctionDisplayRib'; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -3891,7 +3899,7 @@ class Societe extends CommonObject */ public function getLibProspCommStatut($mode = 0, $label = '') { - return $this->LibProspCommStatut($this->stcomm_id, $mode, $label); + return $this->LibProspCommStatut($this->stcomm_id, $mode, $label, $this->stcomm_picto); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -3901,45 +3909,45 @@ class Societe extends CommonObject * @param int|string $status Id or code for prospection status * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto * @param string $label Label to use for status for added status + * @param string $picto Name of image file to show ('filenew', ...) + * If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory. + * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img + * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img + * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) * @return string Label of prospection status */ - public function LibProspCommStatut($status, $mode = 0, $label = '') + public function LibProspCommStatut($status, $mode = 0, $label = '', $picto = '') { // phpcs:enable global $langs; $langs->load('customers'); - if ($mode == 2) - { - if ($status == '-1' || $status == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1).' '.$langs->trans("StatusProspect-1"); - elseif ($status == '0' || $status == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0).' '.$langs->trans("StatusProspect0"); - elseif ($status == '1' || $status == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1).' '.$langs->trans("StatusProspect1"); - elseif ($status == '2' || $status == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2).' '.$langs->trans("StatusProspect2"); - elseif ($status == '3' || $status == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3).' '.$langs->trans("StatusProspect3"); + if ($mode == 2) { + if ($status == '-1' || $status == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1, $picto).' '.$langs->trans("StatusProspect-1"); + elseif ($status == '0' || $status == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0, $picto).' '.$langs->trans("StatusProspect0"); + elseif ($status == '1' || $status == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto).' '.$langs->trans("StatusProspect1"); + elseif ($status == '2' || $status == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto).' '.$langs->trans("StatusProspect2"); + elseif ($status == '3' || $status == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto).' '.$langs->trans("StatusProspect3"); else { - return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0).' '.(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label); + return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0, $picto).' '.(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label); } - } - if ($mode == 3) - { - if ($status == '-1' || $status == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1); - elseif ($status == '0' || $status == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0); - elseif ($status == '1' || $status == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1); - elseif ($status == '2' || $status == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2); - elseif ($status == '3' || $status == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3); + } elseif ($mode == 3) { + if ($status == '-1' || $status == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1, $picto); + elseif ($status == '0' || $status == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0, $picto); + elseif ($status == '1' || $status == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto); + elseif ($status == '2' || $status == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto); + elseif ($status == '3' || $status == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto); else { - return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0); + return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0, $picto); } - } - if ($mode == 4) - { - if ($status == '-1' || $status == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1).' '.$langs->trans("StatusProspect-1"); - elseif ($status == '0' || $status == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0).' '.$langs->trans("StatusProspect0"); - elseif ($status == '1' || $status == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1).' '.$langs->trans("StatusProspect1"); - elseif ($status == '2' || $status == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2).' '.$langs->trans("StatusProspect2"); - elseif ($status == '3' || $status == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3).' '.$langs->trans("StatusProspect3"); + } elseif ($mode == 4) { + if ($status == '-1' || $status == 'ST_NO') return img_action($langs->trans("StatusProspect-1"), -1, $picto).' '.$langs->trans("StatusProspect-1"); + elseif ($status == '0' || $status == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0, $picto).' '.$langs->trans("StatusProspect0"); + elseif ($status == '1' || $status == 'ST_TODO') return img_action($langs->trans("StatusProspect1"), 1, $picto).' '.$langs->trans("StatusProspect1"); + elseif ($status == '2' || $status == 'ST_PEND') return img_action($langs->trans("StatusProspect2"), 2, $picto).' '.$langs->trans("StatusProspect2"); + elseif ($status == '3' || $status == 'ST_DONE') return img_action($langs->trans("StatusProspect3"), 3, $picto).' '.$langs->trans("StatusProspect3"); else { - return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0).' '.(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label); + return img_action(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label, 0, $picto).' '.(($langs->trans("StatusProspect".$status) != "StatusProspect".$status) ? $langs->trans("StatusProspect".$status) : $label); } } diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 4de868a1b27..71e214af5c0 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -10,6 +10,7 @@ * Copyright (C) 2017 Rui Strecht * Copyright (C) 2017 Juanjo Menent * Copyright (C) 2018 Nicolas ZABOURI + * Copyright (C) 2020 Open-Dsi * * This program is free software; you can redistribute it and/or modify @@ -392,7 +393,7 @@ if ($resql) $sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.barcode, s.town, s.zip, s.datec, s.code_client, s.code_fournisseur, s.logo,"; $sql .= " s.entity,"; -$sql .= " st.libelle as stcomm, s.fk_stcomm as stcomm_id, s.fk_prospectlevel, s.prefix_comm, s.client, s.fournisseur, s.canvas, s.status as status,"; +$sql .= " st.libelle as stcomm, st.picto as stcomm_picto, s.fk_stcomm as stcomm_id, s.fk_prospectlevel, s.prefix_comm, s.client, s.fournisseur, s.canvas, s.status as status,"; $sql .= " s.email, s.phone, s.fax, s.url, s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4 as idprof4, s.idprof5 as idprof5, s.idprof6 as idprof6, s.tva_intra, s.fk_pays,"; $sql .= " s.tms as date_update, s.datec as date_creation,"; $sql .= " s.code_compta, s.code_compta_fournisseur, s.parent as fk_parent,"; @@ -1195,6 +1196,7 @@ while ($i < min($num, $limit)) print "".$obj->idprof6."\n"; if (!$i) $totalarray['nbfield']++; } + // VAT if (!empty($arrayfields['s.tva_intra']['checked'])) { print ""; @@ -1241,13 +1243,13 @@ while ($i < min($num, $limit)) { // Prospect status print '
'; - print '
'.$companystatic->LibProspCommStatut($obj->stcomm_id, 2, $prospectstatic->cacheprospectstatus[$obj->stcomm_id]['label']); + print '
' . $companystatic->LibProspCommStatut($obj->stcomm_id, 2, $prospectstatic->cacheprospectstatus[$obj->stcomm_id]['label'], $obj->stcomm_picto); print '
-
'; foreach ($prospectstatic->cacheprospectstatus as $key => $val) { $titlealt = 'default'; if (!empty($val['code']) && !in_array($val['code'], array('ST_NO', 'ST_NEVER', 'ST_TODO', 'ST_PEND', 'ST_DONE'))) $titlealt = $val['label']; - if ($obj->stcomm_id != $val['id']) print ''.img_action($titlealt, $val['code']).''; + if ($obj->stcomm_id != $val['id']) print '' . img_action($titlealt, $val['code'], $val['picto']) . ''; } print '
'; if (!$i) $totalarray['nbfield']++; diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index d872c9dfef3..e02a41dab86 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -848,7 +848,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; print ''; print ''; - print ''; + print ''; print ''; } print ''; @@ -903,7 +903,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' print ''; print ''; print ''; - //print ''; + //print ''; print ''; } print ''; diff --git a/htdocs/societe/tpl/linesalesrepresentative.tpl.php b/htdocs/societe/tpl/linesalesrepresentative.tpl.php index 5b9078e6b76..9c6e485e97d 100644 --- a/htdocs/societe/tpl/linesalesrepresentative.tpl.php +++ b/htdocs/societe/tpl/linesalesrepresentative.tpl.php @@ -29,7 +29,7 @@ print $langs->trans('SalesRepresentatives'); print ''; if ($action != 'editsalesrepresentatives' && $user->rights->societe->creer) { print ''; - print 'id . '">' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . ''; + print 'id . '">' . img_edit($langs->transnoentitiesnoconv('Edit'), 1) . ''; print ''; } print ''; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 9d6ce02c8ee..44d5e3bbd1a 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2630,6 +2630,7 @@ class SupplierProposal extends CommonObject global $conf, $langs; $langs->load("supplier_proposal"); + $outputlangs->load("products"); if (!dol_strlen($modele)) { $modele = 'aurore'; diff --git a/htdocs/takepos/admin/bar.php b/htdocs/takepos/admin/bar.php index 3d4bd490dde..b6a06dee9fb 100644 --- a/htdocs/takepos/admin/bar.php +++ b/htdocs/takepos/admin/bar.php @@ -105,14 +105,16 @@ print "\n"; if ($conf->global->TAKEPOS_BAR_RESTAURANT && $conf->global->TAKEPOS_PRINT_METHOD != "browser") { print ''; print $langs->trans("OrderPrinters").' ('.$langs->trans("Setup").')'; - print ''; + print ''; + print ''; print ajax_constantonoff("TAKEPOS_ORDER_PRINTERS", array(), $conf->entity, 0, 0, 1, 0); //print $form->selectyesno("TAKEPOS_ORDER_PRINTERS", $conf->global->TAKEPOS_ORDER_PRINTERS, 1); print ''; print ''; print $langs->trans("OrderNotes"); - print ''; + print ''; + print ''; print ajax_constantonoff("TAKEPOS_ORDER_NOTES", array(), $conf->entity, 0, 0, 1, 0); //print $form->selectyesno("TAKEPOS_ORDER_NOTES", $conf->global->TAKEPOS_ORDER_NOTES, 1); print ''; @@ -120,14 +122,16 @@ if ($conf->global->TAKEPOS_BAR_RESTAURANT && $conf->global->TAKEPOS_PRINT_METHOD print ''; print $langs->trans("BasicPhoneLayout"); -print ''; +print ''; +print ''; //print $form->selectyesno("TAKEPOS_PHONE_BASIC_LAYOUT", $conf->global->TAKEPOS_PHONE_BASIC_LAYOUT, 1); print ajax_constantonoff("TAKEPOS_PHONE_BASIC_LAYOUT", array(), $conf->entity, 0, 0, 1, 0); print ''; print ''; print $langs->trans("ProductSupplements"); -print ''; +print ''; +print ''; //print $form->selectyesno("TAKEPOS_SUPPLEMENTS", $conf->global->TAKEPOS_SUPPLEMENTS, 1); print ajax_constantonoff("TAKEPOS_SUPPLEMENTS", array(), $conf->entity, 0, 0, 1, 0); print ''; @@ -136,55 +140,30 @@ if ($conf->global->TAKEPOS_SUPPLEMENTS) { print ''; print $langs->trans("SupplementCategory"); - print ''; + print ''; + print ''; print $form->select_all_categories(Categorie::TYPE_PRODUCT, $conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, 'TAKEPOS_SUPPLEMENTS_CATEGORY', 64, 0, 0); print ajax_combobox('TAKEPOS_SUPPLEMENTS_CATEGORY'); print "\n"; } -print ''; -print 'QR - '.$langs->trans("AutoOrder"); -print ''; -print ajax_constantonoff("TAKEPOS_AUTO_ORDER", array(), $conf->entity, 0, 0, 1, 0); -print ''; - print ''; print 'QR - '.$langs->trans("CustomerMenu"); -print ''; +print ''; +print ''; print ajax_constantonoff("TAKEPOS_QR_MENU", array(), $conf->entity, 0, 0, 1, 0); print ''; +print ''; +print 'QR - '.$langs->trans("AutoOrder"); +print ''; +print ''; +print ajax_constantonoff("TAKEPOS_AUTO_ORDER", array(), $conf->entity, 0, 0, 1, 0); +print ''; + print ''; -if ($conf->global->TAKEPOS_AUTO_ORDER) -{ - print '
'; - print ''; - print ''; - print ''; - print "\n"; - - //global $dolibarr_main_url_root; - $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 - $sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables"; - $resql = $db->query($sql); - $rows = array(); - while ($row = $db->fetch_array($resql)) { - print ''; - } - - print '
'.$langs->trans("Table").''.$langs->trans("URL").''.$langs->trans("QR").'
'; - print $langs->trans("Table")." ".$row['label']; - print ''; - print "".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid']).""; - print ''; - print ""; - print '
'; -} - - if ($conf->global->TAKEPOS_QR_MENU) { $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); @@ -192,16 +171,46 @@ if ($conf->global->TAKEPOS_QR_MENU) print '
'; print ''; print ''; - print ''; + print ''; print "\n"; print ''; + print ''; print '
'.$langs->trans("URL").''.$langs->trans("QR").''.$langs->trans("URL").''.$langs->trans("QR").'
'; print "".$urlwithroot."/takepos/public/menu.php"; - print ''; + print ''; print ""; print '
'; } +if ($conf->global->TAKEPOS_AUTO_ORDER) +{ + print '
'; + print ''; + print ''; + print ''; + print "\n"; + + //global $dolibarr_main_url_root; + $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 + $sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables"; + $resql = $db->query($sql); + $rows = array(); + while ($row = $db->fetch_array($resql)) { + print ''; + print ''; + print ''; + } + + print '
'.$langs->trans("Table").''.$langs->trans("URL").''.$langs->trans("QR").'
'; + print $langs->trans("Table")." ".$row['label']; + print ''; + print "".$urlwithroot."/takepos/public/auto_order.php?key=".dol_encode($row['rowid']).""; + print ''; + print ""; + print '
'; +} + print '
'; print '
'; diff --git a/htdocs/takepos/admin/receipt.php b/htdocs/takepos/admin/receipt.php index af5b8fdf8db..59e0f3da96c 100644 --- a/htdocs/takepos/admin/receipt.php +++ b/htdocs/takepos/admin/receipt.php @@ -89,7 +89,7 @@ print load_fiche_titre($langs->trans("PrintMethod"), '', ''); print ''; print ''; -print ''; +print ''; print "\n"; // Browser method @@ -97,7 +97,7 @@ print '\n"; +// Gift receipt +print '\n"; + // Numbering module //print ' - - + + @@ -140,8 +142,8 @@ if ($conf->global->TAKEPOS_SHOW_CUSTOMER) else echo $line->description; ?> - - + + global->TAKEPOS_SHOW_CUSTOMER)
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status").''.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status").'
'; print $langs->trans('Browser'); print ''; print $langs->trans('BrowserMethodDescription'); -print ''; +print ''; if ($conf->global->TAKEPOS_PRINT_METHOD == "browser") { print img_picto($langs->trans("Activated"), 'switch_on'); @@ -114,7 +114,7 @@ if ($conf->global->MAIN_FEATURES_LEVEL >= 1) { print $langs->trans('ReceiptPrinterMethodDescription'); print '
'; print ''.$langs->trans("Setup").''; - print '
'; + print ''; if ($conf->receiptprinter->enabled) { if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter") { print img_picto($langs->trans("Activated"), 'switch_on'); @@ -134,7 +134,7 @@ print '
'; print "TakePOS Connector"; print ''; print $langs->trans('TakeposConnectorMethodDescription'); -print ''; +print ''; if ($conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { print img_picto($langs->trans("Activated"), 'switch_on'); diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php index 830e5d203d3..22355c70d9d 100644 --- a/htdocs/takepos/admin/setup.php +++ b/htdocs/takepos/admin/setup.php @@ -365,6 +365,13 @@ print ''; print ajax_constantonoff("TAKEPOS_CONTROL_CASH_OPENING", array(), $conf->entity, 0, 0, 1, 0); print "
'; +print $langs->trans('GiftReceiptButton'); +print ''; +print ajax_constantonoff("TAKEPOS_GIFT_RECEIPT", array(), $conf->entity, 0, 0, 1, 0); +print "
'; //print $langs->trans("BillsNumberingModule"); diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index ab5acc1ac50..ee304b7438e 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -529,8 +529,19 @@ function Search2(keyCodeForEnter) { ClickProduct(0); } } + if (eventKeyCode == keyCodeForEnter){ + if (data.length == 0) { + $('#search').val('load('errors'); + echo dol_escape_js($langs->trans("ErrorRecordNotFound")); + ?>'); + $('#search').select(); + } + else ClearSearch(); + } }); } + } function Edit(number) { @@ -631,7 +642,7 @@ function TakeposPrintingTemp(){ } function OpenDrawer(){ - console.log("OpenDrawer"); + console.log("OpenDrawer call ajax url http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print"); $.ajax({ type: "POST", url: 'http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print', @@ -640,7 +651,7 @@ function OpenDrawer(){ } function DolibarrOpenDrawer() { - console.log("DolibarrOpenDrawer"); + console.log("DolibarrOpenDrawer call ajax url /takepos/ajax/ajax.php?action=opendrawer&term="); $.ajax({ type: "GET", url: "", diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index c6b7bb2c734..cfde72c9fd3 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -348,6 +348,7 @@ if ($action == "addline") } } if ($idoflineadded <= 0) { + $invoice->fetch_thirdparty(); $idoflineadded = $invoice->addline($prod->description, $price, 1, $tva_tx, $localtax1_tx, $localtax2_tx, $idproduct, $customer->remise_percent, '', 0, 0, 0, '', $price_base_type, $price_ttc, $prod->type, -1, 0, '', 0, $parent_line, null, '', '', 0, 100, '', null, 0); } @@ -597,6 +598,9 @@ if ($action == "valid" || $action == "history") $sectionwithinvoicelink .= ' '; } else { $sectionwithinvoicelink .= ' '; + if ($conf->global->TAKEPOS_GIFT_RECEIPT) { + $sectionwithinvoicelink .= '
'; + } } if ($conf->global->TAKEPOS_EMAIL_TEMPLATE_INVOICE > 0) { @@ -700,8 +704,8 @@ function SendTicket(id) $.colorbox({href:"send.php?facid="+id, width:"70%", height:"30%", transition:"none", iframe:"true", title:"trans("SendTicket"); ?>"}); } -function Print(id){ - $.colorbox({href:"receipt.php?facid="+id, width:"40%", height:"90%", transition:"none", iframe:"true", title:"trans("PrintTicket"); ?>"}); } @@ -718,6 +722,7 @@ function TakeposPrinting(id){ } function TakeposConnector(id){ + console.log("TakeposConnector" + id); var invoice='" + id, diff --git a/htdocs/takepos/public/menu.php b/htdocs/takepos/public/menu.php index c051ae4d673..217da157c2f 100644 --- a/htdocs/takepos/public/menu.php +++ b/htdocs/takepos/public/menu.php @@ -45,7 +45,7 @@ if (!$conf->global->TAKEPOS_QR_MENU) accessforbidden(); // If Restaurant Menu is
diff --git a/htdocs/takepos/receipt.php b/htdocs/takepos/receipt.php index 1da92de8827..99000c278de 100644 --- a/htdocs/takepos/receipt.php +++ b/htdocs/takepos/receipt.php @@ -34,6 +34,8 @@ $place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : 0); // $place is $facid = GETPOST('facid', 'int'); +$gift = GETPOST('gift', 'int'); + if (empty($user->rights->takepos->run)) { accessforbidden(); } @@ -125,8 +127,8 @@ if ($conf->global->TAKEPOS_SHOW_CUSTOMER)
trans("Label"); ?> trans("Qty"); ?>trans("Price"); ?>trans("TotalTTC"); ?>trans("Price"); ?>trans("TotalTTC"); ?>
qty; ?>total_ttc / $line->qty, 'MT'), 1); ?>total_ttc, 1); ?>total_ttc / $line->qty, 'MT'), 1); ?>total_ttc, 1); ?>
- - + + global->TAKEPOS_TICKET_VAT_GROUPPED) { $vat_groups = array(); @@ -166,18 +168,18 @@ if ($conf->global->TAKEPOS_SHOW_CUSTOMER) foreach ($vat_groups as $key => $val) { ?> - - + + - + - +
trans("TotalHT"); ?>total_ht, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>trans("TotalHT"); ?>total_ht, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>
trans("VAT").' '.vatrate($key, 1); ?>currency)."\n"; ?>trans("VAT").' '.vatrate($key, 1); ?>currency)."\n"; ?>
trans("TotalVAT").''.price($object->total_tva, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>trans("TotalVAT").''.price($object->total_tva, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>
trans("TotalTTC").''.price($object->total_ttc, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>trans("TotalTTC").''.price($object->total_ttc, 1, '', 1, - 1, - 1, $conf->currency)."\n"; ?>
diff --git a/htdocs/theme/eldy/badges.inc.php b/htdocs/theme/eldy/badges.inc.php index d2a59447bb9..36296bb0b8a 100644 --- a/htdocs/theme/eldy/badges.inc.php +++ b/htdocs/theme/eldy/badges.inc.php @@ -24,6 +24,18 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); font-size: 0.95em; padding: .19em .35em; /* more than 0.19 generate a change into heigth of lines */ } +.tabBar .arearef .statusref .badge-status, .tabBar .arearefnobottom .statusref .badge-status { + font-size: 1.1em; + padding: .4em .4em; +} +/* Force values for small screen 767 */ +@media only screen and (max-width: 767px) +{ + .tabBar .arearef .statusref .badge-status, .tabBar .arearefnobottom .statusref .badge-status { + font-size: 0.95em; + padding: .3em .2em; + } +} .badge-pill, .tabs .badge { padding-right: .5em; diff --git a/htdocs/theme/eldy/btn.inc.php b/htdocs/theme/eldy/btn.inc.php index e78d82592bb..dc3245abc4c 100644 --- a/htdocs/theme/eldy/btn.inc.php +++ b/htdocs/theme/eldy/btn.inc.php @@ -9,14 +9,18 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> --btncolorborder: #FFF; --butactiondeletebg: rgb(234,228,225); /* tertiary color */ - --butactionbg:rgb(218, 235, 225); + /* --butactionbg:rgb(218, 235, 225); */ /* --butactionbg:rgb(228, 218, 235); */ + --butactionbg:rgb(118, 145, 225); } global->MAIN_THEME_DARKMODEENABLED)) { +if (!empty($conf->global->THEME_DARKMODEENABLED)) { + print "/* For dark mode */\n"; + if ($conf->global->THEME_DARKMODEENABLED != 2) { + print "@media (prefers-color-scheme: dark) {"; + } print " - @media (prefers-color-scheme: dark) { :root { --btncolortext: ; @@ -26,8 +30,10 @@ if (!empty($conf->global->MAIN_THEME_DARKMODEENABLED)) { --butactionbg:rgb(173,140,79); --butactiondeletebg: rgb(252,84,91); - } - }"; + }\n"; + if ($conf->global->THEME_DARKMODEENABLED != 2) { + print "}"; + } } ?> @@ -53,6 +59,8 @@ span.butAction, span.butActionDelete { .butAction { background: var(--butactionbg); + color: #FFF !important; + border-radius: 3px; /* background: rgb(230, 232, 239); */ } .butActionRefused, .butAction, .butAction:link, .butAction:visited, .butAction:hover, .butAction:active, .butActionDelete, .butActionDelete:link, .butActionDelete:visited, .butActionDelete:hover, .butActionDelete:active { @@ -72,10 +80,10 @@ span.butAction, span.butActionDelete { /* border: 1px solid #aaa; */ /* border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25); */ - border-top-right-radius: 0 !important; + /*border-top-right-radius: 0 !important; border-bottom-right-radius: 0 !important; border-top-left-radius: 0 !important; - border-bottom-left-radius: 0 !important; + border-bottom-left-radius: 0 !important;*/ } .butActionNew, .butActionNewRefused, .butActionNew:link, .butActionNew:visited, .butActionNew:hover, .butActionNew:active { text-decoration: none; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 4ef3bef90d1..972221079c9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -34,7 +34,7 @@ --oddevencolor: #202020; --colorboxstatsborder: #e0e0e0; --dolgraphbg: rgba(255,255,255,0); - --fieldrequiredcolor: #000055; + --fieldrequiredcolor: #804000; --colortextbacktab: #; --colorboxiconbg: #eee; --refidnocolor:#444; @@ -45,10 +45,12 @@ } global->MAIN_THEME_DARKMODEENABLED)) { - print "@media (prefers-color-scheme: dark) { - :root { - +if (!empty($conf->global->THEME_DARKMODEENABLED)) { + print "/* For dark mode */\n"; + if ($conf->global->THEME_DARKMODEENABLED != 2) { + print "@media (prefers-color-scheme: dark) {"; + } + print ":root { --colorbackhmenu1: #1d1e20; --colorbackvmenu1: #2b2c2e; --colorbacktitle1: #2b2d2f; @@ -84,8 +86,10 @@ if (!empty($conf->global->MAIN_THEME_DARKMODEENABLED)) { --amountremaintopaycolor:rgb(252,84,91); --amountpaymentcomplete:rgb(101,184,77); --amountremaintopaybackcolor:rbg(245,130,46); - } - }"; + }\n"; + if ($conf->global->THEME_DARKMODEENABLED != 2) { + print "}\n"; + } } ?> @@ -186,9 +190,18 @@ input, select { } #mainbody input.button:not(.buttongen):not(.bordertransp) { background: var(--butactionbg); + color: #FFF !important; + + /* -webkit-box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); + box-shadow: 0px 0px 1px 1px rgba(0, 0, 0, 0.2), 0px 0px 0px rgba(60,60,60,0.1); */ + + border-radius: 3px; border-collapse: collapse; border: none; } +#mainbody span.websitetools input.button:not(.buttongen):not(.bordertransp) { + color: #000 !important; +} #mainbody input.buttongen, #mainbody button.buttongen { padding: 3px 4px; } @@ -372,6 +385,9 @@ input.pageplusone { .colorwhite { color: #fff; } +.colorgrey { + color: #888 !important; +} .colorblack { color: #000; } @@ -1796,6 +1812,9 @@ img.photoref, div.photoref { width: 80px; object-fit: contain; } +div.photoref .fa, div.photoref .fas, div.photoref .far { + font-size: 2.5em; +} img.fitcontain { object-fit: contain; } @@ -3245,11 +3264,7 @@ div.pagination li:first-child span { /*border-top-left-radius: 4px; border-bottom-left-radius: 4px;*/ } -div.pagination li:last-child a, -div.pagination li:last-child span { - /*border-top-right-radius: 4px; - border-bottom-right-radius: 4px;*/ -} + div.pagination li a:hover, div.pagination li:not(.paginationafterarrows,.title-button) span:hover, div.pagination li a:focus, @@ -3972,10 +3987,11 @@ div.boximport { .product_line_stock_ok { color: #002200; } .product_line_stock_too_low { color: #884400; } -.fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor); } +.fieldrequired { font-weight: bold; color: var(--fieldrequiredcolor) !important; } td.widthpictotitle { width: 26px; text-align: ; } -span.widthpictotitle { font-size: 1.7em; }; +span.widthpictotitle { font-size: 1.7em; } +table.titlemodulehelp tr td img.widthpictotitle { width: 80px; } .dolgraphtitle { margin-top: 6px; margin-bottom: 4px; } .dolgraphtitlecssboxes { /* margin: 0px; */ } @@ -4040,6 +4056,8 @@ div.titre { } div.fiche > table.table-fiche-title:first-of-type div { color: var(--colortexttitlenotab); + font-size: 1.05em; + /* text-transform: uppercase; */ /* font-weight: 600; */ } div.titre { diff --git a/htdocs/theme/eldy/info-box.inc.php b/htdocs/theme/eldy/info-box.inc.php index b995b551f43..b009d7ef95b 100644 --- a/htdocs/theme/eldy/info-box.inc.php +++ b/htdocs/theme/eldy/info-box.inc.php @@ -101,6 +101,13 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> max-width: 60%; } +a.info-box-text.info-box-text-a { + display: table-cell; +} +a.info-box-text-a i.fa.fa-exclamation-triangle { + font-size: 0.9em; +} + .info-box-icon-text{ box-sizing: border-box; display: block; @@ -166,15 +173,21 @@ if (!defined('ISLOADEDBYSTEELSHEET')) die('Must be call by steelsheet'); ?> padding: 5px 10px; margin-left: 84px; } - .info-box-sm .info-box-content{ margin-left: 80px; } -/*.info-box-setup span { - color: var(--colortexttitlenotab2); +.info-box-sm .info-box-module-enabled { + /* background: linear-gradient(0.35turn, #fff, #fff, #f6faf8, #e4efe8) */ + background: linear-gradient(0.4turn, #fff, #fff, #fff, #e4efe8); } -.tdsetuppicto span { - color: var(--colortexttitlenotab2); +.info-box-content-warning span.font-status4 { + color: #bc9526 !important; +} +/*.info-box-sm .info-box-content-warning { + background: #ffd7a3; +}*/ +/*.info-box-icon.info-box-icon-module-enabled { + background: #e4f0e4 !important; }*/ .info-box-number { @@ -212,6 +225,8 @@ a.info-box-text{ text-decoration: none;} + + /* ICONS INFO BOX */ global->THEME_SATURATE_RATIO = border-radius: 3px; } + + .bg-infobox-project{ color: #6c6aa8 !important; } diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index 98f9e311274..b9f630872ae 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -66,6 +66,7 @@ else header('Cache-Control: no-cache'); if (GETPOST('theme', 'alpha')) $conf->theme = GETPOST('theme', 'alpha'); // If theme was forced on URL if (GETPOST('lang', 'aZ09')) $langs->setDefaultLang(GETPOST('lang', 'aZ09')); // If language was forced on URL +if (GETPOST('THEME_DARKMODEENABLED', 'int')) $conf->global->THEME_DARKMODEENABLED = GETPOST('THEME_DARKMODEENABLED', 'int'); // If darkmode was forced on URL $langs->load("main", 0, 1); $right = ($langs->trans("DIRECTION") == 'rtl' ? 'left' : 'right'); diff --git a/htdocs/theme/eldy/theme_vars.inc.php b/htdocs/theme/eldy/theme_vars.inc.php index 3ce29206c0d..cd88654e309 100644 --- a/htdocs/theme/eldy/theme_vars.inc.php +++ b/htdocs/theme/eldy/theme_vars.inc.php @@ -65,7 +65,7 @@ $colorbacklinepairhover = '230,237,244'; // line hover $colorbacklinepairchecked = '230,237,244'; // line checked $colorbacklinebreak = '248,247,244'; // line break $colorbackbody = '255,255,255'; -$colortexttitlenotab = '0,123,140'; // 150,90,121 140,80,10 or 10,140,80 #875a7b green=0,123,140, violet: 0,50,120 +$colortexttitlenotab = '10,120,140'; // 150,90,121 140,80,10 or 10,140,80 #875a7b green=0,123,140, violet: 0,50,120 $colortexttitlenotab2 = '100,0,100'; // 150,90,121 140,80,10 or 10,140,80 #875a7b green=0,123,140, violet: 0,50,120 $colortexttitle = '0,0,0'; $colortexttitlelink = '10, 20, 100'; @@ -87,11 +87,11 @@ $colorblind_deuteranopes_textWarning = $textWarning; // currently not tested wit // Badges colors $badgePrimary = '#007bff'; -$badgeSecondary = '#cccccc'; +$badgeSecondary = '#aaaabb'; +$badgeInfo = '#aaaabb'; $badgeSuccess = '#55a580'; $badgeWarning = '#bc9526'; // See $textWarning bc9526 $badgeDanger = '#9f4705'; // See $textDanger -$badgeInfo = '#aaaabb'; $badgeDark = '#343a40'; $badgeLight = '#f8f9fa'; diff --git a/htdocs/theme/md/info-box.inc.php b/htdocs/theme/md/info-box.inc.php index e53f5d1f914..926e59aef51 100644 --- a/htdocs/theme/md/info-box.inc.php +++ b/htdocs/theme/md/info-box.inc.php @@ -108,6 +108,13 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) $conf->global->THEME_SATURATE_RATIO = background: #bbb; } +a.info-box-text.info-box-text-a { + display: table-cell; +} +a.info-box-text-a i.fa.fa-exclamation-triangle { + font-size: 0.9em; +} + .info-box { display: block; position: relative; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 6c20f4d66c1..fb9f0239d10 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -3862,6 +3862,7 @@ div.boximport { .fieldrequired { font-weight: bold; color: #000055; } .widthpictotitle { width: 40px; font-size: 1.4em; text-align: ; } +table.titlemodulehelp tr td img.widthpictotitle { width: 80px; } .dolgraphtitle { margin-top: 6px; margin-bottom: 4px; } .dolgraphtitlecssboxes { /* margin: 0px; */ } diff --git a/htdocs/ticket/agenda.php b/htdocs/ticket/agenda.php index 3d1b89e6c65..13874eb7ecb 100644 --- a/htdocs/ticket/agenda.php +++ b/htdocs/ticket/agenda.php @@ -235,6 +235,8 @@ if (!empty($object->id)) $messagingUrl = DOL_URL_ROOT.'/ticket/messaging.php?track_id='.$object->track_id; $morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1); + $messagingUrl = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id; + $morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-list-alt imgforviewmode', $messagingUrl, '', 1, array('morecss'=>'btnTitleSelected')); // Show link to add a message (if read and not closed) $btnstatus = $object->fk_statut < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage"; @@ -246,7 +248,6 @@ if (!empty($object->id)) $url = dol_buildpath('/comm/action/card.php', 1).'?action=create&datep='.date('YmdHi').'&origin=ticket&originid='.$object->id.'&projectid='.$object->fk_project.'&backtopage='.urlencode($_SERVER["PHP_SELF"]); $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', $url, 'add-new-ticket-even-button', $btnstatus); - print_barre_liste($langs->trans("ActionsOnTicket"), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1); // List of all actions diff --git a/htdocs/ticket/messaging.php b/htdocs/ticket/messaging.php index b7d4c3d7b21..fc0bce96cb8 100644 --- a/htdocs/ticket/messaging.php +++ b/htdocs/ticket/messaging.php @@ -232,9 +232,12 @@ if (!empty($object->id)) $morehtmlright = ''; + $messagingUrl = DOL_URL_ROOT.'/ticket/messaging.php?track_id='.$object->track_id; + $morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1, array('morecss'=>'btnTitleSelected')); $messagingUrl = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id; $morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-list-alt imgforviewmode', $messagingUrl, '', 1); + // Show link to add a message (if read and not closed) $btnstatus = $object->fk_statut < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage"; $url = 'card.php?track_id='.$object->track_id.'&action=presend_addmessage&mode=init'; diff --git a/htdocs/user/card.php b/htdocs/user/card.php index d74467a14b7..eb3cd67cf50 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -44,6 +44,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/usergroups.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; @@ -253,6 +254,8 @@ if (empty($reshook)) { $object->fk_warehouse = GETPOST('fk_warehouse', 'int'); + $object->lang = GETPOST('default_lang', 'aZ09'); + // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost(null, $object); if ($ret < 0) { @@ -415,6 +418,8 @@ if (empty($reshook)) { $object->fk_warehouse = GETPOST('fk_warehouse', 'int'); } + $object->lang = GETPOST('default_lang', 'aZ09'); + if (!empty($conf->multicompany->enabled)) { if (!empty($_POST["superadmin"])) @@ -671,6 +676,7 @@ if (empty($reshook)) { $form = new Form($db); $formother = new FormOther($db); $formcompany = new FormCompany($db); +$formadmin = new FormAdmin($db); $formfile = new FormFile($db); if (!empty($conf->stock->enabled)) $formproduct = new FormProduct($db); @@ -1113,6 +1119,14 @@ if ($action == 'create' || $action == 'adduserldap') print ""; } + if (!empty($conf->global->MAIN_MULTILANGS)) + { + print ''.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print $formadmin->select_language(GETPOST('default_lang', 'alpha') ?GETPOST('default_lang', 'alpha') : ($object->lang ? $object->lang : ''), 'default_lang', 0, 0, 1, 0, 0, 'maxwidth200onsmartphone'); + print ''; + print ''; + } + // Multicompany if (!empty($conf->multicompany->enabled) && is_object($mc)) { @@ -1654,6 +1668,19 @@ if ($action == 'create' || $action == 'adduserldap') print ''; } + // Default language + if (!empty($conf->global->MAIN_MULTILANGS)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + print ''.$langs->trans("DefaultLang").''; + //$s=picto_from_langcode($object->default_lang); + //print ($s?$s.' ':''); + $langs->load("languages"); + $labellang = ($object->lang ? $langs->trans('Language_'.$object->lang) : ''); + print $form->textwithpicto($labellang, $langs->trans("WarningNotLangOfInterface", $langs->transnoentitiesnoconv("UserGUISetup"))); + print ''; + } + if (isset($conf->file->main_authentication) && preg_match('/openid/', $conf->file->main_authentication) && !empty($conf->global->MAIN_OPENIDURL_PERUSER)) { print ''.$langs->trans("OpenIDURL").''; @@ -2446,6 +2473,15 @@ if ($action == 'create' || $action == 'adduserldap') print ""; } + // Default language + if (!empty($conf->global->MAIN_MULTILANGS)) + { + print ''.$form->editfieldkey('DefaultLang', 'default_lang', '', $object, 0).''."\n"; + print $formadmin->select_language($object->lang, 'default_lang', 0, 0, 1); + print ''; + print ''; + } + // Status print ''.$langs->trans("Status").''; print ''; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index cc794db045b..75c6a0a4d60 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -1549,6 +1549,7 @@ class User extends CommonObject $sql .= ", default_range = ".($this->default_range > 0 ? $this->default_range : 'null'); $sql .= ", default_c_exp_tax_cat = ".($this->default_c_exp_tax_cat > 0 ? $this->default_c_exp_tax_cat : 'null'); $sql .= ", fk_warehouse = ".($this->fk_warehouse ? "'".$this->db->escape($this->fk_warehouse)."'" : "null"); + $sql .= ", lang = ".($this->lang ? "'".$this->db->escape($this->lang)."'" : "null"); $sql .= " WHERE rowid = ".$this->id; diff --git a/htdocs/user/param_ihm.php b/htdocs/user/param_ihm.php index 1f0880b0fb3..2cb4f174b23 100644 --- a/htdocs/user/param_ihm.php +++ b/htdocs/user/param_ihm.php @@ -264,19 +264,6 @@ if ($action == 'edit') print ''; print ''; - // Landing page - print ''; - print ''; - print ''; - print ''; - // Language by default print ''; print ''; print ''; + print '> '; print ''; + // Landing page + print ''; + print ''; + print ''; + print ''; + + // Landing page for Agenda - AGENDA_DEFAULT_VIEW + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''; + print ''."\n"; + // Max size of lists print ''; print ''; print ''; + print '> '; print ''; - // AGENDA_DEFAULT_VIEW - print ''."\n"; - print ''."\n"; - print ''."\n"; - print ''; - print ''."\n"; - print '
'.$langs->trans("Parameter").''.$langs->trans("DefaultValue").' '.$langs->trans("PersonalValue").'
'.$langs->trans("LandingPage").''; - print (empty($conf->global->MAIN_LANDING_PAGE) ? '' : $conf->global->MAIN_LANDING_PAGE); - print 'conf->MAIN_LANDING_PAGE) ? " checked" : ""); - print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo - print '> '.$langs->trans("UsePersonalValue").''; - print $form->selectarray('MAIN_LANDING_PAGE', $tmparray, (!empty($object->conf->MAIN_LANDING_PAGE) ? $object->conf->MAIN_LANDING_PAGE : ''), 0, 0, 0, '', 1); - //print info_admin($langs->trans("WarningYouMayLooseAccess"), 0, 0, 0); - print '
'.$langs->trans("Language").''; @@ -286,31 +273,44 @@ if ($action == 'edit') print 'conf->MAIN_LANG_DEFAULT) ? " checked" : ""); print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo - print '> '.$langs->trans("UsePersonalValue").''; print $formadmin->select_language((!empty($object->conf->MAIN_LANG_DEFAULT) ? $object->conf->MAIN_LANG_DEFAULT : ''), 'main_lang_default', 1, null, 0, 0, (!empty($dolibarr_main_demo))); print '
'.$langs->trans("LandingPage").''; + print (empty($conf->global->MAIN_LANDING_PAGE) ? '' : $conf->global->MAIN_LANDING_PAGE); + print 'conf->MAIN_LANDING_PAGE) ? " checked" : ""); + print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo + print '> '; + print $form->selectarray('MAIN_LANDING_PAGE', $tmparray, (!empty($object->conf->MAIN_LANDING_PAGE) ? $object->conf->MAIN_LANDING_PAGE : ''), 0, 0, 0, '', 1); + //print info_admin($langs->trans("WarningYouMayLooseAccess"), 0, 0, 0); + print '
'.$langs->trans("AGENDA_DEFAULT_VIEW").' conf->AGENDA_DEFAULT_VIEW) ? " checked" : ""); + print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo + print '> '."\n"; + $tmplist = array(''=>' ', 'show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser")); + print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $object->conf->AGENDA_DEFAULT_VIEW, 0, 0, 0, ''); + print '
'.$langs->trans("MaxSizeList").''.$conf->global->MAIN_SIZE_LISTE_LIMIT.'conf->MAIN_SIZE_LISTE_LIMIT) ? " checked" : ""); print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo - print '> '.$langs->trans("UsePersonalValue").'
'.$langs->trans("AGENDA_DEFAULT_VIEW").' conf->AGENDA_DEFAULT_VIEW) ? " checked" : ""); - print empty($dolibarr_main_demo) ? '' : ' disabled="disabled"'; // Disabled for demo - print '> '.$langs->trans("UsePersonalValue").''."\n"; - $tmplist = array(''=>' ', 'show_list'=>$langs->trans("ViewList"), 'show_month'=>$langs->trans("ViewCal"), 'show_week'=>$langs->trans("ViewWeek"), 'show_day'=>$langs->trans("ViewDay"), 'show_peruser'=>$langs->trans("ViewPerUser")); - print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $object->conf->AGENDA_DEFAULT_VIEW, 0, 0, 0, ''); - print '

'; // Theme @@ -334,6 +334,20 @@ if ($action == 'edit') print ''; print ''; + // Language + print ''; + print ''; + print ''; + print ''; + // Landing page print ''; print ''; - // Language - print ''; - print ''; - print ''; - print ''; - - // Max size for lists - print ''; - print ''; - print ''; - print ''; - - // AGENDA_DEFAULT_VIEW + // Landing page for Agenda - AGENDA_DEFAULT_VIEW print ''."\n"; print ''."\n"; print ''."\n"; @@ -380,6 +374,12 @@ if ($action == 'edit') if (!empty($object->conf->AGENDA_DEFAULT_VIEW)) print $form->selectarray('AGENDA_DEFAULT_VIEW', $tmplist, $object->conf->AGENDA_DEFAULT_VIEW, 0, 0, 0, '', 0, 0, 1); print ''."\n"; + // Max size for lists + print ''; + print ''; + print ''; + print ''; + print '
'.$langs->trans("Parameter").''.$langs->trans("DefaultValue").' '.$langs->trans("PersonalValue").'
'.$langs->trans("Language").''; + $s = picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); + print ($s ? $s.' ' : ''); + print (isset($conf->global->MAIN_LANG_DEFAULT) && $conf->global->MAIN_LANG_DEFAULT == 'auto' ? $langs->trans("AutoDetectLang") : $langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); + print 'conf->MAIN_LANG_DEFAULT) ? " checked" : "").'> '.$langs->trans("UsePersonalValue").''; + $s = (isset($object->conf->MAIN_LANG_DEFAULT) ? picto_from_langcode($object->conf->MAIN_LANG_DEFAULT) : ''); + print ($s ? $s.' ' : ''); + print (isset($object->conf->MAIN_LANG_DEFAULT) && $object->conf->MAIN_LANG_DEFAULT == 'auto' ? $langs->trans("AutoDetectLang") : (!empty($object->conf->MAIN_LANG_DEFAULT) ? $langs->trans("Language_".$object->conf->MAIN_LANG_DEFAULT) : '')); + print '
'.$langs->trans("LandingPage").''; @@ -350,27 +364,7 @@ if ($action == 'edit') //print $form->selectarray('MAIN_LANDING_PAGE', $tmparray, (! empty($object->conf->MAIN_LANDING_PAGE)?$object->conf->MAIN_LANDING_PAGE:''), 0, 0, 0, '', 1); print '
'.$langs->trans("Language").''; - $s = picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); - print ($s ? $s.' ' : ''); - print (isset($conf->global->MAIN_LANG_DEFAULT) && $conf->global->MAIN_LANG_DEFAULT == 'auto' ? $langs->trans("AutoDetectLang") : $langs->trans("Language_".$conf->global->MAIN_LANG_DEFAULT)); - print 'conf->MAIN_LANG_DEFAULT) ? " checked" : "").'> '.$langs->trans("UsePersonalValue").''; - $s = (isset($object->conf->MAIN_LANG_DEFAULT) ? picto_from_langcode($object->conf->MAIN_LANG_DEFAULT) : ''); - print ($s ? $s.' ' : ''); - print (isset($object->conf->MAIN_LANG_DEFAULT) && $object->conf->MAIN_LANG_DEFAULT == 'auto' ? $langs->trans("AutoDetectLang") : (!empty($object->conf->MAIN_LANG_DEFAULT) ? $langs->trans("Language_".$object->conf->MAIN_LANG_DEFAULT) : '')); - print '
'.$langs->trans("MaxSizeList").''.(!empty($conf->global->MAIN_SIZE_LISTE_LIMIT) ? $conf->global->MAIN_SIZE_LISTE_LIMIT : ' ').'conf->MAIN_SIZE_LISTE_LIMIT) ? " checked" : "").'> '.$langs->trans("UsePersonalValue").''.(!empty($object->conf->MAIN_SIZE_LISTE_LIMIT) ? $object->conf->MAIN_SIZE_LISTE_LIMIT : ' ').'
'.$langs->trans("AGENDA_DEFAULT_VIEW").' 
'.$langs->trans("MaxSizeList").''.(!empty($conf->global->MAIN_SIZE_LISTE_LIMIT) ? $conf->global->MAIN_SIZE_LISTE_LIMIT : ' ').'conf->MAIN_SIZE_LISTE_LIMIT) ? " checked" : "").'> '.$langs->trans("UsePersonalValue").''.(!empty($object->conf->MAIN_SIZE_LISTE_LIMIT) ? $object->conf->MAIN_SIZE_LISTE_LIMIT : ' ').'

'; diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index c325e672043..768ddbdb19c 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -290,6 +290,7 @@ class Website extends CommonObject $sql .= ' t.rowid,'; $sql .= " t.entity,"; $sql .= " t.ref,"; + $sql .= " t.position,"; $sql .= " t.description,"; $sql .= " t.lang,"; $sql .= " t.otherlang,"; @@ -319,6 +320,7 @@ class Website extends CommonObject $this->entity = $obj->entity; $this->ref = $obj->ref; + $this->position = $obj->position; $this->description = $obj->description; $this->lang = $obj->lang; $this->otherlang = $obj->otherlang; @@ -670,7 +672,8 @@ class Website extends CommonObject $object->virtualhost = ''; $object->date_creation = $now; $object->fk_user_creat = $user->id; - $object->position = $object->position + 1; + $object->position = ((int) $object->position) + 1; + $object->status = self::STATUS_DRAFT; if (empty($object->lang)) $object->lang = substr($langs->defaultlang, 0, 2); // Should not happen. Protection for corrupted site with no languages // Create clone diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 1393f8254f3..e0afd583ea2 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2594,11 +2594,11 @@ if (!GETPOST('hide_websitemenu')) $textifempty = 1; $formquestion = array( array('type' => 'hidden', 'name' => 'sourcepageurl', 'value'=> $objectpage->pageurl), - array('type' => 'checkbox', 'tdclass'=>'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0), - array('type' => 'other', 'name' => 'newlang', 'label' => $form->textwithpicto($langs->trans("Language"), $langs->trans("DefineListOfAltLanguagesInWebsiteProperties")), 'value' => $formadmin->select_language($preselectedlanguage, 'newlang', 0, null, $textifempty, 0, 0, 'minwidth200', 0, 1, 0, $onlylang, 1)), - array('type' => 'other', 'name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)), + array('type' => 'other', 'tdclass'=>'fieldrequired', 'name' => 'newwebsite', 'label' => $langs->trans("WebSite"), 'value' => $formwebsite->selectWebsite($object->id, 'newwebsite', 0)), array('type' => 'text', 'tdclass'=>'maxwidth200 fieldrequired', 'name' => 'newtitle', 'label'=> $langs->trans("WEBSITE_TITLE"), 'value'=> $langs->trans("CopyOf").' '.$objectpage->title), array('type' => 'text', 'tdclass'=>'maxwidth200', 'name' => 'newpageurl', 'label'=> $langs->trans("WEBSITE_PAGENAME"), 'value'=> ''), + array('type' => 'checkbox', 'tdclass'=>'maxwidth200', 'name' => 'is_a_translation', 'label' => $langs->trans("PageIsANewTranslation"), 'value' => 0, 'morecss'=>'margintoponly'), + array('type' => 'other', 'name' => 'newlang', 'label' => $form->textwithpicto($langs->trans("Language"), $langs->trans("DefineListOfAltLanguagesInWebsiteProperties")), 'value' => $formadmin->select_language($preselectedlanguage, 'newlang', 0, null, $textifempty, 0, 0, 'minwidth200', 0, 1, 0, $onlylang, 1)), ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?website='.$object->ref.'&pageid='.$pageid, $langs->trans('ClonePage'), '', 'confirm_createpagefromclone', $formquestion, 0, 1, 300, 550); @@ -2972,6 +2972,15 @@ if ($action == 'editcss') print $websitekey; print ''; + // Status of web site + print ''."\n"; + print ''; + print $langs->trans('Status'); + print ''; + print ajax_object_onoff($object, 'status', 'status', 'Enabled', 'Disabled'); + //print dol_print_date($pagedatecreation, 'dayhour'); + print ''; + // Main language print ''; $htmltext = ''; @@ -3288,15 +3297,16 @@ if ($action == 'editmeta' || $action == 'createcontainer') if ($action != 'createcontainer') { - print ''; - print $langs->trans('IDOfPage'); + print ''; + print $langs->trans('IDOfPage').' - '.$langs->trans('InternalURLOfPage'); print ''; print $pageid; - print ''; + //print ''; - print ''; - print $langs->trans('InternalURLOfPage'); - print ''; + //print ''; + //print $langs->trans('InternalURLOfPage'); + //print ''; + print '   -   '; print '/public/website/index.php?website='.urlencode($websitekey).'&pageid='.urlencode($pageid); //if ($objectpage->grabbed_from) print ' - '.$langs->trans('InitiallyGrabbedFrom').' '.$objectpage->grabbed_from.''; print ''; @@ -3334,6 +3344,17 @@ if ($action == 'editmeta' || $action == 'createcontainer') if (GETPOST('WEBSITE_LANG', 'aZ09')) $pagelang = GETPOST('WEBSITE_LANG', 'aZ09'); if (GETPOST('htmlheader', 'none')) $pagehtmlheader = GETPOST('htmlheader', 'none'); + if ($action != 'createcontainer') + { + print ''."\n"; + print ''; + print $langs->trans('Status'); + print ''; + print ajax_object_onoff($objectpage, 'status', 'status', 'Enabled', 'Disabled'); + //print dol_print_date($pagedatecreation, 'dayhour'); + print ''; + } + // Type of container print ''; print $langs->trans('WEBSITE_TYPE_CONTAINER'); @@ -3555,17 +3576,6 @@ if ($action == 'editmeta' || $action == 'createcontainer') print $doleditor->Create(1, '', true, 'HTML Header', 'html'); print ''; - if ($action != 'createcontainer') - { - print ''."\n"; - print ''; - print $langs->trans('Status'); - print ''; - print ajax_object_onoff($objectpage, 'status', 'status', 'Enabled', 'Disabled'); - //print dol_print_date($pagedatecreation, 'dayhour'); - print ''; - } - print ''; if ($action == 'createcontainer') { @@ -3832,12 +3842,15 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print getTitleFieldOfList("Categories", 0, $_SERVER['PHP_SELF']); print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']); print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']); + print getTitleFieldOfList("", 0, $_SERVER['PHP_SELF']); print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; print ''; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $c = new Categorie($db); + $totalnbwords = 0; + foreach ($listofpages['list'] as $answerrecord) { if (get_class($answerrecord) == 'WebsitePage') @@ -3891,6 +3904,18 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print $answerrecord->lang; print ''; + // Number of words + print ''; + $textwithouthtml = dol_string_nohtmltag(dolStripPhpCode($answerrecord->content)); + $characterMap = 'áàéèëíóúüñùç0123456789'; + $nbofwords = str_word_count($textwithouthtml, 0, $characterMap); + if ($nbofwords) { + print $nbofwords.' '.$langs->trans("words"); + $totalnbwords += $nbofwords; + } + print ''; + + // Edit properties, HTML sources, status print ''; $disabled = ''; @@ -3967,6 +3992,15 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print ''; print ''; + // Categories - Tags + print ''; + print ''; + + // Nb of words + print ''; + print ''; + + // Edit properties, HTML sources, status print ''; print ''; @@ -3977,6 +4011,44 @@ if ($action == 'replacesite' || $action == 'replacesiteconfirm' || $massaction = print ''; } } + + if (count($listofpages['list']) >= 2) { + // Total + print ''; + + // Type of container + print ''; + print $langs->trans("Total"); + print ''; + + // Container url and label + print ''; + print ''; + + // Language + print ''; + print ''; + + // Categories - Tags + print ''; + print ''; + + // Nb of words + print ''; + print $totalnbwords.' '.$langs->trans("words"); + print ''; + + // Edit properties, HTML sources, status + print ''; + print ''; + + // Action column + print ''; + print ''; + + print ''; + } + print ''; print '
'; print '
'; diff --git a/htdocs/zapier/class/hook.class.php b/htdocs/zapier/class/hook.class.php index 0a6f39c777b..c9e8bd15d9e 100644 --- a/htdocs/zapier/class/hook.class.php +++ b/htdocs/zapier/class/hook.class.php @@ -354,10 +354,10 @@ class Hook extends CommonObject // ... // Clear extrafields that are unique if (is_array($object->array_options) && count($object->array_options) > 0) { - $extrafields->fetch_name_optionals_label($this->element); + $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->element]['unique'][$shortkey])) { + if (!empty($extrafields->attributes[$this->table_element]['unique'][$shortkey])) { // var_dump($key); // var_dump($clonedObj->array_options[$key]); // exit; diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 5a248006498..50ae74e5031 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -300,9 +300,9 @@ class SecurityTest extends PHPUnit\Framework\TestCase $this->assertEquals($genpass2, ''); $conf->global->USER_PASSWORD_GENERATED='Standard'; - $genpass3=getRandomPassword(false); // Should return a password of 8 chars + $genpass3=getRandomPassword(false); // Should return a password of 10 chars print __METHOD__." genpass3=".$genpass3."\n"; - $this->assertEquals(strlen($genpass3), 8); + $this->assertEquals(strlen($genpass3), 10); return 0; }