diff --git a/SECURITY.md b/SECURITY.md index e095b64fdff..3c89a2f38e1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -67,7 +67,7 @@ Scope is the web application (back office) and the APIs. * Remote code execution (RCE) * Local files access and manipulation (LFI, RFI, XXE, SSRF, XSPA) -* Code injections (HTML, JS, SQL, PHP, ...) +* Code injections (JS, SQL, PHP). HTML are covered only for fields that are not description, notes or comments fields (where rich content is allowed on purpose). * Cross-Site Scripting (XSS), except from setup page of module "External web site" (allowing any content here, editable by admin user only, is accepted on purpose) and except into module "Web site" when permission to edit website content is allowed (injecting any data in this case is allowed too). * Cross-Site Requests Forgery (CSRF) with real security impact (when using GET URLs, CSRF are qualified only for creating, updating or deleting data from pages restricted to admin users) * Open redirect diff --git a/htdocs/accountancy/index.php b/htdocs/accountancy/index.php index f5feef4a0f2..3a1944b3cf4 100644 --- a/htdocs/accountancy/index.php +++ b/htdocs/accountancy/index.php @@ -119,6 +119,7 @@ if (isModEnabled('accounting')) { print "
\n"; print ''.$langs->trans("AccountancyAreaDescIntro")."
\n"; if ($user->hasRight('accounting', 'chartofaccount')) { + print '
'; print load_fiche_titre(' '.$langs->trans("AccountancyAreaDescActionOnce"), '', '')."\n"; print '
'; print "
\n"; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 74df98e873a..e06ce655c73 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -441,7 +441,7 @@ class Adherent extends CommonObject * @param string $errors_to erros to * @param string $moreinheader Add more html headers * @deprecated since V18 - * @see sendEmail + * @see sendEmail() * @return int <0 if KO, >0 if OK */ public function send_an_email($text, $subject, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $addr_cc = "", $addr_bcc = "", $deliveryreceipt = 0, $msgishtml = -1, $errors_to = '', $moreinheader = '') diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 98093ef299a..90bb35320c0 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -581,11 +581,11 @@ print 'MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED = print '
'; $examplecsprule = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;"; -print 'MAIN_SECURITY_FORCECSPRO = '.getDolGlobalString('MAIN_SECURITY_FORCECSP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").': "'.$examplecsprule.'")
'; +print 'MAIN_SECURITY_FORCECSPRO = '.getDolGlobalString('MAIN_SECURITY_FORCECSPRO', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").': "'.$examplecsprule.'")
'; print '
'; $examplecsprule = "frame-ancestors 'self'; img-src * data:; font-src *; default-src 'self' 'unsafe-inline' 'unsafe-eval' *.paypal.com *.stripe.com *.google.com *.googleapis.com *.google-analytics.com *.googletagmanager.com;"; -print 'MAIN_SECURITY_FORCECSP = '.getDolGlobalString('MAIN_SECURITY_FORCERP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").': "'.$examplecsprule.'")
'; +print 'MAIN_SECURITY_FORCECSP = '.getDolGlobalString('MAIN_SECURITY_FORCECSP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Example").': "'.$examplecsprule.'")
'; print '
'; print 'MAIN_SECURITY_FORCERP = '.getDolGlobalString('MAIN_SECURITY_FORCERP', ''.$langs->trans("Undefined").'').'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or")." \"same-origin\" so browser doesn't send any referrer when going into another web site domain)
"; diff --git a/htdocs/api/class/api_access.class.php b/htdocs/api/class/api_access.class.php index 541682101c6..f246b20680c 100644 --- a/htdocs/api/class/api_access.class.php +++ b/htdocs/api/class/api_access.class.php @@ -113,15 +113,15 @@ class DolibarrApiAccess implements iAuthenticate $sql = "SELECT u.login, u.datec, u.api_key, "; $sql .= " u.tms as date_modification, u.entity"; $sql .= " FROM ".MAIN_DB_PREFIX."user as u"; - $sql .= " WHERE u.api_key = '".$this->db->escape($api_key)."'"; - // TODO Check if 2 users has same API key. + $sql .= " WHERE u.api_key = '".$this->db->escape($api_key)."' OR u.api_key = '".$this->db->escape(dolEncrypt($api_key, '', '', 'dolibarr'))."'"; $result = $this->db->query($sql); if ($result) { - if ($this->db->num_rows($result)) { + $nbrows = $this->db->num_rows($result); + if ($nbrows == 1) { $obj = $this->db->fetch_object($result); $login = $obj->login; - $stored_key = $obj->api_key; + $stored_key = dolDecrypt($obj->api_key); $userentity = $obj->entity; if (!defined("DOLENTITY") && $conf->entity != ($obj->entity ? $obj->entity : 1)) { // If API was not forced with HTTP_DOLENTITY, and user is on another entity, so we reset entity to entity of user @@ -130,6 +130,8 @@ class DolibarrApiAccess implements iAuthenticate dol_syslog("Entity was not set on http header with HTTP_DOLAPIENTITY (recommanded for performance purpose), so we switch now on entity of user (".$conf->entity.") and we have to reload configuration.", LOG_WARNING); $conf->setValues($this->db); } + } elseif ($nbrows > 1) { + throw new RestException(503, 'Error when fetching user api_key : More than 1 user with this apikey'); } } else { throw new RestException(503, 'Error when fetching user api_key :'.$this->db->error_msg); diff --git a/htdocs/api/class/api_login.class.php b/htdocs/api/class/api_login.class.php index 0b8d3e64828..7cad862b3be 100644 --- a/htdocs/api/class/api_login.class.php +++ b/htdocs/api/class/api_login.class.php @@ -18,6 +18,7 @@ use Luracast\Restler\RestException; +require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; /** @@ -152,7 +153,7 @@ class Login // We store API token into database $sql = "UPDATE ".MAIN_DB_PREFIX."user"; - $sql .= " SET api_key = '".$this->db->escape($token)."'"; + $sql .= " SET api_key = '".$this->db->escape(dolEncrypt($token, '', '', 'dolibarr'))."'"; $sql .= " WHERE login = '".$this->db->escape($login)."'"; dol_syslog(get_class($this)."::login", LOG_DEBUG); // No log diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index a36f944d6c5..f0354cba285 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -155,9 +155,6 @@ if (!empty($conf->global->AGENDA_REMINDER_EMAIL)) { $TDurationTypes = array('y'=>$langs->trans('Years'), 'm'=>$langs->trans('Month'), 'w'=>$langs->trans('Weeks'), 'd'=>$langs->trans('Days'), 'h'=>$langs->trans('Hours'), 'i'=>$langs->trans('Minutes')); $result = restrictedArea($user, 'agenda', $object->id, 'actioncomm&societe', 'myactions|allactions', 'fk_soc', 'id'); -if ($user->socid && $socid) { - $result = restrictedArea($user, 'societe', $socid); -} $usercancreate = $user->hasRight('agenda', 'allactions', 'create') || (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->rights->agenda->myactions->create); diff --git a/htdocs/comm/propal/agenda.php b/htdocs/comm/propal/agenda.php index f3b35d07cfe..cb321ebfde7 100644 --- a/htdocs/comm/propal/agenda.php +++ b/htdocs/comm/propal/agenda.php @@ -140,7 +140,7 @@ if ($object->id > 0) { // Object card // ------------------------------------------------------------ - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; $morehtmlref = '
'; // Ref customer diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index e65a1b5e1a3..cae98408d44 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -955,6 +955,8 @@ if (empty($reshook)) { $price_ttc = ''; $price_ttc_devise = ''; + // TODO Implement if (getDolGlobalInt('MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES')) + if (GETPOST('price_ht') !== '') { $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); } diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 75990668e5d..47e178292eb 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -871,6 +871,8 @@ class Propal extends CommonObject $txtva = preg_replace('/\s*\(.*\)/', '', $txtva); // Remove code into vatrate. } + // TODO Implement if (getDolGlobalInt('MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES')) ? + $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $type, $mysoc, $localtaxes_type, 100, $this->multicurrency_tx, $pu_ht_devise); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 5b0fd0bd105..13b9aa1a4fe 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -196,7 +196,7 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // List of fields to search into when doing a "search in all" $fieldstosearchall = array( 'p.ref'=>'Ref', - 'p.ref_client'=>'CustomerRef', + 'p.ref_client'=>'RefCustomer', 'pd.description'=>'Description', 's.nom'=>"ThirdParty", 's.name_alias'=>"AliasNameShort", diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index 177f68a1fbb..c665166b0af 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -223,6 +223,7 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); +$error = 0; /* @@ -1284,24 +1285,24 @@ if ($resql) { if ($permissiontovalidate) { $arrayofmassactions['prevalidate'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Validate"); } - if ($permissiontosendbymail) { - $arrayofmassactions['presend'] = img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"); - } if ($permissiontoclose) { $arrayofmassactions['preshipped'] = img_picto('', 'dollyrevert', 'class="pictofixedwidth"').$langs->trans("ClassifyShipped"); } - if ($permissiontocancel) { - $arrayofmassactions['cancelorders'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Cancel"); - } - if (isModEnabled('facture') && $user->hasRight("facture", "creer")) { - $arrayofmassactions['createbills'] = img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("CreateInvoiceForThisCustomer"); - } if ($permissiontoclose) { $arrayofmassactions['setbilled'] = img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("ClassifyBilled"); } + if ($permissiontocancel) { + $arrayofmassactions['cancelorders'] = img_picto('', 'close_title', 'class="pictofixedwidth"').$langs->trans("Cancel"); + } if ($permissiontodelete) { $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); } + if (isModEnabled('facture') && $user->hasRight("facture", "creer")) { + $arrayofmassactions['createbills'] = img_picto('', 'bill', 'class="pictofixedwidth"').$langs->trans("CreateInvoiceForThisCustomer"); + } + if ($permissiontosendbymail) { + $arrayofmassactions['presend'] = img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"); + } if (in_array($massaction, array('presend', 'predelete', 'createbills'))) { $arrayofmassactions = array(); } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index eadbe8efd05..a54a866ba6d 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -18,7 +18,7 @@ * Copyright (C) 2018-2022 Alexandre Spangaro * Copyright (C) 2018 Nicolas ZABOURI * Copyright (C) 2022 Sylvain Legrand - * Copyright (C) 2022 Gauthier VERDOL + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -2695,7 +2695,7 @@ class Facture extends CommonInvoice return -5; } - $sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time'; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'element_time'; $sql .= ' SET invoice_id = NULL, invoice_line_id = NULL'; $sql .= ' WHERE invoice_id = '.((int) $rowid); @@ -4230,19 +4230,6 @@ class Facture extends CommonInvoice $this->db->begin(); - // Free discount linked to invoice line - $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; - $sql .= ' SET fk_facture_line = NULL'; - $sql .= ' WHERE fk_facture_line = '.((int) $rowid); - - dol_syslog(get_class($this)."::deleteline", LOG_DEBUG); - $result = $this->db->query($sql); - if (!$result) { - $this->error = $this->db->error(); - $this->db->rollback(); - return -1; - } - // Memorize previous line for triggers $staticline = clone $line; $line->oldline = $staticline; @@ -6444,13 +6431,38 @@ class FactureLigne extends CommonInvoiceLine return -1; } - $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".((int) $this->rowid); + // Free discount linked to invoice line + $sql = 'UPDATE '.MAIN_DB_PREFIX.'societe_remise_except'; + $sql .= ' SET fk_facture_line = NULL'; + $sql .= ' WHERE fk_facture_line = '.((int) $this->id); + + dol_syslog(get_class($this)."::deleteline", LOG_DEBUG); + $result = $this->db->query($sql); + if (!$result) { + $this->error = $this->db->error(); + $this->errors[] = $this->error; + $this->db->rollback(); + return -1; + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time'; + $sql .= ' SET invoice_id = NULL, invoice_line_id = NULL'; + $sql .= ' WHERE invoice_line_id = '.((int) $this->id); + if (!$this->db->query($sql)) { + $this->error = $this->db->error()." sql=".$sql; + $this->errors[] = $this->error; + $this->db->rollback(); + return -1; + } + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".((int) $this->id); if ($this->db->query($sql)) { $this->db->commit(); return 1; } else { $this->error = $this->db->error()." sql=".$sql; + $this->errors[] = $this->error; $this->db->rollback(); return -1; } diff --git a/htdocs/compta/facture/invoicetemplate_list.php b/htdocs/compta/facture/invoicetemplate_list.php index a36edf5cd88..825de33bec6 100644 --- a/htdocs/compta/facture/invoicetemplate_list.php +++ b/htdocs/compta/facture/invoicetemplate_list.php @@ -1035,7 +1035,7 @@ while ($i < $imaxinloop) { // Status if (!empty($arrayfields['status']['checked'])) { print ''; - print $invoicerectmp->getLibStatut(3, 0); + print $invoicerectmp->getLibStatut(5, 0); print ''; if (!$i) { $totalarray['nbfield']++; diff --git a/htdocs/compta/resultat/clientfourn.php b/htdocs/compta/resultat/clientfourn.php index 6d4a04102f0..beda62520d9 100644 --- a/htdocs/compta/resultat/clientfourn.php +++ b/htdocs/compta/resultat/clientfourn.php @@ -70,36 +70,34 @@ if (!$sortorder) { } // Date range -$year = GETPOST('year', 'int'); +$year = GETPOST('year', 'int'); // this is used for navigation previous/next. It is the last year to show in filter if (empty($year)) { $year_current = dol_print_date(dol_now(), "%Y"); $month_current = dol_print_date(dol_now(), "%m"); - $year_start = $year_current; + $year_start = $year_current - ($nbofyear - 1); } else { $year_current = $year; $month_current = dol_print_date(dol_now(), "%m"); - $year_start = $year; + $year_start = $year - $nbofyear + (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); } $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); // We define date_start and date_end if (empty($date_start) || empty($date_end)) { // We define date_start and date_end - $q = GETPOST("q") ?GETPOST("q") : 0; + $q = GETPOST("q") ? GETPOST("q", 'int') : 0; if ($q == 0) { // We define date_start and date_end - $year_end = $year_start; - $month_start = GETPOST("month") ?GETPOST("month") : ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); + $year_end = $year_start + $nbofyear - (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); + $month_start = GETPOST("month") ? GETPOST("month", 'int') : getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1); if (!GETPOST('month')) { - if (!GETPOST("year") && $month_start > $month_current) { + if (!$year && $month_start > $month_current) { $year_start--; $year_end--; } $month_end = $month_start - 1; if ($month_end < 1) { $month_end = 12; - } else { - $year_end++; } } else { $month_end = $month_start; @@ -157,6 +155,7 @@ if (isModEnabled('accounting')) { } $hookmanager->initHooks(['customersupplierreportlist']); + /* * View */ @@ -174,13 +173,6 @@ $total_ttc = 0; // Affiche en-tete de rapport if ($modecompta == "CREANCES-DETTES") { $name = $langs->trans("ReportInOut").', '.$langs->trans("ByPredefinedAccountGroups"); - $calcmode = $langs->trans("CalcModeDebt"); - $calcmode .= '
('.$langs->trans("SeeReportInInputOutputMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - if (isModEnabled('accounting')) { - $calcmode .= '
('.$langs->trans("SeeReportInBookkeepingMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - } $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesResultDue"); @@ -196,13 +188,6 @@ if ($modecompta == "CREANCES-DETTES") { //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "RECETTES-DEPENSES") { $name = $langs->trans("ReportInOut").', '.$langs->trans("ByPredefinedAccountGroups"); - $calcmode = $langs->trans("CalcModeEngagement"); - $calcmode .= '
('.$langs->trans("SeeReportInDueDebtMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - if (isModEnabled('accounting')) { - $calcmode .= '
('.$langs->trans("SeeReportInBookkeepingMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - } $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesResultInOut"); @@ -210,14 +195,9 @@ if ($modecompta == "CREANCES-DETTES") { //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "BOOKKEEPING") { $name = $langs->trans("ReportInOut").', '.$langs->trans("ByPredefinedAccountGroups"); - $calcmode = $langs->trans("CalcModeBookkeeping"); - $calcmode .= '
('.$langs->trans("SeeReportInInputOutputMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - $calcmode .= '
('.$langs->trans("SeeReportInDueDebtMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); $arraylist = array('no'=>$langs->trans("CustomerCode"), 'yes'=>$langs->trans("AccountWithNonZeroValues"), 'all'=>$langs->trans("All")); - $period .= '     '.$langs->trans("DetailByAccount").' '.$form->selectarray('showaccountdetail', $arraylist, $showaccountdetail, 0); + $period .= '     '.$langs->trans("DetailBy").' '.$form->selectarray('showaccountdetail', $arraylist, $showaccountdetail, 0); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesResultBookkeepingPredefined"); $description .= ' ('.$langs->trans("SeePageForSetup", DOL_URL_ROOT.'/accountancy/admin/account.php?mainmenu=accountancy&leftmenu=accountancy_admin', $langs->transnoentitiesnoconv("Accountancy").' / '.$langs->transnoentitiesnoconv("Setup").' / '.$langs->transnoentitiesnoconv("Chartofaccounts")).')'; @@ -225,7 +205,23 @@ if ($modecompta == "CREANCES-DETTES") { //$exportlink=$langs->trans("NotYetAvailable"); } -$hselected = 'report'; +// Define $calcmode line +$calcmode = ''; +if (isModEnabled('accounting')) { + $calcmode .= ''; + $calcmode .= '
'; +} +$calcmode .= ''; +$calcmode .= '
'; + report_header($name, '', $period, $periodlink, $description, $builddate, $exportlink, array('modecompta'=>$modecompta, 'showaccountdetail'=>$showaccountdetail), $calcmode); diff --git a/htdocs/compta/resultat/index.php b/htdocs/compta/resultat/index.php index 73a4e7d902a..686f5ff42f7 100644 --- a/htdocs/compta/resultat/index.php +++ b/htdocs/compta/resultat/index.php @@ -36,17 +36,21 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; // Load translation files required by the page $langs->loadLangs(array('compta', 'bills', 'donation', 'salaries')); -$date_startmonth = GETPOST('date_startmonth', 'int'); $date_startday = GETPOST('date_startday', 'int'); +$date_startmonth = GETPOST('date_startmonth', 'int'); $date_startyear = GETPOST('date_startyear', 'int'); -$date_endmonth = GETPOST('date_endmonth', 'int'); $date_endday = GETPOST('date_endday', 'int'); +$date_endmonth = GETPOST('date_endmonth', 'int'); $date_endyear = GETPOST('date_endyear', 'int'); $nbofyear = 4; +// Change this to test different cases of setup +//$conf->global->SOCIETE_FISCAL_MONTH_START = 7; + + // Date range -$year = GETPOST('year', 'int'); +$year = GETPOST('year', 'int'); // this is used for navigation previous/next. It is the last year to show in filter if (empty($year)) { $year_current = dol_print_date(dol_now(), "%Y"); $month_current = dol_print_date(dol_now(), "%m"); @@ -54,28 +58,26 @@ if (empty($year)) { } else { $year_current = $year; $month_current = dol_print_date(dol_now(), "%m"); - $year_start = $year - ($nbofyear - 1); + $year_start = $year - $nbofyear + (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); } -$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); -$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); +$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear, 'tzserver'); +$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear, 'tzserver'); // We define date_start and date_end if (empty($date_start) || empty($date_end)) { // We define date_start and date_end $q = GETPOST("q") ? GETPOST("q", 'int') : 0; if ($q == 0) { // We define date_start and date_end - $year_end = $year_start + ($nbofyear - 1); - $month_start = GETPOST("month") ? GETPOST("month", 'int') : ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); + $year_end = $year_start + $nbofyear - (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); + $month_start = GETPOST("month") ? GETPOST("month", 'int') : getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1); if (!GETPOST('month')) { - if (!GETPOST("year") && $month_start > $month_current) { + if (!$year && $month_start > $month_current) { $year_start--; $year_end--; } $month_end = $month_start - 1; if ($month_end < 1) { $month_end = 12; - } else { - $year_end++; } } else { $month_end = $month_start; @@ -149,13 +151,6 @@ $decaiss_ttc = array(); // Affiche en-tete du rapport if ($modecompta == 'CREANCES-DETTES') { $name = $langs->trans("ReportInOut").', '.$langs->trans("ByYear"); - $calcmode = $langs->trans("CalcModeDebt"); - $calcmode .= '
('.$langs->trans("SeeReportInInputOutputMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - if (isModEnabled('accounting')) { - $calcmode .= '
('.$langs->trans("SeeReportInBookkeepingMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - } $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesAmountWithTaxExcluded"); @@ -172,13 +167,6 @@ if ($modecompta == 'CREANCES-DETTES') { //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "RECETTES-DEPENSES") { $name = $langs->trans("ReportInOut").', '.$langs->trans("ByYear"); - $calcmode = $langs->trans("CalcModeEngagement"); - $calcmode .= '
('.$langs->trans("SeeReportInDueDebtMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - if (isModEnabled('accounting')) { - $calcmode .= '
('.$langs->trans("SeeReportInBookkeepingMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - } $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesAmountWithTaxIncluded"); @@ -187,11 +175,6 @@ if ($modecompta == 'CREANCES-DETTES') { //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "BOOKKEEPING") { $name = $langs->trans("ReportInOut").', '.$langs->trans("ByYear"); - $calcmode = $langs->trans("CalcModeBookkeeping"); - $calcmode .= '
('.$langs->trans("SeeReportInInputOutputMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); - $calcmode .= '
('.$langs->trans("SeeReportInDueDebtMode", '{s1}', '{s2}').')'; - $calcmode = str_replace(array('{s1}', '{s2}'), array('', ''), $calcmode); $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesAmountOnInOutBookkeepingRecord"); @@ -200,9 +183,25 @@ if ($modecompta == 'CREANCES-DETTES') { //$exportlink=$langs->trans("NotYetAvailable"); } -$hselected = 'report'; +// Define $calcmode line +$calcmode = ''; +if (isModEnabled('accounting')) { + $calcmode .= ''; + $calcmode .= '
'; +} +$calcmode .= ''; +$calcmode .= '
'; -report_header($name, '', $period, $periodlink, $description, $builddate, $exportlink, array('modecompta'=>$modecompta), $calcmode); + +report_header($name, '', $period, $periodlink, $description, $builddate, $exportlink, array(), $calcmode); if (isModEnabled('accounting') && $modecompta != 'BOOKKEEPING') { print info_admin($langs->trans("WarningReportNotReliable"), 0, 0, 1); @@ -996,17 +995,18 @@ $reshook = $hookmanager->executeHooks('addReportInfo', $parameters, $object, $ac $totentrees = array(); $totsorties = array(); +$year_end_for_table = ($year_end - (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 1 : 0)); print '
'; print ''."\n"; print ''; -for ($annee = $year_start; $annee <= $year_end; $annee++) { +for ($annee = $year_start; $annee <= $year_end_for_table; $annee++) { print ''; @@ -1014,7 +1014,7 @@ for ($annee = $year_start; $annee <= $year_end; $annee++) { print ''; print ''; // Loop on each year to ouput -for ($annee = $year_start; $annee <= $year_end; $annee++) { +for ($annee = $year_start; $annee <= $year_end_for_table; $annee++) { print ''; print ""; - for ($annee = $year_start; $annee <= $year_end; $annee++) { + for ($annee = $year_start; $annee <= $year_end_for_table; $annee++) { $annee_decalage = $annee; if ($mois > 12) { $annee_decalage = $annee + 1; @@ -1100,7 +1100,7 @@ if ($modecompta == 'CREANCES-DETTES' || $modecompta == 'BOOKKEEPING') { print $langs->trans("TotalTTC"); } print ''; -for ($annee = $year_start; $annee <= $year_end; $annee++) { +for ($annee = $year_start; $annee <= $year_end_for_table; $annee++) { $nbcols += 2; print ''; print ''; @@ -1115,7 +1115,7 @@ print "\n"; // Balance print ''; -for ($annee = $year_start; $annee <= $year_end; $annee++) { +for ($annee = $year_start; $annee <= $year_end_for_table; $annee++) { print '"; } - // Valeur CA du mois + // Value turnover of month print '"; - // Pourcentage du mois + // Percentage of month if ($annee_decalage > $minyear && $case <= $casenow) { if (!empty($cum[$caseprev]) && !empty($cum[$case])) { $percent = (round(($cum[$case] - $cum[$caseprev]) / $cum[$caseprev], 4) * 100); @@ -439,7 +453,9 @@ for ($annee = $year_start; $annee <= $year_end; $annee++) { if ($modecompta == 'CREANCES-DETTES') { // Montant total HT if ($total_ht[$annee] || ($annee >= $minyear && $annee <= max($nowyear, $maxyear))) { - print '"; + print '"; } else { print ''; } @@ -456,20 +472,22 @@ for ($annee = $year_start; $annee <= $year_end; $annee++) { if ($annee > $minyear && $annee <= max($nowyear, $maxyear)) { if ($total[$annee - 1] && $total[$annee]) { $percent = (round(($total[$annee] - $total[$annee - 1]) / $total[$annee - 1], 4) * 100); - print ''; + print ''; } - if ($total[$annee - 1] && !$total[$annee]) { + if (!empty($total[$annee - 1]) && empty($total[$annee])) { print ''; } - if (!$total[$annee - 1] && $total[$annee]) { + if (empty($total[$annee - 1]) && !empty($total[$annee])) { print ''; } - if (!$total[$annee - 1] && !$total[$annee]) { + if (empty($total[$annee - 1]) && empty($total[$annee])) { print ''; } } else { print ''; if (!$i) { diff --git a/htdocs/core/ajax/fileupload.php b/htdocs/core/ajax/fileupload.php index 379a2e689a3..4e05c7d8cb6 100644 --- a/htdocs/core/ajax/fileupload.php +++ b/htdocs/core/ajax/fileupload.php @@ -19,6 +19,8 @@ /** * \file htdocs/core/ajax/fileupload.php * \brief File to return Ajax response on file upload + * + * Option MAIN_USE_JQUERY_FILEUPLOAD must be enabled to have this feature working. Use is NOT secured ! */ if (!defined('NOTOKENRENEWAL')) { diff --git a/htdocs/core/ajax/security.php b/htdocs/core/ajax/security.php index b01c952662e..2a836359e1c 100644 --- a/htdocs/core/ajax/security.php +++ b/htdocs/core/ajax/security.php @@ -36,7 +36,7 @@ if (!defined('NOREQUIREAJAX')) { if (!defined('NOREQUIRESOC')) { define('NOREQUIRESOC', '1'); } -// We need langs because the getRandomPassword may use user language to define some rules of pass generation +// We need langs because the getRandomPassword may use the user language to define some rules of pass generation /*if (!defined('NOREQUIRETRAN')) { define('NOREQUIRETRAN', '1'); }*/ diff --git a/htdocs/core/boxes/box_validated_projects.php b/htdocs/core/boxes/box_validated_projects.php index bab64d5a000..f071871d0d4 100644 --- a/htdocs/core/boxes/box_validated_projects.php +++ b/htdocs/core/boxes/box_validated_projects.php @@ -4,6 +4,7 @@ * Copyright (C) 2015 Frederic France * Copyright (C) 2016 Juan José Menent * Copyright (C) 2020 Pierre Ardoin + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -119,7 +120,7 @@ class box_validated_projects extends ModeleBoxes if ($projectsListId) { $sql .= ' AND p.rowid IN ('.$this->db->sanitize($projectsListId).')'; // Only projects that are allowed } - $sql .= " AND t.rowid NOT IN (SELECT fk_task FROM ".MAIN_DB_PREFIX."projet_task_time WHERE fk_user = ".((int) $user->id).")"; + $sql .= " AND t.rowid NOT IN (SELECT fk_element FROM ".MAIN_DB_PREFIX."element_time WHERE elementtype = 'task' AND fk_user = ".((int) $user->id).")"; $sql .= " GROUP BY p.rowid, p.ref, p.fk_soc, p.dateo"; $sql .= " ORDER BY p.dateo ASC"; diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 2635acd7951..04da241f16c 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -32,6 +32,7 @@ use OAuth\Common\Storage\DoliStorage; use OAuth\Common\Consumer\Credentials; + /** * Class to send emails (with attachments or not) * Usage: $mailfile = new CMailFile($subject,$sendto,$replyto,$message,$filepath,$mimetype,$filename,$cc,$ccc,$deliveryreceipt,$msgishtml,$errors_to,$css,$trackid,$moreinheader,$sendcontext,$replyto); @@ -171,6 +172,10 @@ class CMailFile { global $conf, $dolibarr_main_data_root, $user; + dol_syslog("CMailFile::CMailfile: charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, replyto=$replyto trackid=$trackid sendcontext=$sendcontext", LOG_DEBUG); + dol_syslog("CMailFile::CMailfile: subject=".$subject.", deliveryreceipt=".$deliveryreceipt.", msgishtml=".$msgishtml, LOG_DEBUG); + + // Clean values of $mimefilename_list if (is_array($mimefilename_list)) { foreach ($mimefilename_list as $key => $val) { @@ -214,9 +219,6 @@ class CMailFile // On defini alternative_boundary $this->alternative_boundary = 'mul_'.dol_hash(uniqid("dolibarr3"), 3); // Force md5 hash (does not contains special chars) - dol_syslog("CMailFile::CMailfile: sendmode=".$this->sendmode." charset=".$conf->file->character_set_client." from=$from, to=$to, addr_cc=$addr_cc, addr_bcc=$addr_bcc, errors_to=$errors_to, replyto=$replyto trackid=$trackid sendcontext=$sendcontext upload_dir_tmp=$upload_dir_tmp", LOG_DEBUG); - dol_syslog("CMailFile::CMailfile: subject=".$subject.", deliveryreceipt=".$deliveryreceipt.", msgishtml=".$msgishtml, LOG_DEBUG); - if (empty($subject)) { dol_syslog("CMailFile::CMailfile: Try to send an email with empty subject"); $this->error = 'ErrorSubjectIsRequired'; @@ -367,6 +369,8 @@ class CMailFile } } + dol_syslog("CMailFile::CMailfile: sendmode=".$this->sendmode." addr_bcc=$addr_bcc, replyto=$replyto", LOG_DEBUG); + // We set all data according to choosed sending method. // We also set a value for ->msgid if ($this->sendmode == 'mail') { diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e3c3dff2b7c..cb5ddfcd395 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -14,7 +14,7 @@ * Copyright (C) 2017 Rui Strecht * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2018 Josep Lluís Amador - * Copyright (C) 2021 Gauthier VERDOL + * Copyright (C) 2023 Gauthier VERDOL * Copyright (C) 2021 Grégory Blémand * Copyright (C) 2023 Lenin Rivas * @@ -2089,10 +2089,6 @@ abstract class CommonObject $id_field = 'rowid'; } - $error = 0; - - $this->db->begin(); - // Special case if ($table == 'product' && $field == 'note_private') { $field = 'note'; @@ -2101,6 +2097,32 @@ abstract class CommonObject $fk_user_field = 'fk_user_mod'; } + if ($trigkey) { + $oldvalue = null; + + $sql = "SELECT " . $field; + $sql .= " FROM " . MAIN_DB_PREFIX . $table; + $sql .= " WHERE " . $id_field . " = " . ((int) $id); + + $resql = $this->db->query($sql); + if ($resql) { + if ($obj = $this->db->fetch_object($resql)) { + if ($format == 'date') { + $oldvalue = $this->db->jdate($obj->$field); + } else { + $oldvalue = $obj->$field; + } + } + } else { + $this->error = $this->db->lasterror(); + return -1; + } + } + + $error = 0; + + $this->db->begin(); + $sql = "UPDATE ".$this->db->prefix().$table." SET "; if ($format == 'text') { @@ -2133,6 +2155,11 @@ abstract class CommonObject } else { $result = $this->fetchCommon($id); } + $this->oldcopy = clone $this; + if (property_exists($this->oldcopy, $field)) { + $this->oldcopy->$field = $oldvalue; + } + if ($result >= 0) { $result = $this->call_trigger($trigkey, (!empty($fuser) && is_object($fuser)) ? $fuser : $user); // This may set this->errors } @@ -4637,6 +4664,9 @@ abstract class CommonObject if (!empty($element['parent']) && !empty($element['parentkey'])) { $sql.= " AND c.".$element['parentkey']." = p.rowid"; } + if (!empty($element['parent']) && !empty($element['parenttypefield']) && !empty($element['parenttypevalue'])) { + $sql.= " AND c.".$element['parenttypefield']." = '".$this->db->escape($element['parenttypevalue'])."'"; + } if (!empty($entity)) { if (!empty($element['parent']) && !empty($element['parentkey'])) { $sql.= " AND p.entity = ".((int) $entity); @@ -6154,13 +6184,15 @@ abstract class CommonObject // If field is a computed field, value must become result of compute (regardless of whether a row exists // in the element's extrafields table) - foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) { - if (!empty($extrafields->attributes[$this->table_element]) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) { - //var_dump($conf->disable_compute); - if (empty($conf->disable_compute)) { - global $objectoffield; // We set a global variable to $objectoffield so - $objectoffield = $this; // we can use it inside computed formula - $this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, ''); + if (is_array($extrafields->attributes[$this->table_element]['label'])) { + foreach ($extrafields->attributes[$this->table_element]['label'] as $key => $val) { + if (!empty($extrafields->attributes[$this->table_element]) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) { + //var_dump($conf->disable_compute); + if (empty($conf->disable_compute)) { + global $objectoffield; // We set a global variable to $objectoffield so + $objectoffield = $this; // we can use it inside computed formula + $this->array_options['options_' . $key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, ''); + } } } } diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 7c76dc9b36b..38bfbd840d8 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -1144,7 +1144,7 @@ class DolGraph if (isset($this->type[$firstlot])) { $cssfordiv .= ' dolgraphchar' . $this->type[$firstlot]; } - $this->stringtoshow .= '
' . "\n"; + $this->stringtoshow .= '
' . "\n"; $this->stringtoshow .= '\n"; + + $msg .= ajax_event($htmlname, $events); + + return $msg; +} + + +/** + * Add event management script. + * + * @param string $htmlname Name of html select field ('myid' or '.myclass') + * @param array $events Add some Ajax events option on change of $htmlname component to call ajax to autofill a HTML element (select#htmlname and #inputautocompletehtmlname) + * Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @return string Return JS string to manage event + */ +function ajax_event($htmlname, $events) +{ + $out = ''; + + if (is_array($events) && count($events)) { // If an array of js events to do were provided. + $out = ' + '; } - $msg .= '});'."\n"; - $msg .= "\n"; - - return $msg; + return $out; } + /** * On/off button for constant * diff --git a/htdocs/core/lib/fichinter.lib.php b/htdocs/core/lib/fichinter.lib.php index 87c9ce4a3fc..0384704a7f2 100644 --- a/htdocs/core/lib/fichinter.lib.php +++ b/htdocs/core/lib/fichinter.lib.php @@ -120,9 +120,38 @@ function fichinter_prepare_head($object) $head[$h][2] = 'documents'; $h++; - $head[$h][0] = DOL_URL_ROOT.'/fichinter/info.php?id='.$object->id; - $head[$h][1] = $langs->trans('Info'); - $head[$h][2] = 'info'; + $head[$h][0] = DOL_URL_ROOT.'/fichinter/agenda.php?id='.$object->id; + $head[$h][1] = $langs->trans('Events'); + if (isModEnabled('agenda')&& (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { + $nbEvent = 0; + // Enable caching of thirdparty count actioncomm + require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php'; + $cachekey = 'count_events_fichinter_'.$object->id; + $dataretrieved = dol_getcache($cachekey); + if (!is_null($dataretrieved)) { + $nbEvent = $dataretrieved; + } else { + $sql = "SELECT COUNT(id) as nb"; + $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm"; + $sql .= " WHERE fk_element = ".((int) $object->id); + $sql .= " AND elementtype = 'fichinter'"; + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + $nbEvent = $obj->nb; + } else { + dol_syslog('Failed to count actioncomm '.$db->lasterror(), LOG_ERR); + } + dol_setcache($cachekey, $nbEvent, 120); // If setting cache fails, this is not a problem, so we do not test result. + } + + $head[$h][1] .= '/'; + $head[$h][1] .= $langs->trans("Agenda"); + if ($nbEvent > 0) { + $head[$h][1] .= ''.$nbEvent.''; + } + } + $head[$h][2] = 'agenda'; $h++; complete_head_from_modules($conf, $langs, $object, $head, $h, 'intervention', 'add', 'external'); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index e0f3fb0a4bb..a3a6b1079ed 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5435,6 +5435,7 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', if ($limit < 0) { $limit = $conf->liste_limit; } + if ($savlimit != 0 && (($num > $limit) || ($num == -1) || ($limit == 0))) { $nextpage = 1; } else { @@ -5475,7 +5476,7 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', } // Show navigation bar $pagelist = ''; - if ($savlimit != 0 && ($page > 0 || $num > $limit)) { + if ($savlimit != 0 && ((int) $page > 0 || $num > $limit)) { if ($totalnboflines) { // If we know total nb of lines // Define nb of extra page links before and after selected page + ... + first or last $maxnbofpage = (empty($conf->dol_optimize_smallscreen) ? 4 : 0); @@ -5535,8 +5536,8 @@ function print_barre_liste($titre, $page, $file, $options = '', $sortfield = '', } } - if ($savlimit || $morehtmlright || $morehtmlrightbeforearrow) { - print_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtmlright, $savlimit, $totalnboflines, $hideselectlimit, $morehtmlrightbeforearrow); // output the div and ul for previous/last completed with page numbers into $pagelist + if (($savlimit || $morehtmlright || $morehtmlrightbeforearrow) && empty($hidenavigation)) { + print_fleche_navigation((int) $page, $file, $options, $nextpage, $pagelist, $morehtmlright, $savlimit, $totalnboflines, $hideselectlimit, $morehtmlrightbeforearrow); // output the div and ul for previous/last completed with page numbers into $pagelist } // js to autoselect page field on focus @@ -11587,7 +11588,7 @@ function jsonOrUnserialize($stringtodecode) /** * forgeSQLFromUniversalSearchCriteria * - * @param string $filter String with universal search string + * @param string $filter String with universal search string. Must be (aaa:bbb:...) with aaa is a field name (with alias or not) and bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'. * @param string $error Error message * @return string Return forged SQL string */ @@ -11605,7 +11606,7 @@ function forgeSQLFromUniversalSearchCriteria($filter, &$error = '') // If the string result contains something else than '()', the syntax was wrong if (preg_match('/[^\(\)]/', $t)) { $error = 'Bad syntax of the search string, filter criteria is inhalited'; - return '1 = 3'; // Bad syntax of the search string, we force a SQL not found + return 'Filter syntax error'; // Bad syntax of the search string, we force a SQL not found } return " AND (".preg_replace_callback('/'.$regexstring.'/i', 'dolForgeCriteriaCallback', $filter).")"; @@ -11684,7 +11685,10 @@ function dolForgeCriteriaCallback($matches) return ''; } - $operator = strtoupper(preg_replace('/[^a-z<>=]/i', '', trim($tmp[1]))); + $operand = preg_replace('/[^a-z0-9\._]/i', '', trim($tmp[0])); + + $operator = strtoupper(preg_replace('/[^a-z<>!=]/i', '', trim($tmp[1]))); + if ($operator == 'NOTLIKE') { $operator = 'NOT LIKE'; } @@ -11722,7 +11726,7 @@ function dolForgeCriteriaCallback($matches) } } - return $db->escape($tmp[0]).' '.strtoupper($operator).' '.$tmpescaped; + return $db->escape($operand).' '.strtoupper($operator).' '.$tmpescaped; } diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php index 3dfccc88ea5..93c7a17de2f 100644 --- a/htdocs/core/lib/payments.lib.php +++ b/htdocs/core/lib/payments.lib.php @@ -146,7 +146,7 @@ function payment_supplier_prepare_head(Paiement $object) */ function getValidOnlinePaymentMethods($paymentmethod = '') { - global $conf, $langs, $hookmanager, $action; + global $langs, $hookmanager, $action; $validpaymentmethod = array(); @@ -434,6 +434,8 @@ function htmlPrintOnlinePaymentFooter($fromcompany, $langs, $addformmessage = 0, { global $conf; + $reg = array(); + // Juridical status $line1 = ""; if ($fromcompany->forme_juridique_code) { @@ -485,9 +487,8 @@ function htmlPrintOnlinePaymentFooter($fromcompany, $langs, $addformmessage = 0, print ''."\n"; + print '
'."\n"; print '
'; - - print '
'."\n"; if ($addformmessage) { print ''; print '
'; @@ -519,5 +520,6 @@ function htmlPrintOnlinePaymentFooter($fromcompany, $langs, $addformmessage = 0, print ' - '; } print $line2; - print '
'."\n"; + print ''; + print '
'."\n"; } diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 7a5848adaf3..468c4d82a9b 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -725,11 +725,16 @@ function pdf_pagehead(&$pdf, $outputlangs, $page_height) $filepath = $conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_USE_BACKGROUND_ON_PDF; if (file_exists($filepath)) { $pdf->SetAutoPageBreak(0, 0); // Disable auto pagebreak before adding image + if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) { $pdf->SetAlpha($conf->global->MAIN_USE_BACKGROUND_ON_PDF_ALPHA); } // Option for change opacity of background $pdf->Image($filepath, (isset($conf->global->MAIN_USE_BACKGROUND_ON_PDF_X) ? $conf->global->MAIN_USE_BACKGROUND_ON_PDF_X : 0), (isset($conf->global->MAIN_USE_BACKGROUND_ON_PDF_Y) ? $conf->global->MAIN_USE_BACKGROUND_ON_PDF_Y : 0), 0, $page_height); + if (getDolGlobalString('MAIN_USE_BACKGROUND_ON_PDF_ALPHA')) { $pdf->SetAlpha(1); } $pdf->SetPageMark(); // This option avoid to have the images missing on some pages $pdf->SetAutoPageBreak(1, 0); // Restore pagebreak } } + if (getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') && getDolGlobalString('MAIN_ADD_PDF_BACKGROUND') != '-1') { + $pdf->SetPageMark(); // This option avoid to have the images missing on some pages + } } @@ -1247,49 +1252,52 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $pdf->SetY(-$posy); - // Hide footer line if footer background color is set - if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) { - $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); - } + // Option for hide all footer (page number will no hidden) + if (!getDolGlobalInt('PDF_FOOTER_HIDDEN')) { + // Hide footer line if footer background color is set + if (!getDolGlobalString('PDF_FOOTER_BACKGROUND_COLOR')) { + $pdf->line($dims['lm'], $dims['hk'] - $posy, $dims['wk'] - $dims['rm'], $dims['hk'] - $posy); + } - // Option for set top margin height of footer after freetext - if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) { - $posy -= floatval(getDolGlobalString('PDF_FOOTER_TOP_MARGIN')); - } else { - $posy--; - } + // Option for set top margin height of footer after freetext + if (getDolGlobalString('PDF_FOOTER_TOP_MARGIN') || getDolGlobalInt('PDF_FOOTER_TOP_MARGIN') === 0) { + $posy -= floatval(getDolGlobalString('PDF_FOOTER_TOP_MARGIN')); + } else { + $posy--; + } - if (!empty($line1)) { - $pdf->SetFont('', 'B', 7); - $pdf->SetXY($dims['lm'], -$posy); - $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', 0); - $posy -= 3; - $pdf->SetFont('', '', 7); - } + if (!empty($line1)) { + $pdf->SetFont('', 'B', 7); + $pdf->SetXY($dims['lm'], -$posy); + $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line1, 0, 'C', 0); + $posy -= 3; + $pdf->SetFont('', '', 7); + } - if (!empty($line2)) { - $pdf->SetFont('', 'B', 7); - $pdf->SetXY($dims['lm'], -$posy); - $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', 0); - $posy -= 3; - $pdf->SetFont('', '', 7); - } + if (!empty($line2)) { + $pdf->SetFont('', 'B', 7); + $pdf->SetXY($dims['lm'], -$posy); + $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line2, 0, 'C', 0); + $posy -= 3; + $pdf->SetFont('', '', 7); + } - if (!empty($line3)) { - $pdf->SetXY($dims['lm'], -$posy); - $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', 0); - } + if (!empty($line3)) { + $pdf->SetXY($dims['lm'], -$posy); + $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line3, 0, 'C', 0); + } - if (!empty($line4)) { - $posy -= 3; - $pdf->SetXY($dims['lm'], -$posy); - $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', 0); + if (!empty($line4)) { + $posy -= 3; + $pdf->SetXY($dims['lm'], -$posy); + $pdf->MultiCell($dims['wk'] - $dims['rm'] - $dims['lm'], 2, $line4, 0, 'C', 0); + } } } } // Show page nb only on iso languages (so default Helvetica font) // if (strtolower(pdf_getPDFFont($outputlangs)) == 'helvetica') { - $pdf->SetXY($dims['wk'] - $dims['rm'] - 18, -$posy); + $pdf->SetXY($dims['wk'] - $dims['rm'] - 18 - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_X', 0), -$posy - getDolGlobalInt('PDF_FOOTER_PAGE_NUMBER_Y', 0)); // $pdf->MultiCell(18, 2, $pdf->getPageNumGroupAlias().' / '.$pdf->getPageGroupAlias(), 0, 'R', 0); // $pdf->MultiCell(18, 2, $pdf->PageNo().' / '.$pdf->getAliasNbPages(), 0, 'R', 0); // doesn't works with all fonts // $pagination = $pdf->getAliasNumPage().' / '.$pdf->getAliasNbPages(); // works with $pdf->Cell diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 8aa8b6d93b7..71c0cd7c0c6 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -4,6 +4,7 @@ * Copyright (C) 2011 Juanjo Menent * Copyright (C) 2018-2021 Frédéric France * Copyright (C) 2022 Charlene Benke + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -100,8 +101,9 @@ function project_prepare_head(Project $project, $moreparam = '') $sql = "SELECT t.rowid"; //$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u"; //$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt"; - $sql .= " WHERE t.fk_task = pt.rowid"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t, ".MAIN_DB_PREFIX."projet_task as pt"; + $sql .= " WHERE t.fk_element = pt.rowid"; + $sql .= " AND t.elementtype = 'task'"; $sql .= " AND pt.fk_projet =".((int) $project->id); $resql = $db->query($sql); if ($resql) { @@ -372,8 +374,8 @@ function task_prepare_head($object) $sql = "SELECT t.rowid"; //$sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."user as u"; //$sql .= " WHERE t.fk_user = u.rowid AND t.fk_task = pt.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; - $sql .= " WHERE t.fk_task = ".((int) $object->id); + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t"; + $sql .= " WHERE t.elementtype='task' AND t.fk_element = ".((int) $object->id); $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); diff --git a/htdocs/core/lib/report.lib.php b/htdocs/core/lib/report.lib.php index c9f44fb4e08..badeb47d6f4 100644 --- a/htdocs/core/lib/report.lib.php +++ b/htdocs/core/lib/report.lib.php @@ -50,7 +50,8 @@ function report_header($reportname, $notused, $period, $periodlink, $description $title = $langs->trans("Report"); - print_barre_liste($title, '', ''); + print_barre_liste($title, 0, '', '', '', '', '', -1, '', 'generic', 0, '', '', -1, 1, 1); + print '
'."\n"; print ''."\n"; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 66de4ca6017..1f7b9404a7c 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -113,10 +113,11 @@ function dolGetRandomBytes($length) * @param string $chain string to encode * @param string $key If '', we use $dolibarr_main_instance_unique_id * @param string $ciphering Default ciphering algorithm + * @param string $forceseed To force the seed * @return string encoded string * @see dolDecrypt(), dol_hash() */ -function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR") +function dolEncrypt($chain, $key = '', $ciphering = 'AES-256-CTR', $forceseed = '') { global $dolibarr_main_instance_unique_id; global $dolibarr_disable_dolcrypt_for_debug; @@ -134,6 +135,9 @@ function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR") if (empty($key)) { $key = $dolibarr_main_instance_unique_id; } + if (empty($ciphering)) { + $ciphering = 'AES-256-CTR'; + } $newchain = $chain; @@ -145,7 +149,11 @@ function dolEncrypt($chain, $key = '', $ciphering = "AES-256-CTR") if ($ivlen === false || $ivlen < 1 || $ivlen > 32) { $ivlen = 16; } - $ivseed = dolGetRandomBytes($ivlen); + if (empty($forceseed)) { + $ivseed = dolGetRandomBytes($ivlen); + } else { + $ivseed = dol_trunc(md5($forceseed), $ivlen, 'right', 'UTF-8', 1); + } $newchain = openssl_encrypt($chain, $ciphering, $key, 0, $ivseed); return 'dolcrypt:'.$ciphering.':'.$ivseed.':'.$newchain; @@ -260,7 +268,7 @@ function dol_verifyHash($chain, $hash, $type = '0') global $conf; if ($type == '0' && !empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'password_hash' && function_exists('password_verify')) { - if ($hash[0] == '$') { + if (! empty($hash[0]) && $hash[0] == '$') { return password_verify($chain, $hash); } elseif (strlen($hash) == 32) { return dol_verifyHash($chain, $hash, '3'); // md5 diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index c68bb49d93b..b60054b9701 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -581,6 +581,9 @@ function dolJSToSetRandomPassword($htmlname, $htmlnameofbutton = 'generate_token token: \''.dol_escape_js(newToken()).'\' }, function(result) { + if ($("input#'.dol_escape_js($htmlname).'").attr("type") == "password") { + $("input#'.dol_escape_js($htmlname).'").attr("type", "text"); + } $("#'.dol_escape_js($htmlname).'").val(result); }); }); diff --git a/htdocs/core/lib/ticket.lib.php b/htdocs/core/lib/ticket.lib.php index 2c218421543..d31da45f968 100644 --- a/htdocs/core/lib/ticket.lib.php +++ b/htdocs/core/lib/ticket.lib.php @@ -203,7 +203,7 @@ function generate_random_id($car = 16) } /** - * Show header for public pages + * Show http header, open body tag and show HTML header banner for public pages for tickets * * @param string $title Title * @param string $head Head array @@ -216,11 +216,14 @@ function generate_random_id($car = 16) function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $arrayofjs = '', $arrayofcss = '') { global $user, $conf, $langs, $mysoc; + $urllogo = ""; top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss, 0, 1); // Show html headers print ''; - print '
'; + print '
'; + + print '
'; // Define urllogo if (getDolGlobalInt('TICKET_SHOW_COMPANY_LOGO') || getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC')) { @@ -239,21 +242,21 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $ } // Output html code for logo - if ($urllogo || getDolGlobalInt('TICKET_PUBLIC_INTERFACE_TOPIC')) { + if ($urllogo || getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC')) { print '
'; print '
'; if ($urllogo) { - print ''; + print ''; print ''; print ''; } - if (getDolGlobalInt('TICKET_PUBLIC_INTERFACE_TOPIC')) { + if (getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC')) { print '
'.(getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC') ? getDolGlobalString('TICKET_PUBLIC_INTERFACE_TOPIC') : $langs->trans("TicketSystem")).''; } print '
'; if (!getDolGlobalInt('MAIN_HIDE_POWERED_BY')) { - print ''; + print ''; } print '
'; } @@ -264,7 +267,7 @@ function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $ print '
'; } - print '
'; + print ''; - print '
'; + //print '
'; } diff --git a/htdocs/core/modules/member/mod_member_advanced.php b/htdocs/core/modules/member/mod_member_advanced.php index 3edb86030e8..d33b3d405e3 100644 --- a/htdocs/core/modules/member/mod_member_advanced.php +++ b/htdocs/core/modules/member/mod_member_advanced.php @@ -122,7 +122,7 @@ class mod_member_advanced extends ModeleNumRefMembers * Return next value * * @param Societe $objsoc Object third party - * @param Member $object Object we need next value for + * @param Adherent $object Object we need next value for * @return string Value if OK, 0 if KO */ public function getNextValue($objsoc, $object) diff --git a/htdocs/core/modules/member/mod_member_simple.php b/htdocs/core/modules/member/mod_member_simple.php index c45738c85cb..92f374cd01d 100644 --- a/htdocs/core/modules/member/mod_member_simple.php +++ b/htdocs/core/modules/member/mod_member_simple.php @@ -120,7 +120,7 @@ class mod_member_simple extends ModeleNumRefMembers * Return next value * * @param Societe $objsoc Object third party - * @param Member $object Object we need next value for + * @param Adherent $object Object we need next value for * @return string Value if OK, 0 if KO */ public function getNextValue($objsoc, $object) diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index a7089037abe..e3d39ea5848 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -239,7 +239,7 @@ class modFacture extends DolibarrModules $this->import_fields_array[$r] = array( 'f.ref' => 'InvoiceRef*', 'f.ref_ext' => 'ExternalRef', - 'f.ref_client' => 'CustomerRef', + 'f.ref_client' => 'RefCustomer', 'f.type' => 'Type*', 'f.fk_soc' => 'Customer*', 'f.datec' => 'InvoiceDateCreation', diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index 8bc8e03adb2..be6c641f852 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -5,7 +5,8 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2013 Florian Henry - * Copyright (C) 2014 Charles-Fr BENKE + * Copyright (C) 2014 Charles-Fr BENKE + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -230,7 +231,7 @@ class modProjet extends DolibarrModules 'p.usage_opportunity'=>'Boolean', 'p.usage_task'=>'Boolean', 'p.usage_bill_time'=>'Boolean', 'p.datec'=>"Date", 'p.dateo'=>"Date", 'p.datee'=>"Date", 'p.fk_statut'=>'Status', 'cls.code'=>"Text", 'p.opp_percent'=>'Numeric', 'p.opp_amount'=>'Numeric', 'p.description'=>"Text", 'p.entity'=>'Numeric', 'p.budget_amount'=>'Numeric', 'pt.rowid'=>'Numeric', 'pt.ref'=>'Text', 'pt.label'=>'Text', 'pt.dateo'=>"Date", 'pt.datee'=>"Date", 'pt.duration_effective'=>"Duree", 'pt.planned_workload'=>"Numeric", 'pt.progress'=>"Numeric", 'pt.description'=>"Text", - 'ptt.rowid'=>'Numeric', 'ptt.task_date'=>'Date', 'ptt.task_duration'=>"Duree", 'ptt.fk_user'=>"FormSelect:select_dolusers", 'ptt.note'=>"Text" + 'ptt.rowid'=>'Numeric', 'ptt.element_date'=>'Date', 'ptt.element_duration'=>"Duree", 'ptt.fk_user'=>"FormSelect:select_dolusers", 'ptt.note'=>"Text" ); $this->export_entities_array[$r] = array( 's.rowid'=>"company", 's.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 's.fk_pays'=>'company', @@ -272,8 +273,8 @@ class modProjet extends DolibarrModules $keyforaliasextra = 'extra2'; include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; // End add extra fields - $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('ptt.rowid'=>'IdTaskTime', 'ptt.task_date'=>'TaskTimeDate', 'ptt.task_duration'=>"TimesSpent", 'ptt.fk_user'=>"TaskTimeUser", 'ptt.note'=>"TaskTimeNote")); - $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('ptt.rowid'=>'task_time', 'ptt.task_date'=>'task_time', 'ptt.task_duration'=>"task_time", 'ptt.fk_user'=>"task_time", 'ptt.note'=>"task_time")); + $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('ptt.rowid'=>'IdTaskTime', 'ptt.element_date'=>'TaskTimeDate', 'ptt.element_duration'=>"TimesSpent", 'ptt.fk_user'=>"TaskTimeUser", 'ptt.note'=>"TaskTimeNote")); + $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('ptt.rowid'=>'task_time', 'ptt.element_date'=>'task_time', 'ptt.element_duration'=>"task_time", 'ptt.fk_user'=>"task_time", 'ptt.note'=>"task_time")); if (empty($conf->global->PROJECT_HIDE_TASKS)) { $this->export_fields_array[$r] = array_merge($this->export_fields_array[$r], array('f.ref'=>"Billed")); $this->export_entities_array[$r] = array_merge($this->export_entities_array[$r], array('f.ref'=>"task_time")); @@ -284,7 +285,7 @@ class modProjet extends DolibarrModules $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_lead_status as cls ON p.fk_opp_status = cls.rowid'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX."projet_task as pt ON p.rowid = pt.fk_projet"; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'projet_task_extrafields as extra2 ON pt.rowid = extra2.fk_object'; - $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX."projet_task_time as ptt ON pt.rowid = ptt.fk_task"; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX."element_time as ptt ON (pt.rowid = ptt.fk_element AND ptt.elementtype = 'task')"; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe as s ON p.fk_soc = s.rowid'; if (empty($conf->global->PROJECT_HIDE_TASKS)) { $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture as f ON ptt.invoice_id = f.rowid'; diff --git a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php index 635a627d0a1..16a197f42b9 100644 --- a/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/doc/doc_generic_project_odt.modules.php @@ -3,7 +3,8 @@ * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2013 Florian Henry * Copyright (C) 2016 Charlie Benke - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018 Frédéric France + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -749,13 +750,14 @@ class doc_generic_project_odt extends ModelePDFProjects } //Time ressources - $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note"; + $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note"; $sql .= ", u.lastname, u.firstname, t.thm"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t"; $sql .= " , ".MAIN_DB_PREFIX."user as u"; - $sql .= " WHERE t.fk_task =".((int) $task->id); + $sql .= " WHERE t.fk_element =".((int) $task->id); + $sql .= " AND t.elementtype = 'task'"; $sql .= " AND t.fk_user = u.rowid"; - $sql .= " ORDER BY t.task_date DESC"; + $sql .= " ORDER BY t.element_date DESC"; $resql = $this->db->query($sql); if ($resql) { diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index 49522a01d33..983d6f9b97a 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -3,7 +3,8 @@ * Copyright (C) 2012 Juanjo Menent * Copyright (C) 2013 Florian Henry * Copyright (C) 2016 Charlie Benke - * Copyright (C) 2018 Frédéric France + * Copyright (C) 2018 Frédéric France + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -662,13 +663,14 @@ class doc_generic_task_odt extends ModelePDFTask } // Time ressources - $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note"; + $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note"; $sql .= ", u.lastname, u.firstname"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t"; $sql .= " , ".MAIN_DB_PREFIX."user as u"; - $sql .= " WHERE t.fk_task =".((int) $object->id); + $sql .= " WHERE t.fk_element =".((int) $object->id); + $sql .= " AND t.elementtype = 'task'"; $sql .= " AND t.fk_user = u.rowid"; - $sql .= " ORDER BY t.task_date DESC"; + $sql .= " ORDER BY t.element_date DESC"; $resql = $this->db->query($sql); if ($resql) { diff --git a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php index 162575f8850..0fec1c99997 100644 --- a/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php +++ b/htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php @@ -386,6 +386,13 @@ class pdf_aurore extends ModelePDFSupplierProposal } } } + + // Extrafields in note + $extranote = $this->getExtrafieldsInHtml($object, $outputlangs); + if (!empty($extranote)) { + $notetoshow = dol_concatdesc($notetoshow, $extranote); + } + if ($notetoshow) { $tab_top -= 2; diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 52761509890..36b9cf6d9f2 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -412,7 +412,7 @@ if ($nolinesbefore) {
'; } - if ($inputalsopricewithtax) { + if (!empty($inputalsopricewithtax) && !getDolGlobalInt('MAIN_NO_INPUT_PRICE_WITH_TAX')) { $coldisplay++; - print ''; } -if ($inputalsopricewithtax) { +if (!empty($inputalsopricewithtax) && !getDolGlobalInt('MAIN_NO_INPUT_PRICE_WITH_TAX')) { print ''; } diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 0f7dc25152b..153773a6519 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -325,8 +325,14 @@ print $tooltiponpriceend; - +if (!empty($inputalsopricewithtax) && !getDolGlobalInt('MAIN_NO_INPUT_PRICE_WITH_TAX')) { ?> + '; +} + +$db->free($resql); + +$parameters = array('arrayfields'=>$arrayfields, 'sql'=>$sql); +$reshook = $hookmanager->executeHooks('printFieldListFooter', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; + +print '
 '; - print ''; + print ''; print $annee; - if ($conf->global->SOCIETE_FISCAL_MONTH_START > 1) { + if (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1) { print '-'.($annee + 1); } print '
'.$langs->trans("Month").''; $htmlhelp = ''; // if ($modecompta == 'RECETTES-DEPENSES') $htmlhelp=$langs->trans("PurchasesPlusVATEarnedAndDue"); @@ -1039,7 +1039,7 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++) { print '
".dol_print_date(dol_mktime(12, 0, 0, $mois_modulo, 1, $annee), "%B")."'.(isset($totsorties[$annee]) ?price(price2num($totsorties[$annee], 'MT')) : ' ').''.(isset($totentrees[$annee]) ?price(price2num($totentrees[$annee], 'MT')) : ' ').'
'.$langs->trans("AccountingResult").' '; if (isset($totentrees[$annee]) || isset($totsorties[$annee])) { $in = (isset($totentrees[$annee]) ?price2num($totentrees[$annee], 'MT') : 0); diff --git a/htdocs/compta/resultat/result.php b/htdocs/compta/resultat/result.php index a44772107aa..8fb4310692e 100644 --- a/htdocs/compta/resultat/result.php +++ b/htdocs/compta/resultat/result.php @@ -56,15 +56,18 @@ $date_endyear = GETPOST('date_endyear', 'int'); $nbofyear = 1; +// Change this to test different cases of setup +//$conf->global->SOCIETE_FISCAL_MONTH_START = 7; + // Date range -$year = GETPOST('year', 'int'); +$year = GETPOST('year', 'int'); // year with current month, is the month of the period we must show if (empty($year)) { $year_current = dol_print_date(dol_now('gmt'), "%Y", 'gmt'); - $month_current = strftime("%m", dol_now()); + $month_current = dol_print_date(dol_now(), "%m"); $year_start = $year_current - ($nbofyear - 1); } else { $year_current = $year; - $month_current = strftime("%m", dol_now()); + $month_current = dol_print_date(dol_now(), "%m"); $year_start = $year - ($nbofyear - 1); } $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear); @@ -72,14 +75,14 @@ $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear); // We define date_start and date_end if (empty($date_start) || empty($date_end)) { // We define date_start and date_end - $q = GETPOST("q") ?GETPOST("q") : 0; + $q = GETPOST("q") ?GETPOST("q", 'int') : 0; if ($q == 0) { // We define date_start and date_end $year_end = $year_start + ($nbofyear - 1); $month_start = GETPOST("month", 'int') ?GETPOST("month", 'int') : ($conf->global->SOCIETE_FISCAL_MONTH_START ? ($conf->global->SOCIETE_FISCAL_MONTH_START) : 1); $date_startmonth = $month_start; if (!GETPOST('month')) { - if (!GETPOST("year") && $month_start > $month_current) { + if (!$year && $month_start > $month_current) { $year_start--; $year_end--; } @@ -141,7 +144,7 @@ $modecompta = $conf->global->ACCOUNTING_MODE; if (isModEnabled('accounting')) { $modecompta = 'BOOKKEEPING'; } -if (GETPOST("modecompta")) { +if (GETPOST("modecompta", 'alpha')) { $modecompta = GETPOST("modecompta", 'alpha'); } @@ -228,8 +231,8 @@ if ($modecompta == "CREANCES-DETTES") { //$calcmode.='
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; //$calcmode.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0); - $arraylist = array('no'=>$langs->trans("No"), 'yes'=>$langs->trans("AccountWithNonZeroValues"), 'all'=>$langs->trans("All")); - $period .= '     '.$langs->trans("DetailByAccount").' '.$form->selectarray('showaccountdetail', $arraylist, $showaccountdetail, 0); + $arraylist = array('no'=>$langs->trans("None"), 'yes'=>$langs->trans("AccountWithNonZeroValues"), 'all'=>$langs->trans("All")); + $period .= '     '.$langs->trans("DetailBy").' '.$form->selectarray('showaccountdetail', $arraylist, $showaccountdetail, 0); $periodlink = $textprevyear.$textnextyear; $exportlink = ''; $description = $langs->trans("RulesResultBookkeepingPersonalized"); diff --git a/htdocs/compta/stats/index.php b/htdocs/compta/stats/index.php index 7d70bc10527..f578e6a2ec9 100644 --- a/htdocs/compta/stats/index.php +++ b/htdocs/compta/stats/index.php @@ -50,28 +50,26 @@ if (empty($year)) { } else { $year_current = $year; $month_current = dol_print_date(dol_now(), "%m"); - $year_start = $year - ($nbofyear - 1); + $year_start = $year - $nbofyear + (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); } -$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear, 'tzserver'); -$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear, 'tzserver'); +$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear, 'tzserver'); // We use timezone of server so report is same from everywhere +$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear, 'tzserver'); // We use timezone of server so report is same from everywhere // We define date_start and date_end if (empty($date_start) || empty($date_end)) { // We define date_start and date_end $q = GETPOST("q") ? GETPOST("q") : 0; if ($q == 0) { // We define date_start and date_end - $year_end = $year_start + ($nbofyear - 1); - $month_start = GETPOSTISSET("month") ? GETPOST("month", 'int') : ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1); + $year_end = $year_start + $nbofyear - (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); + $month_start = GETPOSTISSET("month") ? GETPOST("month", 'int') : getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1); if (!GETPOST('month')) { - if (!GETPOST("year") && $month_start > $month_current) { + if (!$year && $month_start > $month_current) { $year_start--; $year_end--; } $month_end = $month_start - 1; if ($month_end < 1) { $month_end = 12; - } else { - $year_end++; } } else { $month_end = $month_start; @@ -97,9 +95,6 @@ if (empty($date_start) || empty($date_end)) { // We define date_start and date_e } } -$userid = GETPOST('userid', 'int'); -$socid = GETPOST('socid', 'int'); - $tmps = dol_getdate($date_start); $mothn_start = $tmps['mon']; $year_start = $tmps['year']; @@ -113,11 +108,14 @@ $modecompta = $conf->global->ACCOUNTING_MODE; if (isModEnabled('accounting')) { $modecompta = 'BOOKKEEPING'; } -if (GETPOST("modecompta")) { +if (GETPOST("modecompta", 'alpha')) { $modecompta = GETPOST("modecompta", 'alpha'); } +$userid = GETPOST('userid', 'int'); + // Security check +$socid = GETPOST('socid', 'int'); if ($user->socid > 0) { $socid = $user->socid; } @@ -147,18 +145,13 @@ llxHeader(); $form = new Form($db); -$exportlink=""; -$namelink=""; +$exportlink = ''; +$namelink = ''; +$builddate = dol_now(); + // Affiche en-tete du rapport if ($modecompta == "CREANCES-DETTES") { $name = $langs->trans("Turnover"); - $calcmode = $langs->trans("CalcModeDebt"); - //$calcmode.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; - if (isModEnabled('accounting')) { - $calcmode .= '
('.$langs->trans("SeeReportInBookkeepingMode", '{link1}', '{link2}').')'; - $calcmode = str_replace('{link1}', '', $calcmode); - $calcmode = str_replace('{link2}', '', $calcmode); - } $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesCADue"); if (!empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { @@ -166,30 +159,17 @@ if ($modecompta == "CREANCES-DETTES") { } else { $description .= $langs->trans("DepositsAreIncluded"); } - $builddate = dol_now(); //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "RECETTES-DEPENSES") { $name = $langs->trans("TurnoverCollected"); - $calcmode = $langs->trans("CalcModeEngagement"); - //$calcmode .= '
('.$langs->trans("SeeReportInDueDebtMode",'','').')'; - //if (isModEnabled('accounting')) { - //$calcmode.='
('.$langs->trans("SeeReportInBookkeepingMode",'','').')'; - //} $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesCAIn"); $description .= $langs->trans("DepositsAreIncluded"); - $builddate = dol_now(); //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "BOOKKEEPING") { $name = $langs->trans("Turnover"); - $calcmode = $langs->trans("CalcModeBookkeeping"); - $calcmode .= '
('.$langs->trans("SeeReportInDueDebtMode", '{link1}', '{link2}').')'; - $calcmode = str_replace('{link1}', '', $calcmode); - $calcmode = str_replace('{link2}', '', $calcmode); - //$calcmode.='
('.$langs->trans("SeeReportInInputOutputMode",'','').')'; $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesSalesTurnoverOfIncomeAccounts"); - $builddate = dol_now(); //$exportlink=$langs->trans("NotYetAvailable"); } $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver'); @@ -200,6 +180,31 @@ $moreparam = array(); if (!empty($modecompta)) { $moreparam['modecompta'] = $modecompta; } + +// Define $calcmode line +$calcmode = ''; +if ($modecompta == "RECETTES-DEPENSES" || $modecompta == "BOOKKEEINGCOLLECTED") { + /*if (isModEnabled('accounting')) { + $calcmode .= ''; + $calcmode .= '
'; + }*/ + $calcmode .= ''; +} else { + if (isModEnabled('accounting')) { + $calcmode .= ''; + $calcmode .= '
'; + } + $calcmode .= ''; +} + report_header($name, $namelink, $period, $periodlink, $description, $builddate, $exportlink, $moreparam, $calcmode); if (isModEnabled('accounting') && $modecompta != 'BOOKKEEPING') { diff --git a/htdocs/compta/stats/supplier_turnover.php b/htdocs/compta/stats/supplier_turnover.php index 7e673c05f75..db6cec39cab 100644 --- a/htdocs/compta/stats/supplier_turnover.php +++ b/htdocs/compta/stats/supplier_turnover.php @@ -46,7 +46,7 @@ if (empty($year)) { } else { $year_current = $year; $month_current = dol_print_date(dol_now(), "%m"); - $year_start = $year - ($nbofyear - 1); + $year_start = $year - $nbofyear + (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); } $date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear, 'tzserver'); // We use timezone of server so report is same from everywhere $date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear, 'tzserver'); // We use timezone of server so report is same from everywhere @@ -56,18 +56,16 @@ if (empty($date_start) || empty($date_end)) { // We define date_start and date_e $q = GETPOST("q") ?GETPOST("q") : 0; if ($q == 0) { // We define date_start and date_end - $year_end = $year_start + ($nbofyear - 1); - $month_start = GETPOSTISSET("month") ? GETPOST("month", 'int') : ($conf->global->SOCIETE_FISCAL_MONTH_START ? $conf->global->SOCIETE_FISCAL_MONTH_START : 1); + $year_end = $year_start + $nbofyear - (getDolGlobalInt('SOCIETE_FISCAL_MONTH_START') > 1 ? 0 : 1); + $month_start = GETPOSTISSET("month") ? GETPOST("month", 'int') : getDolGlobalInt('SOCIETE_FISCAL_MONTH_START', 1); if (!GETPOST('month')) { - if (!GETPOST("year") && $month_start > $month_current) { + if (!$year && $month_start > $month_current) { $year_start--; $year_end--; } $month_end = $month_start - 1; if ($month_end < 1) { $month_end = 12; - } else { - $year_end++; } } else { $month_end = $month_start; @@ -107,7 +105,7 @@ $modecompta = $conf->global->ACCOUNTING_MODE; if (isModEnabled('accounting')) { $modecompta = 'BOOKKEEPING'; } -if (GETPOST("modecompta")) { +if (GETPOST("modecompta", 'alpha')) { $modecompta = GETPOST("modecompta", 'alpha'); } @@ -131,10 +129,14 @@ llxHeader(); $form = new Form($db); +$exportlink = ''; +$namelink = ''; +$builddate = dol_now(); + // TODO Report from bookkeeping not yet available, so we switch on report on business events -if ($modecompta == "BOOKKEEPING") { +/*if ($modecompta == "BOOKKEEPING") { $modecompta = "CREANCES-DETTES"; -} +}*/ if ($modecompta == "BOOKKEEPINGCOLLECTED") { $modecompta = "RECETTES-DEPENSES"; } @@ -142,42 +144,26 @@ if ($modecompta == "BOOKKEEPINGCOLLECTED") { // Affiche en-tete du rapport if ($modecompta == "CREANCES-DETTES") { $name = $langs->trans("PurchaseTurnover"); - $calcmode = $langs->trans("CalcModeDebt"); - if (isModEnabled('accounting')) { - $calcmode .= '
('.$langs->trans("SeeReportInBookkeepingMode", '{link1}', '{link2}').')'; - $calcmode = str_replace('{link1}', '', $calcmode); - $calcmode = str_replace('{link2}', '', $calcmode); - } $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesPurchaseTurnoverDue"); //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "RECETTES-DEPENSES") { $name = $langs->trans("PurchaseTurnoverCollected"); - $calcmode = $langs->trans("CalcModeEngagement"); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesPurchaseTurnoverIn"); //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "BOOKKEEPING") { $name = $langs->trans("PurchaseTurnover"); - $calcmode = $langs->trans("CalcModeBookkeeping"); - $calcmode .= '
('.$langs->trans("SeeReportInDueDebtMode", '{link1}', '{link2}').')'; - $calcmode = str_replace('{link1}', '', $calcmode); - $calcmode = str_replace('{link2}', '', $calcmode); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesPurchaseTurnoverOfExpenseAccounts"); //$exportlink=$langs->trans("NotYetAvailable"); } elseif ($modecompta == "BOOKKEEPINGCOLLECTED") { $name = $langs->trans("PurchaseTurnoverCollected"); - $calcmode = $langs->trans("CalcModeBookkeeping"); - $calcmode .= '
('.$langs->trans("SeeReportInDueDebtMode", '{link1}', '{link2}').')'; - $calcmode = str_replace('{link1}', '', $calcmode); - $calcmode = str_replace('{link2}', '', $calcmode); $periodlink = ($year_start ? "".img_previous()." ".img_next()."" : ""); $description = $langs->trans("RulesPurchaseTurnoverCollectedOfExpenseAccounts"); //$exportlink=$langs->trans("NotYetAvailable"); } -$builddate = dol_now(); $period = $form->selectDate($date_start, 'date_start', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver'); $period .= ' - '; $period .= $form->selectDate($date_end, 'date_end', 0, 0, 0, '', 1, 0, 0, '', '', '', '', 1, '', '', 'tzserver'); @@ -187,9 +173,32 @@ if (!empty($modecompta)) { $moreparam['modecompta'] = $modecompta; } -$exportlink = ''; +// Define $calcmode line +$calcmode = ''; +if ($modecompta == "RECETTES-DEPENSES" || $modecompta == "BOOKKEEPINGCOLLECTED") { + /*if (isModEnabled('accounting')) { + $calcmode .= ''; + $calcmode .= '
'; + }*/ + $calcmode .= ''; +} else { + if (isModEnabled('accounting')) { + $calcmode .= ''; + $calcmode .= '
'; + } + $calcmode .= ''; +} -report_header($name, '', $period, $periodlink, $description, $builddate, $exportlink, $moreparam, $calcmode); + +report_header($name, $namelink, $period, $periodlink, $description, $builddate, $exportlink, $moreparam, $calcmode); if (isModEnabled('accounting') && $modecompta != 'BOOKKEEPING') { print info_admin($langs->trans("WarningReportNotReliable"), 0, 0, 1); @@ -242,14 +251,19 @@ $sql .= " ORDER BY dm"; $minyearmonth = $maxyearmonth = 0; +$cum = array(); +$cum_ht = array(); +$total_ht = array(); +$total = array(); + $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); $i = 0; while ($i < $num) { $obj = $db->fetch_object($result); - $cum_ht[$obj->dm] = !empty($obj->amount) ? $obj->amount : 0; - $cum[$obj->dm] = $obj->amount_ttc; + $cum_ht[$obj->dm] = empty($obj->amount) ? 0 : $obj->amount; + $cum[$obj->dm] = empty($obj->amount_ttc) ? 0 : $obj->amount_ttc; if ($obj->amount_ttc) { $minyearmonth = ($minyearmonth ? min($minyearmonth, $obj->dm) : $obj->dm); $maxyearmonth = max($maxyearmonth, $obj->dm); @@ -348,7 +362,7 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++) { if ($annee >= $year_start) { // We ignore $annee < $year_start, we loop on it to be able to make delta, nothing is output. if ($modecompta == 'CREANCES-DETTES') { - // Valeur CA du mois w/o VAT + // Value turnover of month w/o VAT print '
'; if (!empty($cum_ht[$case])) { $now_show_delta = 1; // On a trouve le premier mois de la premiere annee generant du chiffre. @@ -363,7 +377,7 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++) { print "'; if (!empty($cum[$case])) { $now_show_delta = 1; // On a trouve le premier mois de la premiere annee generant du chiffre. @@ -383,7 +397,7 @@ for ($mois = 1 + $nb_mois_decalage; $mois <= 12 + $nb_mois_decalage; $mois++) { } print "'.($total_ht[$annee] ?price($total_ht[$annee]) : "0")."'; + print ($total_ht[$annee] ?price($total_ht[$annee]) : "0"); + print " '.($percent >= 0 ? "+$percent" : "$percent").'%'; + print ($percent >= 0 ? "+$percent" : "$percent").'%'; + print '-100%+'.$langs->trans('Inf').'%+0%'; - if ($total[$annee] || ($minyear <= $annee && $annee <= max($nowyear, $maxyear))) { + if (!empty($total[$annee]) || ($minyear <= $annee && $annee <= max($nowyear, $maxyear))) { print '-'; } else { print ' '; diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 1a9a318acb5..a7bc1e713ff 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -1504,7 +1504,7 @@ while ($i < $imaxinloop) { // Alias name if (!empty($arrayfields['s.name_alias']['checked'])) { - print ''; + print ''; print dol_escape_htmltag($obj->alias); print ' diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index d9c8a09a384..a0bf235c0eb 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -228,9 +228,13 @@ $coldisplay++; print 'pu_ttc) ? $line->pu_ttc : null; + if (getDolGlobalInt('MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES')) { + $upinctax = price2num($line->total_ttc / $line->qty, 'MU'); + } + print 'multicurrency_code != $conf->currenc print ''.$langs->trans('PriceUHTCurrency', $this->multicurrency_code).''.$langs->trans('PriceUTTC').'multicurrency_subprice); ?> pu_ttc) ? price($sign * $line->pu_ttc) : price($sign * $line->subprice)); ?>pu_ttc) ? $line->pu_ttc : null; + if (getDolGlobalInt('MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES')) { + $upinctax = price2num($line->total_ttc / $line->qty, 'MU'); + } + print (isset($upinctax) ? price($sign * $upinctax) : price($sign * $line->subprice)); + ?> diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 417ac943493..7b1c8ae6df7 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -530,6 +530,7 @@ class Expedition extends CommonObject foreach ($tab as $detbatch) { if ($detbatch->entrepot_id == $stockLocation) { if (!($detbatch->create($line_id) > 0)) { // Create an ExpeditionLineBatch + $this->errors = $detbatch->errors; $error++; } } @@ -3020,7 +3021,7 @@ class ExpeditionLigne extends CommonObjectLine $shipmentLot->qty = $this->detail_batch->qty; $shipmentLot->fk_origin_stock = $batch_id; if ($shipmentLot->create($this->id) < 0) { - $this->errors[] = $shipmentLot->errors; + $this->errors = $shipmentLot->errors; $error++; } } diff --git a/htdocs/expedition/class/expeditionlinebatch.class.php b/htdocs/expedition/class/expeditionlinebatch.class.php index ab1d9123830..b010564768f 100644 --- a/htdocs/expedition/class/expeditionlinebatch.class.php +++ b/htdocs/expedition/class/expeditionlinebatch.class.php @@ -103,11 +103,16 @@ class ExpeditionLineBatch extends CommonObject * Create an expeditiondet_batch DB record link to an expedtiondet record * * @param int $id_line_expdet rowid of expedtiondet record + * @param User $f_user User that create + * @param int $notrigger 1 = disable triggers * @return int <0 if KO, Id of record (>0) if OK */ - public function create($id_line_expdet) + public function create($id_line_expdet, $f_user = null, $notrigger = 0) { + global $user; + $error = 0; + if (!is_object($f_user)) $f_user = $user; $id_line_expdet = (int) $id_line_expdet; @@ -137,13 +142,24 @@ class ExpeditionLineBatch extends CommonObject $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX.$this->table_element); $this->fk_expeditiondet = $id_line_expdet; + } + + if (!$error && !$notrigger) { + // Call trigger + $result = $this->call_trigger('EXPEDITIONLINEBATCH_CREATE', $f_user); + if ($result < 0) { + $error++; + } + // End call triggers + } + + if (!$error) { return $this->id; } else { foreach ($this->errors as $errmsg) { dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); $this->error .= ($this->error ? ', '.$errmsg : $errmsg); } - $this->db->rollback(); return -1 * $error; } } diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php index 503fa92b108..3bff859b847 100644 --- a/htdocs/expensereport/class/expensereport_ik.class.php +++ b/htdocs/expensereport/class/expensereport_ik.class.php @@ -197,9 +197,9 @@ class ExpenseReportIk extends CommonObject $default_range = (int) $userauthor->default_range; // if not defined, then 0 $ranges = $this->getRangesByCategory($fk_c_exp_tax_cat); // prevent out of range -1 indice - $indice = $default_range > 0 ? $default_range - 1 : 0; + $indice = $default_range - 1; // substract 1 because array start from 0 - if (empty($ranges) || !isset($ranges[$indice])) { + if (empty($ranges) || $indice < 0 || !isset($ranges[$indice])) { return false; } else { return $ranges[$indice]; diff --git a/htdocs/fichinter/agenda.php b/htdocs/fichinter/agenda.php new file mode 100644 index 00000000000..4b4ef9a7215 --- /dev/null +++ b/htdocs/fichinter/agenda.php @@ -0,0 +1,256 @@ + + * Copyright (C) ---Put here your own copyright and developer email--- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/fichinter/agenda.php + * \ingroup fichinter + * \brief Tab of events on Interventions + */ +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; +require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; +require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/fichinter.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + +// Load translation files required by the page +$langs->loadLangs(array("fichinter", "other")); + +// Get parameters +$id = GETPOST('id', 'int'); +$ref = GETPOST('ref', 'alpha'); +$action = GETPOST('action', 'aZ09'); +$cancel = GETPOST('cancel', 'aZ09'); +$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search +$backtopage = GETPOST('backtopage', 'alpha'); + +if (GETPOST('actioncode', 'array')) { + $actioncode = GETPOST('actioncode', 'array', 3); + if (!count($actioncode)) { + $actioncode = '0'; + } +} else { + $actioncode = GETPOST("actioncode", "alpha", 3) ? GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT')); +} +$search_rowid = GETPOST('search_rowid'); +$search_agenda_label = GETPOST('search_agenda_label'); + +$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST('sortfield', 'aZ09comma'); +$sortorder = GETPOST('sortorder', 'aZ09comma'); +$page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); +if (empty($page) || $page == -1) { + $page = 0; +} // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortfield) { + $sortfield = 'a.datep,a.id'; +} +if (!$sortorder) { + $sortorder = 'DESC,DESC'; +} + +// Initialize technical objects +$object = new Fichinter($db); +$extrafields = new ExtraFields($db); +$diroutputmassaction = $conf->fichinter->multidir_output[$conf->entity].'/temp/massgeneration/'.$user->id; +$hookmanager->initHooks(array('myobjectagenda', 'globalcard')); // Note that conf->hooks_modules contains array +// Fetch optionals attributes and labels +$extrafields->fetch_name_optionals_label($object->table_element); + +// Load object +include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals +if ($id > 0 || !empty($ref)) { + $upload_dir = $conf->fichinter->multidir_output[!empty($object->entity) ? $object->entity : $conf->entity]."/".$object->id; +} + +$permissiontoread = $user->hasRight("fichinter", "lire"); +$permissiontoadd = $user->hasRight("fichinter", "creer"); + +// Security check +if (!empty($user->socid)) { + $socid = $user->socid; +} +$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0); +restrictedArea($user, 'ficheinter', $object->id, '', '', 'fk_soc', 'rowid', $isdraft); + + +/* + * Actions + */ + +$parameters = array('id'=>$id); +$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) { + setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); +} + +if (empty($reshook)) { + // Cancel + if (GETPOST('cancel', 'alpha') && !empty($backtopage)) { + header("Location: ".$backtopage); + exit; + } + + // Purge search criteria + if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All tests are required to be compatible with all browsers + $actioncode = ''; + $search_agenda_label = ''; + } +} + + + +/* + * View + */ + +$form = new Form($db); + +if ($object->id > 0) { + $title = $langs->trans("Agenda"); + //if (!empty($conf->global->MAIN_HTML_TITLE) && preg_match('/thirdpartynameonly/',$conf->global->MAIN_HTML_TITLE) && $object->name) $title=$object->name." - ".$title; + $help_url = 'EN:Module_Agenda_En|DE:Modul_Terminplanung'; + llxHeader('', $title, $help_url); + + if (isModEnabled('notification')) { + $langs->load("mails"); + } + $head = fichinter_prepare_head($object); + + + print dol_get_fiche_head($head, 'agenda', $langs->trans("Intervention"), -1, $object->picto); + + // Object card + // ------------------------------------------------------------ + $linkback = ''.$langs->trans("BackToList").''; + + $morehtmlref = '
'; + // Ref customer + $morehtmlref .= $form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref .= $form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + // Thirdparty + $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1); + // Project + if (isModEnabled('project')) { + $langs->load("projects"); + $morehtmlref .= '
'; + if (0) { + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); + if ($action != 'classify') { + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; + } + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); + } else { + if (!empty($object->fk_project)) { + $proj = new Project($db); + $proj->fetch($object->fk_project); + $morehtmlref .= $proj->getNomUrl(1); + if ($proj->title) { + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; + } + } + } + } + $morehtmlref .= '
'; + + + dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); + + print '
'; + print '
'; + + $object->info($object->id); + dol_print_object_info($object, 1); + + print '
'; + + print dol_get_fiche_end(); + + + + // Actions buttons + + $objthirdparty = $object; + $objcon = new stdClass(); + + $out = '&origin='.urlencode($object->element.(property_exists($object, 'module') ? '@'.$object->module : '')).'&originid='.urlencode($object->id); + $urlbacktopage = $_SERVER['PHP_SELF'].'?id='.$object->id; + $out .= '&backtopage='.urlencode($urlbacktopage); + $permok = $user->rights->agenda->myactions->create; + if ((!empty($objthirdparty->id) || !empty($objcon->id)) && $permok) { + //$out.='trans("AddAnAction"),'filenew'); + //$out.=""; + } + + $morehtmlright = ''; + + //$messagingUrl = DOL_URL_ROOT.'/societe/messaging.php?socid='.$object->id; + //$morehtmlright .= dolGetButtonTitle($langs->trans('ShowAsConversation'), '', 'fa fa-comments imgforviewmode', $messagingUrl, '', 1); + //$messagingUrl = DOL_URL_ROOT.'/societe/agenda.php?socid='.$object->id; + //$morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 2); + + if (isModEnabled('agenda')) { + if ($user->hasRight('agenda', 'myactions', 'create') || $user->hasRight('agenda', 'allactions', 'create')) { + $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/fichinter/card.php?action=create'.$out); + } else { + $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/fichinter/card.php?action=create'.$out, '', 0); + } + } + + + if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) { + print '
'; + + $param = '&id='.$object->id.(!empty($socid) ? '&socid='.$socid : ''); + if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage='.urlencode($contextpage); + } + if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.urlencode($limit); + } + + // Try to know count of actioncomm from cache + require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php'; + $cachekey = 'count_events_fichinter_'.$object->id; + $nbEvent = dol_getcache($cachekey); + + print_barre_liste($langs->trans("ActionsOnFicheInter").(is_numeric($nbEvent) ? '('.$nbEvent.')': ''), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1); + //print_barre_liste($langs->trans("ActionsOnPropal"), 0, $_SERVER["PHP_SELF"], '', $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1); + + // List of all actions + $filters = array(); + $filters['search_agenda_label'] = $search_agenda_label; + $filters['search_rowid'] = $search_rowid; + + // TODO Replace this with same code than into list.php + show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder, property_exists($object, 'module') ? $object->module : ''); + } +} + +// End of page +llxFooter(); +$db->close(); diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index f5aa06d48d5..0f18d024671 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -102,10 +102,12 @@ if ($user->socid) { } $result = restrictedArea($user, 'ficheinter', $id, 'fichinter'); -$permissionnote = $user->rights->ficheinter->creer; // Used by the include of actions_setnotes.inc.php -$permissiondellink = $user->rights->ficheinter->creer; // Used by the include of actions_dellink.inc.php +$permissionnote = $user->hasRight('ficheinter', 'creer'); // Used by the include of actions_setnotes.inc.php +$permissiondellink = $user->hasRight('ficheinter', 'creer'); // Used by the include of actions_dellink.inc.php $permissiontodelete = (($object->statut == Fichinter::STATUS_DRAFT && $user->hasRight('ficheinter', 'creer')) || $user->rights->ficheinter->supprimer); +$usercancreate = $user->hasRight('ficheinter', 'creer'); + /* * Actions @@ -1163,32 +1165,21 @@ if ($action == 'create') { // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= '
'.$langs->trans('Project').' '; - if ($user->rights->ficheinter->creer) { + $morehtmlref .= '
'; + if ($usercancreate) { + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' : '; - } - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; - $morehtmlref .= ''; - } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ' : '.$proj->getNomUrl(1); + $morehtmlref .= $proj->getNomUrl(1); if ($proj->title) { - $morehtmlref .= ' - '.$proj->title; + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; } - } else { - $morehtmlref .= ''; } } } @@ -1729,10 +1720,14 @@ if ($action == 'create') { print '
'; + $MAXEVENT = 10; + + $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/fichinter/agenda.php?id='.$object->id); + // List of actions on element include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php'; $formactions = new FormActions($db); - $somethingshown = $formactions->showactions($object, 'fichinter', $socid, 1); + $somethingshown = $formactions->showactions($object, 'fichinter', $socid, 1, '', $MAXEVENT, '', $morehtmlcenter); // Show all action for thirdparty print '
'; } diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php index 98cb04368a1..6609ce03786 100644 --- a/htdocs/fichinter/class/api_interventions.class.php +++ b/htdocs/fichinter/class/api_interventions.class.php @@ -16,9 +16,15 @@ * along with this program. If not, see . */ - use Luracast\Restler\RestException; +/** + * \file htdocs/fichinter/class/api_interventions.class.php + * \ingroup fichinter + * \brief File of API to manage intervention + */ +use Luracast\Restler\RestException; + +require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; - require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; /** * API class for Interventions diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 606a88c9d51..45a78d2914d 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -24,7 +24,7 @@ /** * \file htdocs/fichinter/class/fichinter.class.php - * \ingroup ficheinter + * \ingroup fichinter * \brief Fichier de la classe des gestion des fiches interventions */ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; diff --git a/htdocs/fichinter/class/fichinterrec.class.php b/htdocs/fichinter/class/fichinterrec.class.php index 44dd63abcd2..17104fb757d 100644 --- a/htdocs/fichinter/class/fichinterrec.class.php +++ b/htdocs/fichinter/class/fichinterrec.class.php @@ -24,7 +24,7 @@ /** * \file htdocs/fichinter/class/fichinterrec.class.php - * \ingroup facture + * \ingroup fichinter * \brief Fichier de la classe des factures recurentes */ diff --git a/htdocs/fichinter/contact.php b/htdocs/fichinter/contact.php index 9884fb1e2cd..6c41c6fb8e1 100644 --- a/htdocs/fichinter/contact.php +++ b/htdocs/fichinter/contact.php @@ -52,6 +52,9 @@ if (!$result) { exit; } +$usercancreate = $user->hasRight('ficheinter', 'creer'); + + /* * Adding a new contact */ @@ -119,40 +122,30 @@ if ($id > 0 || !empty($ref)) { $morehtmlref = '
'; // Ref customer - //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); - //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->ficheinter->creer, 'string', '', 0, 1); + //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->ficheinter->creer, 'string', '', null, null, '', 1); + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); // Thirdparty - $morehtmlref .= $langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1); + $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1, 'customer'); // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= '
'.$langs->trans('Project').' '; - if ($user->rights->ficheinter->creer) { + $morehtmlref .= '
'; + if ($usercancreate && 0) { + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref .= ' : '; - } - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref .= '
'; - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; - $morehtmlref .= '
'; - } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ' : '.$proj->getNomUrl(1); + $morehtmlref .= $proj->getNomUrl(1); if ($proj->title) { - $morehtmlref .= ' - '.$proj->title; + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; } - } else { - $morehtmlref .= ''; } } } diff --git a/htdocs/fichinter/document.php b/htdocs/fichinter/document.php index 52d1019d755..32495a8b9ad 100644 --- a/htdocs/fichinter/document.php +++ b/htdocs/fichinter/document.php @@ -119,40 +119,30 @@ if ($object->id) { $morehtmlref = '
'; // Ref customer - //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); - //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->ficheinter->creer, 'string', '', 0, 1); + //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->ficheinter->creer, 'string', '', null, null, '', 1); + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); // Thirdparty - $morehtmlref .= $langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1); + $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1, 'customer'); // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= '
'.$langs->trans('Project').' '; - if ($user->hasRight('commande', 'creer')) { + $morehtmlref .= '
'; + if ($usercancreate && 0) { + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref .= ' : '; - } - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref .= '
'; - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; - $morehtmlref .= '
'; - } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ' : '.$proj->getNomUrl(1); + $morehtmlref .= $proj->getNomUrl(1); if ($proj->title) { - $morehtmlref .= ' - '.$proj->title; + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; } - } else { - $morehtmlref .= ''; } } } diff --git a/htdocs/fichinter/info.php b/htdocs/fichinter/info.php deleted file mode 100644 index 77e31705790..00000000000 --- a/htdocs/fichinter/info.php +++ /dev/null @@ -1,132 +0,0 @@ - - * Copyright (C) 2009-2016 Laurent Destailleur - * Copyright (C) 2011 Juanjo Menent - * Copyright (C) 2017 Ferran Marcet - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/fichinter/info.php - * \ingroup fichinter - * \brief Page d'affichage des infos d'une fiche d'intervention - */ - -// Load Dolibarr environment -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/fichinter.lib.php'; -if (isModEnabled('project')) { - require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -} - -// Load translation files required by the page -$langs->loadLangs(array('companies', 'interventions')); - -$socid = 0; -$id = GETPOST('id', 'int'); -$ref = GETPOST('ref', 'alpha'); - -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'ficheinter', $id, 'fichinter'); - -$object = new Fichinter($db); - -if (!$object->fetch($id, $ref) > 0) { - dol_print_error($db); - exit; -} - - -/* - * View - */ - -$form = new Form($db); - -llxHeader('', $langs->trans("Intervention")); - -$object->fetch_thirdparty(); -$object->info($object->id); - -$head = fichinter_prepare_head($object); -print dol_get_fiche_head($head, 'info', $langs->trans('InterventionCard'), -1, 'intervention'); - -// Intervention card -$linkback = ''.$langs->trans("BackToList").''; - - -$morehtmlref = '
'; -// Ref customer -//$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); -//$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); -// Thirdparty -$morehtmlref .= $langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1); -// Project -if (isModEnabled('project')) { - $langs->load("projects"); - $morehtmlref .= '
'.$langs->trans('Project').' '; - if ($user->hasRight('commande', 'creer')) { - if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref .= ' : '; - } - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref .= '
'; - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; - $morehtmlref .= '
'; - } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); - } - } else { - if (!empty($object->fk_project)) { - $proj = new Project($db); - $proj->fetch($object->fk_project); - $morehtmlref .= ' : '.$proj->getNomUrl(1); - if ($proj->title) { - $morehtmlref .= ' - '.$proj->title; - } - } else { - $morehtmlref .= ''; - } - } -} -$morehtmlref .= '
'; - -dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); - -print '
'; -print '
'; - -print '
'; - -print '
'; -dol_print_object_info($object); -print '
'; - -print '
'; - -print dol_get_fiche_end(); - -llxFooter(); -$db->close(); diff --git a/htdocs/fichinter/note.php b/htdocs/fichinter/note.php index f80f08a44bc..aa2f452bbd0 100644 --- a/htdocs/fichinter/note.php +++ b/htdocs/fichinter/note.php @@ -84,40 +84,30 @@ if ($id > 0 || !empty($ref)) { $morehtmlref = '
'; // Ref customer - //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); - //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->ficheinter->creer, 'string', '', 0, 1); + //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, $user->rights->ficheinter->creer, 'string', '', null, null, '', 1); + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); // Thirdparty - $morehtmlref .= $langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1); + $morehtmlref .= '
'.$object->thirdparty->getNomUrl(1, 'customer'); // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= '
'.$langs->trans('Project').' '; - if ($user->hasRight('commande', 'creer')) { + $morehtmlref .= '
'; + if ($usercancreate && 0) { + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - //$morehtmlref.='' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref .= ' : '; - } - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $object->id, $object->socid, $object->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref .= '
'; - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects($object->socid, $object->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; - $morehtmlref .= '
'; - } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($object->fk_project)) { $proj = new Project($db); $proj->fetch($object->fk_project); - $morehtmlref .= ' : '.$proj->getNomUrl(1); + $morehtmlref .= $proj->getNomUrl(1); if ($proj->title) { - $morehtmlref .= ' - '.$proj->title; + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; } - } else { - $morehtmlref .= ''; } } } diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 066c5918742..4be37fe4130 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -649,7 +649,7 @@ class FactureFournisseur extends CommonInvoice $res = $this->updateline( $idligne, $this->lines[$i]->description, - $this->lines[$i]->pu_ht, + $this->lines[$i]->subprice, $this->lines[$i]->tva_tx.($this->lines[$i]->vat_src_code ? ' ('.$this->lines[$i]->vat_src_code.')' : ''), $this->lines[$i]->localtax1_tx, $this->lines[$i]->localtax2_tx, @@ -1824,12 +1824,11 @@ class FactureFournisseur extends CommonInvoice $cpt = count($this->lines); for ($i = 0; $i < $cpt; $i++) { if ($this->lines[$i]->fk_product > 0) { - $this->line = $this->lines[$i]; $mouvP = new MouvementStock($this->db); $mouvP->origin = &$this; $mouvP->setOrigin($this->element, $this->id); // We increase stock for product - $up_ht_disc = $this->lines[$i]->pu_ht; + $up_ht_disc = $this->lines[$i]->subprice; if (!empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) { $up_ht_disc = price2num($up_ht_disc * (100 - $this->lines[$i]->remise_percent) / 100, 'MU'); } @@ -1841,7 +1840,6 @@ class FactureFournisseur extends CommonInvoice if ($result < 0) { $error++; } - unset($this->line); } } } @@ -2174,61 +2172,61 @@ class FactureFournisseur extends CommonInvoice } // Insert line - $this->line = new SupplierInvoiceLine($this->db); + $supplierinvoiceline = new SupplierInvoiceLine($this->db); - $this->line->context = $this->context; + $supplierinvoiceline->context = $this->context; - $this->line->fk_facture_fourn = $this->id; - //$this->line->label=$label; // deprecated - $this->line->desc = $desc; - $this->line->ref_supplier = $ref_supplier; + $supplierinvoiceline->fk_facture_fourn = $this->id; + //$supplierinvoiceline->label=$label; // deprecated + $supplierinvoiceline->desc = $desc; + $supplierinvoiceline->ref_supplier = $ref_supplier; - $this->line->qty = ($this->type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty); // For credit note, quantity is always positive and unit price negative - $this->line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise + $supplierinvoiceline->qty = ($this->type == self::TYPE_CREDIT_NOTE ? abs($qty) : $qty); // For credit note, quantity is always positive and unit price negative + $supplierinvoiceline->subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise - $this->line->vat_src_code = $vat_src_code; - $this->line->tva_tx = $txtva; - $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0); - $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0); - $this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; - $this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; + $supplierinvoiceline->vat_src_code = $vat_src_code; + $supplierinvoiceline->tva_tx = $txtva; + $supplierinvoiceline->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0); + $supplierinvoiceline->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0); + $supplierinvoiceline->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0]; + $supplierinvoiceline->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2]; - $this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative - $this->line->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva); // For credit note and if qty is negative, total is negative - $this->line->total_localtax1 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax1) : $total_localtax1); // For credit note and if qty is negative, total is negative - $this->line->total_localtax2 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax2) : $total_localtax2); // For credit note and if qty is negative, total is negative - $this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc); // For credit note and if qty is negative, total is negative + $supplierinvoiceline->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative + $supplierinvoiceline->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_tva) : $total_tva); // For credit note and if qty is negative, total is negative + $supplierinvoiceline->total_localtax1 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax1) : $total_localtax1); // For credit note and if qty is negative, total is negative + $supplierinvoiceline->total_localtax2 = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_localtax2) : $total_localtax2); // For credit note and if qty is negative, total is negative + $supplierinvoiceline->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($total_ttc) : $total_ttc); // For credit note and if qty is negative, total is negative - $this->line->fk_product = $fk_product; - $this->line->product_type = $type; - $this->line->remise_percent = $remise_percent; - $this->line->date_start = $date_start; - $this->line->date_end = $date_end; - $this->line->fk_code_ventilation = $ventil; - $this->line->rang = $rang; - $this->line->info_bits = $info_bits; - $this->line->fk_remise_except = $fk_remise_except; + $supplierinvoiceline->fk_product = $fk_product; + $supplierinvoiceline->product_type = $type; + $supplierinvoiceline->remise_percent = $remise_percent; + $supplierinvoiceline->date_start = $date_start; + $supplierinvoiceline->date_end = $date_end; + $supplierinvoiceline->fk_code_ventilation = $ventil; + $supplierinvoiceline->rang = $rang; + $supplierinvoiceline->info_bits = $info_bits; + $supplierinvoiceline->fk_remise_except = $fk_remise_except; - $this->line->special_code = ((string) $special_code != '' ? $special_code : $this->special_code); - $this->line->fk_parent_line = $fk_parent_line; - $this->line->origin = $this->origin; - $this->line->origin_id = $origin_id; - $this->line->fk_unit = $fk_unit; + $supplierinvoiceline->special_code = ((string) $special_code != '' ? $special_code : $this->special_code); + $supplierinvoiceline->fk_parent_line = $fk_parent_line; + $supplierinvoiceline->origin = $this->origin; + $supplierinvoiceline->origin_id = $origin_id; + $supplierinvoiceline->fk_unit = $fk_unit; // Multicurrency - $this->line->fk_multicurrency = $this->fk_multicurrency; - $this->line->multicurrency_code = $this->multicurrency_code; - $this->line->multicurrency_subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise); // For credit note, unit price always negative, always positive otherwise + $supplierinvoiceline->fk_multicurrency = $this->fk_multicurrency; + $supplierinvoiceline->multicurrency_code = $this->multicurrency_code; + $supplierinvoiceline->multicurrency_subprice = ($this->type == self::TYPE_CREDIT_NOTE ? -abs($pu_ht_devise) : $pu_ht_devise); // For credit note, unit price always negative, always positive otherwise - $this->line->multicurrency_total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht); // For credit note and if qty is negative, total is negative - $this->line->multicurrency_total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva); // For credit note and if qty is negative, total is negative - $this->line->multicurrency_total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc); // For credit note and if qty is negative, total is negative + $supplierinvoiceline->multicurrency_total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ht) : $multicurrency_total_ht); // For credit note and if qty is negative, total is negative + $supplierinvoiceline->multicurrency_total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_tva) : $multicurrency_total_tva); // For credit note and if qty is negative, total is negative + $supplierinvoiceline->multicurrency_total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ? -abs($multicurrency_total_ttc) : $multicurrency_total_ttc); // For credit note and if qty is negative, total is negative if (is_array($array_options) && count($array_options) > 0) { - $this->line->array_options = $array_options; + $supplierinvoiceline->array_options = $array_options; } - $result = $this->line->insert($notrigger); + $result = $supplierinvoiceline->insert($notrigger); if ($result > 0) { // Reorder if child line if (!empty($fk_parent_line)) { @@ -2244,15 +2242,15 @@ class FactureFournisseur extends CommonInvoice $result = $this->update_price(1, 'auto', 0, $this->thirdparty); // The addline method is designed to add line from user input so total calculation with update_price must be done using 'auto' mode. if ($result > 0) { $this->db->commit(); - return $this->line->id; + return $supplierinvoiceline->id; } else { $this->error = $this->db->error(); $this->db->rollback(); return -1; } } else { - $this->error = $this->line->error; - $this->errors = $this->line->errors; + $this->error = $supplierinvoiceline->error; + $this->errors = $supplierinvoiceline->errors; $this->db->rollback(); return -2; } diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 341b0c700e1..f3c7130e7f8 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -1497,9 +1497,11 @@ class Holiday extends CommonObject } $out .= ''."\n"; - $out .= ajax_combobox($htmlname); - print $out; + $showempty= 0; + $out .= ajax_combobox($htmlname, array(), 0, 0, 'resolve', ($showempty < 0 ? (string) $showempty : '-1'), $morecss); + + return $out; } /** @@ -2488,7 +2490,7 @@ class Holiday extends CommonObject $return .= ''; if (property_exists($this, 'fk_type')) { $return .= '
'.$langs->trans("Type").' : '; - $return .= ''.arraydata['labeltype'].''; + $return .= ''.$arraydata['labeltype'].''; } if (property_exists($this, 'date_debut') && property_exists($this, 'date_fin')) { $return .= '
'.dol_print_date($this->date_debut, 'day').''; diff --git a/htdocs/holiday/define_holiday.php b/htdocs/holiday/define_holiday.php index 2eb69145254..6ff31497a57 100644 --- a/htdocs/holiday/define_holiday.php +++ b/htdocs/holiday/define_holiday.php @@ -363,6 +363,7 @@ if (count($typeleaves) == 0) { print_liste_field_titre((empty($user->rights->holiday->define_holiday) ? '' : 'Note'), $_SERVER["PHP_SELF"]); print_liste_field_titre(''); + $selectedfields = ''; if ($massactionbutton) { $selectedfields = $form->showCheckAddButtons('checkforselect', 1); } diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index 3f8f9d69131..0be113d8205 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -143,7 +143,13 @@ if ($user->socid > 0) { // Protection if external user accessforbidden(); } -if (empty($conf->holiday->enabled)) accessforbidden('Module not enabled'); +$permissiontoread = $user->hasRight('holiday', 'read'); +$permissiontodelete = $user->hasRight('holiday', 'delete'); +$permissiontoapprove = $user->hasRight('holiday', 'approve'); + +if (!ismodEnabled('holiday')) { + accessforbidden('Module holiday not enabled'); +} $result = restrictedArea($user, 'holiday', '', ''); // If we are on the view of a specific user @@ -152,10 +158,10 @@ if ($id > 0) { if ($id == $user->id) { $canread = 1; } - if (!empty($user->rights->holiday->readall)) { + if ($user->hasRight('holiday', 'readall')) { $canread = 1; } - if (!empty($user->rights->holiday->read) && in_array($id, $childids)) { + if ($user->hasRight('holiday', 'read') && in_array($id, $childids)) { $canread = 1; } if (!$canread) { @@ -165,13 +171,13 @@ if ($id > 0) { - /* * Actions */ if (GETPOST('cancel', 'alpha')) { - $action = 'list'; $massaction = ''; + $action = 'list'; + $massaction = ''; } if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massaction != 'confirm_presend') { $massaction = ''; @@ -211,9 +217,6 @@ if (empty($reshook)) { // Mass actions $objectclass = 'Holiday'; $objectlabel = 'Holiday'; - $permissiontoread = $user->hasRight('holiday', 'read'); - $permissiontodelete = $user->hasRight('holiday', 'delete'); - $permissiontoapprove = $user->hasRight('holiday', 'approve'); $uploaddir = $conf->holiday->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -236,6 +239,8 @@ $holidaystatic = new Holiday($db); $result = $object->updateBalance(); $title = $langs->trans('CPTitreMenu'); +$help_url = ''; + llxHeader('', $title); $max_year = 5; @@ -304,7 +309,8 @@ if (!empty($extrafields->attributes[$object->table_element]['label'])) { // Add fields from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook -$sql .= $hookmanager->resPrint; +$sql .= preg_replace('/^,/', '', $hookmanager->resPrint); +$sql = preg_replace('/,\s*$/', '', $sql); $sqlfields = $sql; // $sql fields to remove for count total @@ -357,7 +363,7 @@ if ($id > 0) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters = array(); -$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook +$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object, $action); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; // Count total nb of records @@ -374,7 +380,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { dol_print_error($db); } - if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0 + if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller than the paging size (filtering), goto and load page 0 $page = 0; $offset = 0; } @@ -389,656 +395,703 @@ if ($limit) { //print $sql; $resql = $db->query($sql); -if ($resql) { - $num = $db->num_rows($resql); +if (!$resql) { + dol_print_error($db); + exit; +} - $arrayofselected = is_array($toselect) ? $toselect : array(); +$num = $db->num_rows($resql); - $param = ''; - if (!empty($mode)) { - $param .= '&mode='.urlencode($mode); - } - if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { - $param .= '&contextpage='.urlencode($contextpage); - } - if ($limit > 0 && $limit != $conf->liste_limit) { - $param .= '&limit='.urlencode($limit); - } - if ($optioncss != '') { - $param .= '&optioncss='.urlencode($optioncss); - } - if ($search_ref) { - $param .= '&search_ref='.urlencode($search_ref); - } - if ($search_day_create) { - $param .= '&search_day_create='.urlencode($search_day_create); - } - if ($search_month_create) { - $param .= '&search_month_create='.urlencode($search_month_create); - } - if ($search_year_create) { - $param .= '&search_year_create='.urlencode($search_year_create); - } - if ($search_day_start) { - $param .= '&search_day_start='.urlencode($search_day_start); - } - if ($search_month_start) { - $param .= '&search_month_start='.urlencode($search_month_start); - } - if ($search_year_start) { - $param .= '&search_year_start='.urlencode($search_year_start); - } - if ($search_day_end) { - $param .= '&search_day_end='.urlencode($search_day_end); - } - if ($search_month_end) { - $param .= '&search_month_end='.urlencode($search_month_end); - } - if ($search_year_end) { - $param .= '&search_year_end='.urlencode($search_year_end); - } - if ($search_employee > 0) { - $param .= '&search_employee='.urlencode($search_employee); - } - if ($search_valideur > 0) { - $param .= '&search_valideur='.urlencode($search_valideur); - } - if ($search_type > 0) { - $param .= '&search_type='.urlencode($search_type); - } - if ($search_status > 0) { - $param .= '&search_status='.urlencode($search_status); - } - // Add $param from extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; +$arrayofselected = is_array($toselect) ? $toselect : array(); - // List of mass actions available - $arrayofmassactions = array( - //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), - //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), - //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), - ); - if (!empty($user->rights->holiday->delete)) { - $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); - } - if (!empty($user->rights->holiday->approve)) { - $arrayofmassactions['preapproveleave'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Approve"); - } - if (in_array($massaction, array('presend', 'predelete'))) { - $arrayofmassactions = array(); - } - $massactionbutton = $form->selectMassAction('', $arrayofmassactions); +$param = ''; +if (!empty($mode)) { + $param .= '&mode='.urlencode($mode); +} +if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { + $param .= '&contextpage='.urlencode($contextpage); +} +if ($limit > 0 && $limit != $conf->liste_limit) { + $param .= '&limit='.((int) $limit); +} +if ($optioncss != '') { + $param .= '&optioncss='.urlencode($optioncss); +} +if ($search_ref) { + $param .= '&search_ref='.urlencode($search_ref); +} +if ($search_day_create) { + $param .= '&search_day_create='.urlencode($search_day_create); +} +if ($search_month_create) { + $param .= '&search_month_create='.urlencode($search_month_create); +} +if ($search_year_create) { + $param .= '&search_year_create='.urlencode($search_year_create); +} +if ($search_day_start) { + $param .= '&search_day_start='.urlencode($search_day_start); +} +if ($search_month_start) { + $param .= '&search_month_start='.urlencode($search_month_start); +} +if ($search_year_start) { + $param .= '&search_year_start='.urlencode($search_year_start); +} +if ($search_day_end) { + $param .= '&search_day_end='.urlencode($search_day_end); +} +if ($search_month_end) { + $param .= '&search_month_end='.urlencode($search_month_end); +} +if ($search_year_end) { + $param .= '&search_year_end='.urlencode($search_year_end); +} +if ($search_employee > 0) { + $param .= '&search_employee='.urlencode($search_employee); +} +if ($search_valideur > 0) { + $param .= '&search_valideur='.urlencode($search_valideur); +} +if ($search_type > 0) { + $param .= '&search_type='.urlencode($search_type); +} +if ($search_status > 0) { + $param .= '&search_status='.urlencode($search_status); +} +// Add $param from extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; - // Lines of title fields - print '
'."\n"; - if ($optioncss != '') { - print ''; - } - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; +// List of mass actions available +$arrayofmassactions = array( + //'generate_doc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("ReGeneratePDF"), + //'builddoc'=>img_picto('', 'pdf', 'class="pictofixedwidth"').$langs->trans("PDFMerge"), + //'presend'=>img_picto('', 'email', 'class="pictofixedwidth"').$langs->trans("SendByMail"), +); +if (!empty($permissiontodelete)) { + $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete"); +} +if (!empty($permissiontoapprove)) { + $arrayofmassactions['preapproveleave'] = img_picto('', 'check', 'class="pictofixedwidth"').$langs->trans("Approve"); +} +if (GETPOST('nomassaction', 'int') || in_array($massaction, array('presend', 'predelete'))) { + $arrayofmassactions = array(); +} +$massactionbutton = $form->selectMassAction('', $arrayofmassactions); - if ($id > 0) { - print ''; +print ''."\n"; +if ($optioncss != '') { + print ''; +} +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +if ($id > 0) { + print ''; +} + +if ($id > 0) { // For user tab + $title = $langs->trans("User"); + $linkback = ''.$langs->trans("BackToList").''; + $head = user_prepare_head($fuser); + + print dol_get_fiche_head($head, 'paidholidays', $title, -1, 'user'); + + dol_banner_tab($fuser, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + + if (empty($conf->global->HOLIDAY_HIDE_BALANCE)) { + print '
'; + + print '
'; + + showMyBalance($object, $user_id); } - if ($id > 0) { // For user tab - $title = $langs->trans("User"); - $linkback = ''.$langs->trans("BackToList").''; - $head = user_prepare_head($fuser); + print dol_get_fiche_end(); - print dol_get_fiche_head($head, 'paidholidays', $title, -1, 'user'); + // Buttons for actions - dol_banner_tab($fuser, 'id', $linkback, $user->rights->user->user->lire || $user->admin); + print '
'; - if (empty($conf->global->HOLIDAY_HIDE_BALANCE)) { - print '
'; - - print '
'; - - showMyBalance($object, $user_id); - } - - print dol_get_fiche_end(); - - // Buttons for actions - - print '
'; - - $cancreate = 0; - if (!empty($user->rights->holiday->writeall)) { - $cancreate = 1; - } - if (!empty($user->rights->holiday->write) && in_array($user_id, $childids)) { - $cancreate = 1; - } - - if ($cancreate) { - print ''.$langs->trans("AddCP").''; - } - - print '
'; - } else { - $title = $langs->trans("ListeCP"); - - - $newcardbutton = ''; - $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); - $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); - $newcardbutton .= dolGetButtonTitle($langs->trans('MenuAddCP'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/holiday/card.php?action=create', '', $user->rights->holiday->write); - - print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_hrm', 0, $newcardbutton, '', $limit, 0, 0, 1); + $cancreate = 0; + if (!empty($user->rights->holiday->writeall)) { + $cancreate = 1; + } + if (!empty($user->rights->holiday->write) && in_array($user_id, $childids)) { + $cancreate = 1; } - $topicmail = "Information"; - $modelmail = "leaverequest"; - $objecttmp = new Holiday($db); - $trackid = 'leav'.$object->id; - include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; - - if ($sall) { - foreach ($fieldstosearchall as $key => $val) { - $fieldstosearchall[$key] = $langs->trans($val); - } - print '
'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'
'; + if ($cancreate) { + print ''.$langs->trans("AddCP").''; } - $moreforfilter = ''; + print '
'; +} else { + $title = $langs->trans("ListeCP"); - $parameters = array(); - $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters); // Note that $action and $object may have been modified by hook - if (empty($reshook)) { - $moreforfilter .= $hookmanager->resPrint; - } else { - $moreforfilter = $hookmanager->resPrint; + + $newcardbutton = ''; + $newcardbutton .= dolGetButtonTitle($langs->trans('ViewList'), '', 'fa fa-bars imgforviewmode', $_SERVER["PHP_SELF"].'?mode=common'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ((empty($mode) || $mode == 'common') ? 2 : 1), array('morecss'=>'reposition')); + $newcardbutton .= dolGetButtonTitle($langs->trans('ViewKanban'), '', 'fa fa-th-list imgforviewmode', $_SERVER["PHP_SELF"].'?mode=kanban'.preg_replace('/(&|\?)*mode=[^&]+/', '', $param), '', ($mode == 'kanban' ? 2 : 1), array('morecss'=>'reposition')); + $newcardbutton .= dolGetButtonTitleSeparator(); + $newcardbutton .= dolGetButtonTitle($langs->trans('MenuAddCP'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/holiday/card.php?action=create', '', $user->rights->holiday->write); + + print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_hrm', 0, $newcardbutton, '', $limit, 0, 0, 1); +} + +$topicmail = "Information"; +$modelmail = "leaverequest"; +$objecttmp = new Holiday($db); +$trackid = 'leav'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + +if ($sall) { + $setupstring = ''; + foreach ($fieldstosearchall as $key => $val) { + $fieldstosearchall[$key] = $langs->trans($val); + $setupstring .= $key."=".$val.";"; + } + print ''."\n"; + print '
'.$langs->trans("FilterOnInto", $sall).join(', ', $fieldstosearchall).'
'; +} + +$moreforfilter = ''; + +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +if (empty($reshook)) { + $moreforfilter .= $hookmanager->resPrint; +} else { + $moreforfilter = $hookmanager->resPrint; +} + +if (!empty($moreforfilter)) { + print '
'; + print $moreforfilter; + $parameters = array('type'=>$type); + $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + print '
'; +} + +$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; +$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields +$selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); + +$include = ''; +if (empty($user->rights->holiday->readall)) { + $include = 'hierarchyme'; // Can see only its hierarchyl +} + +print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table +print ''."\n"; + +// Fields title search +// -------------------------------------------------------------------- +print ''; +// Action column +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; +} +if (!empty($arrayfields['cp.ref']['checked'])) { + print ''; +} + +if (!empty($arrayfields['cp.fk_user']['checked'])) { + $morefilter = ''; + if (!empty($conf->global->HOLIDAY_HIDE_FOR_NON_SALARIES)) { + $morefilter = 'AND employee = 1'; } - if (!empty($moreforfilter)) { - print '
'; - print $moreforfilter; - print '
'; + // User + $disabled = 0; + // If into the tab holiday of a user ($id is set in such a case) + if ($id && !GETPOSTISSET('search_employee')) { + $search_employee = $id; + $disabled = 1; } - $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; - $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')); // This also change content of $arrayfields - $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); - - - $include = ''; - if (empty($user->rights->holiday->readall)) { - $include = 'hierarchyme'; // Can see only its hierarchyl - } - - print '
'; - print '
'; + $searchpicto = $form->showFilterButtons('left'); + print $searchpicto; + print ''; + print ''; + print '
'."\n"; - - - // Filters - print ''; - // Action column - if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - } - if (!empty($arrayfields['cp.ref']['checked'])) { - print ''; - } - - if (!empty($arrayfields['cp.fk_user']['checked'])) { - $morefilter = ''; - if (!empty($conf->global->HOLIDAY_HIDE_FOR_NON_SALARIES)) { - $morefilter = 'AND employee = 1'; - } - - // User - $disabled = 0; - // If into the tab holiday of a user ($id is set in such a case) - if ($id && !GETPOSTISSET('search_employee')) { - $search_employee = $id; - $disabled = 1; - } + print ''; +} +// Approver +if (!empty($arrayfields['cp.fk_validator']['checked'])) { + if ($user->hasRight('holiday', 'readall')) { print ''; - } - - // Approver - if (!empty($arrayfields['cp.fk_validator']['checked'])) { - if ($user->hasRight('holiday', 'readall')) { - print ''; - } else { - print ''; - } - } - - // Type - if (!empty($arrayfields['cp.fk_type']['checked'])) { - print ''; - } - - // Duration - if (!empty($arrayfields['duration']['checked'])) { + } else { print ''; } +} - // Start date - if (!empty($arrayfields['cp.date_debut']['checked'])) { - print ''; +// Type +if (!empty($arrayfields['cp.fk_type']['checked'])) { + print ''; +} - // End date - if (!empty($arrayfields['cp.date_fin']['checked'])) { - print ''; - } +// Duration +if (!empty($arrayfields['duration']['checked'])) { + print ''; +} - // Date validation - if (!empty($arrayfields['cp.date_valid']['checked'])) { - print ''; - } +// Start date +if (!empty($arrayfields['cp.date_debut']['checked'])) { + print ''; +} - // Date appoval - if (!empty($arrayfields['cp.date_approval']['checked'])) { - print ''; - } +// End date +if (!empty($arrayfields['cp.date_fin']['checked'])) { + print ''; +} - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; - // Fields from hook - $parameters = array('arrayfields'=>$arrayfields); - $reshook = $hookmanager->executeHooks('printFieldListOption', $parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; +// Date validation +if (!empty($arrayfields['cp.date_valid']['checked'])) { + print ''; +} - // Create date - if (!empty($arrayfields['cp.date_create']['checked'])) { - print ''; - } +// Date appoval +if (!empty($arrayfields['cp.date_approval']['checked'])) { + print ''; +} - // Create date - if (!empty($arrayfields['cp.tms']['checked'])) { - print ''; - } +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; - // Status - if (!empty($arrayfields['cp.statut']['checked'])) { - print ''; - } +// Fields from hook +$parameters = array('arrayfields'=>$arrayfields); +$reshook = $hookmanager->executeHooks('printFieldListOption', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; - // Action column - if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - } +// Create date +if (!empty($arrayfields['cp.date_create']['checked'])) { + print ''; +} - print "\n"; +// Create date +if (!empty($arrayfields['cp.tms']['checked'])) { + print ''; +} - print ''; - if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch center '); - } - if (!empty($arrayfields['cp.ref']['checked'])) { - print_liste_field_titre($arrayfields['cp.ref']['label'], $_SERVER["PHP_SELF"], "cp.ref", "", $param, '', $sortfield, $sortorder); - } - if (!empty($arrayfields['cp.fk_user']['checked'])) { - print_liste_field_titre($arrayfields['cp.fk_user']['label'], $_SERVER["PHP_SELF"], "cp.fk_user", "", $param, '', $sortfield, $sortorder); - } - if (!empty($arrayfields['cp.fk_validator']['checked'])) { - print_liste_field_titre($arrayfields['cp.fk_validator']['label'], $_SERVER["PHP_SELF"], "cp.fk_validator", "", $param, '', $sortfield, $sortorder); - } - if (!empty($arrayfields['cp.fk_type']['checked'])) { - print_liste_field_titre($arrayfields['cp.fk_type']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder); - } - if (!empty($arrayfields['duration']['checked'])) { - print_liste_field_titre($arrayfields['duration']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right maxwidth100'); - } - if (!empty($arrayfields['cp.date_debut']['checked'])) { - print_liste_field_titre($arrayfields['cp.date_debut']['label'], $_SERVER["PHP_SELF"], "cp.date_debut", "", $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['cp.date_fin']['checked'])) { - print_liste_field_titre($arrayfields['cp.date_fin']['label'], $_SERVER["PHP_SELF"], "cp.date_fin", "", $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['cp.date_valid']['checked'])) { - print_liste_field_titre($arrayfields['cp.date_valid']['label'], $_SERVER["PHP_SELF"], "cp.date_valid", "", $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['cp.date_approval']['checked'])) { - print_liste_field_titre($arrayfields['cp.date_approval']['label'], $_SERVER["PHP_SELF"], "cp.date_approval", "", $param, '', $sortfield, $sortorder, 'center '); - } - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; - // Hook fields - $parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder); - $reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (!empty($arrayfields['cp.date_create']['checked'])) { - print_liste_field_titre($arrayfields['cp.date_create']['label'], $_SERVER["PHP_SELF"], "cp.date_create", "", $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['cp.tms']['checked'])) { - print_liste_field_titre($arrayfields['cp.tms']['label'], $_SERVER["PHP_SELF"], "cp.tms", "", $param, '', $sortfield, $sortorder, 'center '); - } - if (!empty($arrayfields['cp.statut']['checked'])) { - print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "cp.statut", "", $param, '', $sortfield, $sortorder, 'right '); - } - if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', '', $sortfield, $sortorder, 'maxwidthsearch center '); - } - print "\n"; +// Status +if (!empty($arrayfields['cp.statut']['checked'])) { + print ''; +} - $listhalfday = array('morning'=>$langs->trans("Morning"), "afternoon"=>$langs->trans("Afternoon")); +// Action column +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; +} + +print ''."\n"; + +$totalarray = array(); +$totalarray['nbfield'] = 0; + +// Fields title label +// -------------------------------------------------------------------- +print ''; +if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.ref']['checked'])) { + print_liste_field_titre($arrayfields['cp.ref']['label'], $_SERVER["PHP_SELF"], "cp.ref", "", $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.fk_user']['checked'])) { + print_liste_field_titre($arrayfields['cp.fk_user']['label'], $_SERVER["PHP_SELF"], "cp.fk_user", "", $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.fk_validator']['checked'])) { + print_liste_field_titre($arrayfields['cp.fk_validator']['label'], $_SERVER["PHP_SELF"], "cp.fk_validator", "", $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.fk_type']['checked'])) { + print_liste_field_titre($arrayfields['cp.fk_type']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['duration']['checked'])) { + print_liste_field_titre($arrayfields['duration']['label'], $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder, 'right maxwidth100'); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.date_debut']['checked'])) { + print_liste_field_titre($arrayfields['cp.date_debut']['label'], $_SERVER["PHP_SELF"], "cp.date_debut", "", $param, '', $sortfield, $sortorder, 'center '); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.date_fin']['checked'])) { + print_liste_field_titre($arrayfields['cp.date_fin']['label'], $_SERVER["PHP_SELF"], "cp.date_fin", "", $param, '', $sortfield, $sortorder, 'center '); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.date_valid']['checked'])) { + print_liste_field_titre($arrayfields['cp.date_valid']['label'], $_SERVER["PHP_SELF"], "cp.date_valid", "", $param, '', $sortfield, $sortorder, 'center '); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.date_approval']['checked'])) { + print_liste_field_titre($arrayfields['cp.date_approval']['label'], $_SERVER["PHP_SELF"], "cp.date_approval", "", $param, '', $sortfield, $sortorder, 'center '); + $totalarray['nbfield']++; +} +// Extra fields +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; +// Hook fields +$parameters = array('arrayfields'=>$arrayfields, 'param'=>$param, 'sortfield'=>$sortfield, 'sortorder'=>$sortorder, 'totalarray'=>&$totalarray); +$reshook = $hookmanager->executeHooks('printFieldListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +if (!empty($arrayfields['cp.date_create']['checked'])) { + print_liste_field_titre($arrayfields['cp.date_create']['label'], $_SERVER["PHP_SELF"], "cp.date_create", "", $param, '', $sortfield, $sortorder, 'center '); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.tms']['checked'])) { + print_liste_field_titre($arrayfields['cp.tms']['label'], $_SERVER["PHP_SELF"], "cp.tms", "", $param, '', $sortfield, $sortorder, 'center '); + $totalarray['nbfield']++; +} +if (!empty($arrayfields['cp.statut']['checked'])) { + print_liste_field_titre("Status", $_SERVER["PHP_SELF"], "cp.statut", "", $param, '', $sortfield, $sortorder, 'right '); + $totalarray['nbfield']++; +} +// Action column +if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + $totalarray['nbfield']++; +} +print ''."\n"; + +$listhalfday = array('morning'=>$langs->trans("Morning"), "afternoon"=>$langs->trans("Afternoon")); - // If we ask a dedicated card and not allow to see it, we force on user. - if ($id && empty($user->rights->holiday->readall) && !in_array($id, $childids)) { - $langs->load("errors"); - print ''; - $result = 0; - } elseif ($num > 0 && !empty($mysoc->country_id)) { - // Lines - $userstatic = new User($db); - $approbatorstatic = new User($db); +// Loop on record +// -------------------------------------------------------------------- - $typeleaves = $object->getTypes(1, -1); +// If we ask a dedicated card and not allow to see it, we force on user. +if ($id && empty($user->rights->holiday->readall) && !in_array($id, $childids)) { + $langs->load("errors"); + print ''; + $result = 0; +} elseif ($num > 0 && !empty($mysoc->country_id)) { + // Lines + $userstatic = new User($db); + $approbatorstatic = new User($db); - $i = 0; - $totalarray = array(); - $totalarray['nbfield'] = 0; - $totalduration = 0; - $imaxinloop = ($limit ? min($num, $limit) : $num); - while ($i < $imaxinloop) { - $obj = $db->fetch_object($resql); + $typeleaves = $object->getTypes(1, -1); - // Leave request - $holidaystatic->id = $obj->rowid; - $holidaystatic->ref = ($obj->ref ? $obj->ref : $obj->rowid); - $holidaystatic->statut = $obj->status; - $holidaystatic->date_debut = $obj->date_debut; - $holidaystatic->date_fin = $obj->date_fin; + $i = 0; + $savnbfield = $totalarray['nbfield']; + $totalarray = array(); + $totalarray['nbfield'] = 0; + $totalduration = 0; + $imaxinloop = ($limit ? min($num, $limit) : $num); + while ($i < $imaxinloop) { + $obj = $db->fetch_object($resql); + if (empty($obj)) { + break; // Should not happen + } - // User - $userstatic->id = $obj->fk_user; - $userstatic->lastname = $obj->user_lastname; - $userstatic->firstname = $obj->user_firstname; - $userstatic->admin = $obj->user_admin; - $userstatic->email = $obj->user_email; - $userstatic->login = $obj->user_login; - $userstatic->statut = $obj->user_status; - $userstatic->photo = $obj->user_photo; + // Leave request + $holidaystatic->id = $obj->rowid; + $holidaystatic->ref = ($obj->ref ? $obj->ref : $obj->rowid); + $holidaystatic->statut = $obj->status; + $holidaystatic->date_debut = $obj->date_debut; + $holidaystatic->date_fin = $obj->date_fin; - // Validator - $approbatorstatic->id = $obj->fk_validator; - $approbatorstatic->lastname = $obj->validator_lastname; - $approbatorstatic->firstname = $obj->validator_firstname; - $approbatorstatic->admin = $obj->validator_admin; - $approbatorstatic->email = $obj->validator_email; - $approbatorstatic->login = $obj->validator_login; - $approbatorstatic->statut = $obj->validator_status; - $approbatorstatic->photo = $obj->validator_photo; + // User + $userstatic->id = $obj->fk_user; + $userstatic->lastname = $obj->user_lastname; + $userstatic->firstname = $obj->user_firstname; + $userstatic->admin = $obj->user_admin; + $userstatic->email = $obj->user_email; + $userstatic->login = $obj->user_login; + $userstatic->statut = $obj->user_status; + $userstatic->photo = $obj->user_photo; - $date = $obj->date_create; - $date_modif = $obj->date_update; + // Validator + $approbatorstatic->id = $obj->fk_validator; + $approbatorstatic->lastname = $obj->validator_lastname; + $approbatorstatic->firstname = $obj->validator_firstname; + $approbatorstatic->admin = $obj->validator_admin; + $approbatorstatic->email = $obj->validator_email; + $approbatorstatic->login = $obj->validator_login; + $approbatorstatic->statut = $obj->validator_status; + $approbatorstatic->photo = $obj->validator_photo; - $starthalfday = ($obj->halfday == -1 || $obj->halfday == 2) ? 'afternoon' : 'morning'; - $endhalfday = ($obj->halfday == 1 || $obj->halfday == 2) ? 'morning' : 'afternoon'; + $date = $obj->date_create; + $date_modif = $obj->date_update; - $nbopenedday = num_open_day($db->jdate($obj->date_debut, 1), $db->jdate($obj->date_fin, 1), 0, 1, $obj->halfday); // user jdate(..., 1) because num_open_day need UTC dates - $totalduration += $nbopenedday; + $starthalfday = ($obj->halfday == -1 || $obj->halfday == 2) ? 'afternoon' : 'morning'; + $endhalfday = ($obj->halfday == 1 || $obj->halfday == 2) ? 'morning' : 'afternoon'; - if ($mode == 'kanban') { - if ($i == 0) { - print ''; + } + } else { + // Show here line of result + $j = 0; + print ''; + // Action column + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; - } - } else { - print ''; - // Action column - if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - } - if (!empty($arrayfields['cp.ref']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - if (!empty($arrayfields['cp.fk_user']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - if (!empty($arrayfields['cp.fk_validator']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - if (!empty($arrayfields['cp.fk_type']['checked'])) { - if (empty($typeleaves[$obj->fk_type])) { - $labeltypeleavetoshow = $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type); - } else { - $labeltypeleavetoshow = ($langs->trans($typeleaves[$obj->fk_type]['code']) != $typeleaves[$obj->fk_type]['code'] ? $langs->trans($typeleaves[$obj->fk_type]['code']) : $typeleaves[$obj->fk_type]['label']); - } - - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - if (!empty($arrayfields['duration']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - if (!empty($arrayfields['cp.date_debut']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - if (!empty($arrayfields['cp.date_fin']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - // Date validation - if (!empty($arrayfields['cp.date_valid']['checked'])) { // date_valid is both date_valid but also date_approval - print ''; - if (!$i) $totalarray['nbfield']++; - } - // Date approval - if (!empty($arrayfields['cp.date_approval']['checked'])) { - print ''; - if (!$i) $totalarray['nbfield']++; - } - - // Extra fields - include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; - // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); - $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - - // Date creation - if (!empty($arrayfields['cp.date_create']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - if (!empty($arrayfields['cp.tms']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - if (!empty($arrayfields['cp.statut']['checked'])) { - print ''; - if (!$i) { - $totalarray['nbfield']++; - } - } - - // Action column - if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; + print ''; } + print ''; if (!$i) { $totalarray['nbfield']++; } - - print ''."\n"; } - $i++; - } - - // Add a line for total if there is a total to show - if (!empty($arrayfields['duration']['checked'])) { - print ''; - if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; - } - foreach ($arrayfields as $key => $val) { - if (!empty($val['checked'])) { - if ($key == 'duration') { - print ''; - } else { - print ''; - } + if (!empty($arrayfields['cp.ref']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; } } - // status - if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print ''; + if (!empty($arrayfields['cp.fk_user']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } } - print ''; + if (!empty($arrayfields['cp.fk_validator']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + if (!empty($arrayfields['cp.fk_type']['checked'])) { + if (empty($typeleaves[$obj->fk_type])) { + $labeltypeleavetoshow = $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type); + } else { + $labeltypeleavetoshow = ($langs->trans($typeleaves[$obj->fk_type]['code']) != $typeleaves[$obj->fk_type]['code'] ? $langs->trans($typeleaves[$obj->fk_type]['code']) : $typeleaves[$obj->fk_type]['label']); + } + + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + if (!empty($arrayfields['duration']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + if (!empty($arrayfields['cp.date_debut']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + if (!empty($arrayfields['cp.date_fin']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + // Date validation + if (!empty($arrayfields['cp.date_valid']['checked'])) { // date_valid is both date_valid but also date_approval + print ''; + if (!$i) $totalarray['nbfield']++; + } + // Date approval + if (!empty($arrayfields['cp.date_approval']['checked'])) { + print ''; + if (!$i) $totalarray['nbfield']++; + } + + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters = array('arrayfields'=>$arrayfields, 'object'=>$object, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); + $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + + // Date creation + if (!empty($arrayfields['cp.date_create']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + if (!empty($arrayfields['cp.tms']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + if (!empty($arrayfields['cp.statut']['checked'])) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + // Action column + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + if (!$i) { + $totalarray['nbfield']++; + } + } + + print ''."\n"; } + $i++; } - // Si il n'y a pas d'enregistrement suite à une recherche - if ($num == 0) { - $colspan = 1; + // Add a line for total if there is a total to show + if ($mode != 'kanban' && !empty($arrayfields['duration']['checked'])) { + print ''; + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } foreach ($arrayfields as $key => $val) { if (!empty($val['checked'])) { - $colspan++; + if ($key == 'duration') { + print ''; + } else { + print ''; + } } } - print ''; + // status + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } + print ''; } - - print '
'; - $searchpicto = $form->showFilterButtons('left'); - print $searchpicto; - print ''; - print ''; - print ''; + print $form->select_dolusers($search_employee, "search_employee", 1, "", $disabled, $include, '', 0, 0, 0, $morefilter, 0, '', 'maxwidth125'); + print ''; - print $form->select_dolusers($search_employee, "search_employee", 1, "", $disabled, $include, '', 0, 0, 0, $morefilter, 0, '', 'maxwidth125'); - print ''; - $validator = new UserGroup($db); - $excludefilter = $user->admin ? '' : 'u.rowid <> '.$user->id; - $valideurobjects = $validator->listUsersForGroup($excludefilter, 1); - $valideurarray = array(); - foreach ($valideurobjects as $val) { - $valideurarray[$val] = $val; - } - print $form->select_dolusers($search_valideur, "search_valideur", 1, "", 0, $valideurarray, '', 0, 0, 0, $morefilter, 0, '', 'maxwidth125'); - print ' '; - if (empty($mysoc->country_id)) { - setEventMessages(null, array($langs->trans("ErrorSetACountryFirst"), $langs->trans("CompanyFoundation")), 'errors'); - } else { - $typeleaves = $holidaystatic->getTypes(1, -1); - $arraytypeleaves = array(); - foreach ($typeleaves as $key => $val) { - $labeltoshow = ($langs->trans($val['code']) != $val['code'] ? $langs->trans($val['code']) : $val['label']); - //$labeltoshow .= ($val['delay'] > 0 ? ' ('.$langs->trans("NoticePeriod").': '.$val['delay'].' '.$langs->trans("days").')':''); - $arraytypeleaves[$val['rowid']] = $labeltoshow; - } - print $form->selectarray('search_type', $arraytypeleaves, $search_type, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100', 1); + $validator = new UserGroup($db); + $excludefilter = $user->admin ? '' : 'u.rowid <> '.$user->id; + $valideurobjects = $validator->listUsersForGroup($excludefilter, 1); + $valideurarray = array(); + foreach ($valideurobjects as $val) { + $valideurarray[$val] = $val; } + print $form->select_dolusers($search_valideur, "search_valideur", 1, "", 0, $valideurarray, '', 0, 0, 0, $morefilter, 0, '', 'maxwidth125'); print ' '; - print ''; - print $formother->selectyear($search_year_start, 'search_year_start', 1, $min_year, $max_year); - print ''; + if (empty($mysoc->country_id)) { + setEventMessages(null, array($langs->trans("ErrorSetACountryFirst"), $langs->trans("CompanyFoundation")), 'errors'); + } else { + $typeleaves = $holidaystatic->getTypes(1, -1); + $arraytypeleaves = array(); + foreach ($typeleaves as $key => $val) { + $labeltoshow = ($langs->trans($val['code']) != $val['code'] ? $langs->trans($val['code']) : $val['label']); + //$labeltoshow .= ($val['delay'] > 0 ? ' ('.$langs->trans("NoticePeriod").': '.$val['delay'].' '.$langs->trans("days").')':''); + $arraytypeleaves[$val['rowid']] = $labeltoshow; + } + print $form->selectarray('search_type', $arraytypeleaves, $search_type, 1, 0, 0, '', 0, 0, 0, '', 'maxwidth100', 1); } + print ''; - print ''; - print $formother->selectyear($search_year_end, 'search_year_end', 1, $min_year, $max_year); - print ' '; - print ''; + print ''; + print $formother->selectyear($search_year_start, 'search_year_start', 1, $min_year, $max_year); + print ''; - print ''; + print ''; + print $formother->selectyear($search_year_end, 'search_year_end', 1, $min_year, $max_year); + print ''; + print ''; - print ''; - print $formother->selectyear($search_year_create, 'search_year_create', 1, $min_year, 0); - print ''; + print ''; - print ''; - print $formother->selectyear($search_year_update, 'search_year_update', 1, $min_year, 0); - print ''; - $object->selectStatutCP($search_status, 'search_status', 'minwidth125'); - print ''; - $searchpicto = $form->showFilterButtons(); - print $searchpicto; - print ''; + print ''; + print $formother->selectyear($search_year_create, 'search_year_create', 1, $min_year, 0); + print '
'; + print ''; + print $formother->selectyear($search_year_update, 'search_year_update', 1, $min_year, 0); + print '
'; + print $object->selectStatutCP($search_status, 'search_status', 'search_status width100 onrightofpage'); + print ''; + $searchpicto = $form->showFilterButtons(); + print $searchpicto; + print '
'.$langs->trans("NotEnoughPermissions").'
'.$langs->trans("NotEnoughPermissions").'
'; - print '
'; + $nbopenedday = num_open_day($db->jdate($obj->date_debut, 1), $db->jdate($obj->date_fin, 1), 0, 1, $obj->halfday); // user jdate(..., 1) because num_open_day need UTC dates + $totalduration += $nbopenedday; + + if ($mode == 'kanban') { + if ($i == 0) { + print '
'; + print '
'; + } + + $holidaystatic->fk_type = empty($typeleaves[$obj->fk_type]['rowid']) ? 0 : $typeleaves[$obj->fk_type]['rowid']; + + // Output Kanban + if ($massactionbutton || $massaction) { + $selected = 0; + if (in_array($object->id, $arrayofselected)) { + $selected = 1; + } + if (empty($typeleaves[$obj->fk_type])) { + $labeltypeleavetoshow = $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type); + } else { + $labeltypeleavetoshow = ($langs->trans($typeleaves[$obj->fk_type]['code']) != $typeleaves[$obj->fk_type]['code'] ? $langs->trans($typeleaves[$obj->fk_type]['code']) : $typeleaves[$obj->fk_type]['label']); } - $holidaystatic->fk_type = $typeleaves[$obj->fk_type]['rowid']; - - // Output Kanban - if ($massactionbutton || $massaction) { + $arraydata = array('user'=>$userstatic, 'labeltype'=>$labeltypeleavetoshow); + } + print $holidaystatic->getKanbanView('', $arraydata); + if ($i == ($imaxinloop - 1)) { + print '
'; + print '
'; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined $selected = 0; - if (in_array($object->id, $arrayofselected)) { + if (in_array($obj->rowid, $arrayofselected)) { $selected = 1; } - if (empty($typeleaves[$obj->fk_type])) { - $labeltypeleavetoshow = $langs->trans("TypeWasDisabledOrRemoved", $obj->fk_type); - } else { - $labeltypeleavetoshow = ($langs->trans($typeleaves[$obj->fk_type]['code']) != $typeleaves[$obj->fk_type]['code'] ? $langs->trans($typeleaves[$obj->fk_type]['code']) : $typeleaves[$obj->fk_type]['label']); - } - - $arraydata = array('user'=>$userstatic, 'labeltype'=>$labeltypeleavetoshow); - print $holidaystatic->getKanbanView('', $arraydata); - } - if ($i == ($imaxinloop - 1)) { - print ''; - print '
'; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($obj->rowid, $arrayofselected)) { - $selected = 1; - } - print ''; - } - print ''; - print $holidaystatic->getNomUrl(1, 1); - print ''.$userstatic->getNomUrl(-1, 'leave').''.$approbatorstatic->getNomUrl(-1).''; - print $labeltypeleavetoshow; - print ''; - $nbopenedday = num_open_day($db->jdate($obj->date_debut, 1), $db->jdate($obj->date_fin, 1), 0, 1, $obj->halfday); // user jdate(..., 1) because num_open_day need UTC dates - $totalduration += $nbopenedday; - print $nbopenedday; - //print ' '.$langs->trans('DurationDays'); - print ''; - print dol_print_date($db->jdate($obj->date_debut), 'day'); - print ' ('.$langs->trans($listhalfday[$starthalfday]).')'; - print ''; - print dol_print_date($db->jdate($obj->date_fin), 'day'); - print ' ('.$langs->trans($listhalfday[$endhalfday]).')'; - print ''; - print dol_print_date($db->jdate($obj->date_valid), 'day'); - print ''; - print dol_print_date($db->jdate($obj->date_approval), 'day'); - print ''.dol_print_date($date, 'dayhour').''.dol_print_date($date_modif, 'dayhour').''.$holidaystatic->getLibStatut(5).''; - if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined - $selected = 0; - if (in_array($obj->rowid, $arrayofselected)) { - $selected = 1; - } - print ''; - } - print '
'.$totalduration.' '.$langs->trans('DurationDays').''; + print $holidaystatic->getNomUrl(1, 1); + print ''.$userstatic->getNomUrl(-1, 'leave').'
'.$approbatorstatic->getNomUrl(-1).''; + print $labeltypeleavetoshow; + print ''; + $nbopenedday = num_open_day($db->jdate($obj->date_debut, 1), $db->jdate($obj->date_fin, 1), 0, 1, $obj->halfday); // user jdate(..., 1) because num_open_day need UTC dates + $totalduration += $nbopenedday; + print $nbopenedday; + //print ' '.$langs->trans('DurationDays'); + print ''; + print dol_print_date($db->jdate($obj->date_debut), 'day'); + print ' ('.$langs->trans($listhalfday[$starthalfday]).')'; + print ''; + print dol_print_date($db->jdate($obj->date_fin), 'day'); + print ' ('.$langs->trans($listhalfday[$endhalfday]).')'; + print ''; + print dol_print_date($db->jdate($obj->date_valid), 'day'); + print ''; + print dol_print_date($db->jdate($obj->date_approval), 'day'); + print ''.dol_print_date($date, 'dayhour').''.dol_print_date($date_modif, 'dayhour').''.$holidaystatic->getLibStatut(5).''; + if ($massactionbutton || $massaction) { // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined + $selected = 0; + if (in_array($obj->rowid, $arrayofselected)) { + $selected = 1; + } + print ''; + } + print '
'.$totalduration.' '.$langs->trans('DurationDays').'
'.$langs->trans("NoRecordFound").'
'; - print '
'; - - print '
'; -} else { - dol_print_error($db); } +// If no record found +if ($num == 0) { + $colspan = 1; + foreach ($arrayfields as $key => $val) { + if (!empty($val['checked'])) { + $colspan++; + } + } + print '
'.$langs->trans("NoRecordFound").'
'."\n"; +print '
'."\n"; + +print ''."\n"; + // End of page llxFooter(); $db->close(); diff --git a/htdocs/install/inc.php b/htdocs/install/inc.php index 9dc12b18277..636f365683f 100644 --- a/htdocs/install/inc.php +++ b/htdocs/install/inc.php @@ -6,6 +6,7 @@ * Copyright (C) 2012 Marcos García * Copyright (C) 2016 Raphaël Doursenaud * Copyright (C) 2021 Charlene Benke + * Copyright (C) 2023 Alexandre Janniaux * * 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 @@ -70,6 +71,92 @@ $conffiletoshow = "htdocs/conf/conf.php"; //$conffile = "/etc/dolibarr/conf.php"; //$conffiletoshow = "/etc/dolibarr/conf.php"; +$short_options = "c:h"; +$long_options = array( + "config:", + "help", +); + +/** + * Print the usage when executing scripts from install/. + * + * Print the help text exposing the available options when executing + * update or install script (ie. from htdocs/install/) from CLI with + * the `php` executable. This function does not `exit` the program and + * the caller should then call `exit` themselves since they should + * determine whether it was an error or not. + * + * @param string $program the script that was originally run + * @param string $header the message to signal to the user + * @return void + */ +function usage($program, $header) +{ + echo $header."\n"; + echo " php ".$program." [options] previous_version new_version [script options]\n"; + echo "\n"; + echo "Script options when using upgrade.php:\n"; + echo "\n"; + echo " dirmodule:\n"; + echo " Specify dirmodule to provide a path for an external module\n"; + echo " so the migration is done using a script from a module.\n"; + echo "\n"; + echo " ignoredbversion:\n"; + echo " Allow to run migration even if database version does\n"; + echo " not match start version of migration.\n"; + echo "\n"; + echo "Script options when using upgrade2.php:\n"; + echo "\n"; + echo " MODULE_NAME1_TO_ENABLE,MODULE_NAME2_TO_ENABLE:\n"; + echo " Specify a list of module-name to enable, joined by comma.\n"; + echo "\n"; + echo "Options:\n"; + echo " -c, --config :\n"; + echo " Provide a different conf.php file to use.\n"; + echo "\n"; + echo " -h, --help:\n"; + echo " Display this help message.\n"; +} + +if (php_sapi_name() === "cli") { + $rest_index = 0; + $opts = getopt($short_options, $long_options, $rest_index); + + foreach ($opts as $opt => $arg) switch ($opt) { + case 'c': + case 'config': + $conffile = $arg; + $conffiletoshow = $arg; + break; + case 'h': + case 'help': + usage($argv[0], "Usage:"); + exit(0); + } + + // In the following test, only dash-prefixed arguments will trigger an + // error, given that scripts options can allow a variable number of + // additional non-prefixed argument and we mostly want to check for + // typo right now. + if ($rest_index < $argc && $argv[$rest_index][0] == "-") { + usage($argv[0], "Unknown option ".$argv[$rest_index]. ", usage:"); + exit(1); + } + + // Currently, scripts using inc.php will require addtional arguments, + // see help above for more details. + if ($rest_index > $argc - 2) { + usage($argv[0], "Missing mandatory arguments, usage:"); + exit(1); + } + + // Tricky argument list hack, should be removed someday. + // Reset argv to remove the argument that were parsed. This is needed + // currently because some install code, like in upgrade.php, are using + // $argv[] directly with fixed index to fetch some arguments. + $argv = array_merge(array($argv[0]), array_slice($argv, $rest_index)); + $argc = count($argv); +} // Load conf file if it is already defined if (!defined('DONOTLOADCONF') && file_exists($conffile) && filesize($conffile) > 8) { // Test on filesize is to ensure that conf file is more that an empty template with just 0 a UPDATE llx_actioncomm set fk_user_action = fk_user_author where fk_user_author > 0 and (fk_user_action is null or fk_user_action = 0); -UPDATE llx_projet_task_time set task_datehour = task_date where task_datehour IS NULL and task_date IS NOT NULL; +UPDATE llx_element_time set element_datehour = element_date where element_datehour IS NULL and element_date IS NOT NULL; UPDATE llx_projet set fk_opp_status = NULL where fk_opp_status = -1; UPDATE llx_projet set fk_opp_status = (SELECT rowid FROM llx_c_lead_status WHERE code='PROSP') where fk_opp_status IS NULL and opp_amount > 0; @@ -389,8 +389,8 @@ update llx_expedition set date_valid = date_creation where fk_statut = 1 and dat update llx_expedition set date_valid = NOW() where fk_statut = 1 and date_valid IS NULL; -- Detect bad consistency between duraction_effective of a task and sum of time of tasks --- select pt.rowid, pt.duration_effective, SUM(ptt.task_duration) as y from llx_projet_task as pt, llx_projet_task_time as ptt where ptt.fk_task = pt.rowid group by pt.rowid, pt.duration_effective having pt.duration_effective <> y; -update llx_projet_task as pt set pt.duration_effective = (select SUM(ptt.task_duration) as y from llx_projet_task_time as ptt where ptt.fk_task = pt.rowid) where pt.duration_effective <> (select SUM(ptt.task_duration) as y from llx_projet_task_time as ptt where ptt.fk_task = pt.rowid); +-- select pt.rowid, pt.duration_effective, SUM(ptt.element_duration) as y from llx_projet_task as pt, llx_element_time as ptt where ptt.fk_element = pt.rowid and ptt.elementtype = 'task' group by pt.rowid, pt.duration_effective having pt.duration_effective <> y; +update llx_projet_task as pt set pt.duration_effective = (select SUM(ptt.element_duration) as y from llx_element_time as ptt where ptt.fk_element = pt.rowid and ptt.elementtype = 'task') where pt.duration_effective <> (select SUM(ptt.element_duration) as y from llx_element_time as ptt where ptt.fk_element = pt.rowid and ptt.elementtype = 'task'); -- Remove duplicate of shipment mode (keep the one with tracking defined) @@ -422,7 +422,7 @@ UPDATE llx_facture_fourn_det SET fk_code_ventilation = 0 WHERE fk_code_ventilati UPDATE llx_expensereport_det SET fk_code_ventilation = 0 WHERE fk_code_ventilation > 0 AND fk_code_ventilation NOT IN (select rowid FROM llx_accounting_account); --- VMYSQL4.1 update llx_projet_task_time set task_datehour = task_date where task_datehour < task_date or task_datehour > DATE_ADD(task_date, interval 1 day); +-- VMYSQL4.1 update llx_element_time set element_datehour = element_date where element_datehour < element_date or element_datehour > DATE_ADD(element_date, interval 1 day); -- Clean product prices @@ -487,7 +487,7 @@ UPDATE llx_chargesociales SET date_creation = tms WHERE date_creation IS NULL; -- Backport a change of value into the hourly rate. --- update llx_projet_task_time as ptt set ptt.thm = (SELECT thm from llx_user as u where ptt.fk_user = u.rowid) where (ptt.thm is null) +-- update llx_element_time as ptt set ptt.thm = (SELECT thm from llx_user as u where ptt.fk_user = u.rowid) where (ptt.thm is null) -- select * from llx_facturedet as fd, llx_product as p where fd.fk_product = p.rowid AND fd.product_type != p.fk_product_type; diff --git a/htdocs/install/mysql/tables/llx_c_country.sql b/htdocs/install/mysql/tables/llx_c_country.sql index 7419b68c26d..f17d93ecdbd 100644 --- a/htdocs/install/mysql/tables/llx_c_country.sql +++ b/htdocs/install/mysql/tables/llx_c_country.sql @@ -21,11 +21,14 @@ create table llx_c_country ( - rowid integer PRIMARY KEY, - code varchar(2) NOT NULL, - code_iso varchar(3) , - label varchar(128) NOT NULL, - eec tinyint DEFAULT 0 NOT NULL, - active tinyint DEFAULT 1 NOT NULL, - favorite tinyint DEFAULT 0 NOT NULL + rowid integer PRIMARY KEY, + code varchar(2) NOT NULL, -- the iso 2 alpha code + code_iso varchar(3), -- the iso 3 alpha code + numeric_code varchar(3), -- the iso numeric number + label varchar(128) NOT NULL, + eec tinyint DEFAULT 0 NOT NULL, + active tinyint DEFAULT 1 NOT NULL, + favorite tinyint DEFAULT 0 NOT NULL )ENGINE=innodb; + + diff --git a/htdocs/install/mysql/tables/llx_projet_task_time.key.sql b/htdocs/install/mysql/tables/llx_element_time.key.sql similarity index 73% rename from htdocs/install/mysql/tables/llx_projet_task_time.key.sql rename to htdocs/install/mysql/tables/llx_element_time.key.sql index 5acb17bb712..5de06450e75 100644 --- a/htdocs/install/mysql/tables/llx_projet_task_time.key.sql +++ b/htdocs/install/mysql/tables/llx_element_time.key.sql @@ -1,5 +1,6 @@ -- =========================================================================== -- Copyright (C) 2014 Laurent Destailleur +-- Copyright (C) 2023 Gauthier VERDOL -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -16,7 +17,7 @@ -- -- =========================================================================== -ALTER TABLE llx_projet_task_time ADD INDEX idx_projet_task_time_task (fk_task); -ALTER TABLE llx_projet_task_time ADD INDEX idx_projet_task_time_date (task_date); -ALTER TABLE llx_projet_task_time ADD INDEX idx_projet_task_time_datehour (task_datehour); +ALTER TABLE llx_element_time ADD INDEX idx_element_time_task (fk_element); +ALTER TABLE llx_element_time ADD INDEX idx_element_time_date (element_date); +ALTER TABLE llx_element_time ADD INDEX idx_element_time_datehour (element_datehour); diff --git a/htdocs/install/mysql/tables/llx_element_time.sql b/htdocs/install/mysql/tables/llx_element_time.sql new file mode 100644 index 00000000000..cf346a48ec0 --- /dev/null +++ b/htdocs/install/mysql/tables/llx_element_time.sql @@ -0,0 +1,38 @@ +-- Copyright (C) 2023 Gauthier VERDOL +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- 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_element_time( + -- BEGIN MODULEBUILDER FIELDS + rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL, + fk_element integer NOT NULL, + elementtype varchar(32) NOT NULL, + element_date date, + element_datehour datetime, + element_date_withhour integer, + element_duration double, + fk_product integer, + fk_user integer, + thm double(24,8), + invoice_id integer DEFAULT NULL, + invoice_line_id integer DEFAULT NULL, + intervention_id integer DEFAULT NULL, + intervention_line_id integer DEFAULT NULL, + import_key varchar(14), + datec datetime, + tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + note text + -- END MODULEBUILDER FIELDS +) ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_projet_task_time.sql b/htdocs/install/mysql/tables/llx_projet_task_time.sql deleted file mode 100644 index e91e50b5721..00000000000 --- a/htdocs/install/mysql/tables/llx_projet_task_time.sql +++ /dev/null @@ -1,38 +0,0 @@ --- =========================================================================== --- Copyright (C) 2005 Rodolphe Quiedeville --- --- 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_projet_task_time -( - rowid integer AUTO_INCREMENT PRIMARY KEY, - fk_task integer NOT NULL, - task_date date, -- only the day - task_datehour datetime, -- day + hour - task_date_withhour integer DEFAULT 0, -- 0 by default, 1 if date was entered with start hour - task_duration double, - fk_product integer NULL, - fk_user integer, - thm double(24,8), - invoice_id integer DEFAULT NULL, -- If we need to invoice each line of timespent, we can save invoice id here - invoice_line_id integer DEFAULT NULL, -- If we need to invoice each line of timespent, we can save invoice line id here - intervention_id integer DEFAULT NULL, -- If we need to have an intervention line for each line of timespent, we can save intervention id here - intervention_line_id integer DEFAULT NULL, -- If we need to have an intervention line of timespent line, we can save intervention line id here - import_key varchar(14), -- Import key - datec datetime, -- date creation time - tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- last modification date - note text -- A comment -)ENGINE=innodb; diff --git a/htdocs/install/pgsql/functions/functions.sql b/htdocs/install/pgsql/functions/functions.sql index 35bc4e05c11..918d17385eb 100644 --- a/htdocs/install/pgsql/functions/functions.sql +++ b/htdocs/install/pgsql/functions/functions.sql @@ -1,6 +1,7 @@ -- ============================================================================ -- Copyright (C) 2004 Benoit Mortier -- Copyright (C) 2010 Laurent Destailleur +-- Copyright (C) 2023 Gauthier VERDOL -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -150,7 +151,7 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet FOR EACH ROW CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet_task FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet_task_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_projet_task_time FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_element_time FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propal FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propal_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_propal_merge_pdf_product FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index c40f4a69e89..70be057b7b8 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2021 Frédéric France + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1030,7 +1031,7 @@ if ($ok && GETPOST('set_empty_time_spent_amount', 'alpha')) { print '
*** Set value of time spent without amount'; $sql = "SELECT COUNT(ptt.rowid) as nb, u.rowid as user_id, u.login, u.thm as user_thm"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."user as u"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as ptt, ".MAIN_DB_PREFIX."user as u"; $sql .= " WHERE ptt.fk_user = u.rowid"; $sql .= " AND ptt.thm IS NULL and u.thm > 0"; $sql .= " GROUP BY u.rowid, u.login, u.thm"; @@ -1048,7 +1049,7 @@ if ($ok && GETPOST('set_empty_time_spent_amount', 'alpha')) { $db->begin(); if (GETPOST('set_empty_time_spent_amount') == 'confirmed') { - $sql2 = "UPDATE ".MAIN_DB_PREFIX."projet_task_time"; + $sql2 = "UPDATE ".MAIN_DB_PREFIX."element_time"; $sql2 .= " SET thm = ".$obj->user_thm." WHERE thm IS NULL AND fk_user = ".((int) $obj->user_id); $resql2 = $db->query($sql2); if (!$resql2) { diff --git a/htdocs/install/upgrade2.php b/htdocs/install/upgrade2.php index 15d2b64dc73..1f53780461e 100644 --- a/htdocs/install/upgrade2.php +++ b/htdocs/install/upgrade2.php @@ -4,6 +4,7 @@ * Copyright (C) 2005-2011 Regis Houssin * Copyright (C) 2010 Juanjo Menent * Copyright (C) 2015-2016 Raphaël Doursenaud + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -339,7 +340,7 @@ if (!GETPOST('action', 'aZ09') || preg_match('/upgrade/i', GETPOST('action', 'aZ $afterversionarray = explode('.', '2.8.9'); $beforeversionarray = explode('.', '2.9.9'); if (versioncompare($versiontoarray, $afterversionarray) >= 0 && versioncompare($versiontoarray, $beforeversionarray) <= 0) { - migrate_project_task_time($db, $langs, $conf); + migrate_element_time($db, $langs, $conf); migrate_customerorder_shipping($db, $langs, $conf); @@ -2901,9 +2902,9 @@ function migrate_relationship_tables($db, $langs, $conf, $table, $fk_source, $so * @param Conf $conf Object conf * @return void */ -function migrate_project_task_time($db, $langs, $conf) +function migrate_element_time($db, $langs, $conf) { - dolibarr_install_syslog("upgrade2::migrate_project_task_time"); + dolibarr_install_syslog("upgrade2::migrate_element_time"); print ''; @@ -2914,8 +2915,8 @@ function migrate_project_task_time($db, $langs, $conf) $db->begin(); - $sql = "SELECT rowid, fk_task, task_duration"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time"; + $sql = "SELECT rowid, fk_element, element_duration"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time"; $resql = $db->query($sql); if ($resql) { $i = 0; @@ -2928,16 +2929,16 @@ function migrate_project_task_time($db, $langs, $conf) while ($i < $num) { $obj = $db->fetch_object($resql); - if ($obj->task_duration > 0) { + if ($obj->element_duration > 0) { // convert to second // only for int time and float time ex: 1,75 for 1h45 - list($hour, $min) = explode('.', $obj->task_duration); + list($hour, $min) = explode('.', $obj->element_duration); $hour = $hour * 60 * 60; $min = ($min / 100) * 60 * 60; $newtime = $hour + $min; - $sql2 = "UPDATE ".MAIN_DB_PREFIX."projet_task_time SET"; - $sql2 .= " task_duration = ".((int) $newtime); + $sql2 = "UPDATE ".MAIN_DB_PREFIX."element_time SET"; + $sql2 .= " element_duration = ".((int) $newtime); $sql2 .= " WHERE rowid = ".((int) $obj->rowid); $resql2 = $db->query($sql2); @@ -2947,16 +2948,16 @@ function migrate_project_task_time($db, $langs, $conf) } print ". "; $oldtime++; - if (!empty($totaltime[$obj->fk_task])) { - $totaltime[$obj->fk_task] += $newtime; + if (!empty($totaltime[$obj->fk_element])) { + $totaltime[$obj->fk_element] += $newtime; } else { - $totaltime[$obj->fk_task] = $newtime; + $totaltime[$obj->fk_element] = $newtime; } } else { - if (!empty($totaltime[$obj->fk_task])) { - $totaltime[$obj->fk_task] += $obj->task_duration; + if (!empty($totaltime[$obj->fk_element])) { + $totaltime[$obj->fk_element] += $obj->element_duration; } else { - $totaltime[$obj->fk_task] = $obj->task_duration; + $totaltime[$obj->fk_element] = $obj->element_duration; } } diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index a5176383d69..2c72878d40e 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -41,6 +41,7 @@ AlreadyInGeneralLedger=Already transferred to accounting journals and ledger NotYetInGeneralLedger=Not yet transferred to accouting journals and ledger GroupIsEmptyCheckSetup=Group is empty, check setup of the personalized accounting group DetailByAccount=Show detail by account +DetailBy=Detail by AccountWithNonZeroValues=Accounts with non-zero values ListOfAccounts=List of accounts CountriesInEEC=Countries in EEC diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index 0d286fb3104..1112d4647bb 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -159,9 +159,10 @@ ConfirmDeleteVariousPayment=Are you sure you want to delete this various payment ExportDataset_tax_1=Social and fiscal taxes and payments CalcModeVATDebt=Mode %sVAT on commitment accounting%s. CalcModeVATEngagement=Mode %sVAT on incomes-expenses%s. -CalcModeDebt=Analysis of known recorded documents even if they are not yet accounted in ledger. -CalcModeEngagement=Analysis of known recorded payments, even if they are not yet accounted in Ledger. +CalcModeDebt=Analysis of known recorded documents +CalcModeEngagement=Analysis of known recorded payments CalcModeBookkeeping=Analysis of data journalized in Bookkeeping Ledger table. +CalcModeNoBookKeeping=Even if they are not yet accounted in Ledger CalcModeLT1= Mode %sRE on customer invoices - suppliers invoices%s CalcModeLT1Debt=Mode %sRE on customer invoices%s CalcModeLT1Rec= Mode %sRE on suppliers invoices%s diff --git a/htdocs/langs/fr_FR/boxes.lang b/htdocs/langs/fr_FR/boxes.lang index 6e237c8692e..bf80ff0a874 100644 --- a/htdocs/langs/fr_FR/boxes.lang +++ b/htdocs/langs/fr_FR/boxes.lang @@ -52,7 +52,7 @@ BoxTitleOldestActionsToDo=Événements %s les plus anciens à faire, non termin BoxTitleLastContracts=Les %s derniers contrats modifiés BoxTitleLastModifiedDonations=Les %s derniers dons modifiés BoxTitleLastModifiedExpenses=Les %s dernières notes de frais modifiées -BoxTitleLatestModifiedBoms=Les %s derières BOMS modifiées +BoxTitleLatestModifiedBoms=Les %s dernières BOMS modifiées BoxTitleLatestModifiedMos=Les %s derniers ordres de fabrication modifiés BoxTitleLastOutstandingBillReached=Clients dont l'en-cours autorisé est dépassé BoxGlobalActivity=Activité globale (factures, propositions, commandes) diff --git a/htdocs/master.inc.php b/htdocs/master.inc.php index 8cf649148a6..a3a6da38951 100644 --- a/htdocs/master.inc.php +++ b/htdocs/master.inc.php @@ -222,6 +222,12 @@ if (!defined('NOREQUIREDB') && !defined('NOREQUIRESOC')) { // For FR, default value of option to show category of operations is on by default. Decret n°2099-1299 2022-10-07 $conf->global->INVOICE_CATEGORY_OF_OPERATION = 1; } + + if ($mysoc->localtax1_assuj || $mysoc->localtax2_assuj) { + // For countries using the 2nd or 3rd tax, we disable input/edit of lines using the price including tax (because 2nb and 3rd tax not yet taken into account). + // Work In Progress to support all taxes into unit price entry when MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES is set. + $conf->global->MAIN_NO_INPUT_PRICE_WITH_TAX = 1; + } } diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index ec5d8c979ed..7a3aae33d9c 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -554,7 +554,7 @@ if (!empty($moreforfilter)) { } $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; -$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields +$selectedfields = ($mode != 'kanban' ? $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')) : ''); // This also change content of $arrayfields $selectedfields .= (count($arrayofmassactions) ? $form->showCheckAddButtons('checkforselect', 1) : ''); print '
'; // You can use div-table-responsive-no-min if you dont need reserved height for your table @@ -631,7 +631,7 @@ $totalarray['nbfield'] = 0; // -------------------------------------------------------------------- print ''; if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; $totalarray['nbfield']++; } foreach ($object->fields as $key => $val) { @@ -663,7 +663,7 @@ print $hookmanager->resPrint; }*/ // Action column if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { - print getTitleFieldOfList(($mode != 'kanban' ? $selectedfields : ''), 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; + print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"], '', '', '', '', $sortfield, $sortorder, 'center maxwidthsearch ')."\n"; $totalarray['nbfield']++; } print ''."\n"; diff --git a/htdocs/product/card.php b/htdocs/product/card.php index 241aec60d8e..b42384e934d 100644 --- a/htdocs/product/card.php +++ b/htdocs/product/card.php @@ -207,7 +207,7 @@ if ($cancel) { $action = ''; } -$createbarcode = empty($conf->barcode->enabled) ? 0 : 1; +$createbarcode = isModEnabled('barcode'); if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->creer_advance)) { $createbarcode = 0; } @@ -1419,7 +1419,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } } - $showbarcode = empty($conf->barcode->enabled) ? 0 : 1; + $showbarcode = isModEnabled('barcode'); if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) { $showbarcode = 0; } @@ -1984,7 +1984,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } // Barcode - $showbarcode = empty($conf->barcode->enabled) ? 0 : 1; + $showbarcode = isModEnabled('barcode'); if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) { $showbarcode = 0; } @@ -2312,7 +2312,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { } else { // Fiche en mode visu - $showbarcode = empty($conf->barcode->enabled) ? 0 : 1; + $showbarcode = isModEnabled('barcode'); if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->barcode->lire_advance)) { $showbarcode = 0; } diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 62526483542..f8c075b228c 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -368,6 +368,8 @@ class MouvementStock extends CommonObject } } else { // If not found, we add record $productlot = new Productlot($this->db); + $productlot->origin = !empty($this->origin) ? (empty($this->origin->origin_type) ? $this->origin->element : $this->origin->origin_type) : ''; + $productlot->origin_id = !empty($this->origin) ? $this->origin->id : 0; $productlot->entity = $conf->entity; $productlot->fk_product = $fk_product; $productlot->batch = $batch; diff --git a/htdocs/projet/activity/index.php b/htdocs/projet/activity/index.php index bbd9442f876..8f69a8afada 100644 --- a/htdocs/projet/activity/index.php +++ b/htdocs/projet/activity/index.php @@ -3,6 +3,7 @@ * Copyright (C) 2006-2015 Laurent Destailleur * Copyright (C) 2010 Regis Houssin * Copyright (C) 2019 Nicolas ZABOURI + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -116,15 +117,16 @@ print ''.$langs->trans('ActivityOnProjectToday').''; print ''.$langs->trans("Time").''; print "\n"; -$sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.task_duration) as nb"; +$sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.element_duration) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; -$sql .= ", ".MAIN_DB_PREFIX."projet_task_time as tt"; +$sql .= ", ".MAIN_DB_PREFIX."element_time as tt"; $sql .= " WHERE t.fk_projet = p.rowid"; $sql .= " AND p.entity = ".((int) $conf->entity); -$sql .= " AND tt.fk_task = t.rowid"; +$sql .= " AND tt.fk_element = t.rowid"; +$sql .= " AND tt.elementtype = 'task'"; $sql .= " AND tt.fk_user = ".((int) $user->id); -$sql .= " AND task_date BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; +$sql .= " AND element_date BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $month, $day, $year))."' AND '".$db->idate(dol_mktime(23, 59, 59, $month, $day, $year))."'"; $sql .= " AND p.rowid in (".$db->sanitize($projectsListId).")"; $sql .= " GROUP BY p.rowid, p.ref, p.title, p.public"; @@ -169,15 +171,16 @@ print ''.$langs->trans('ActivityOnProjectYesterday').''; print ''.$langs->trans("Time").''; print "\n"; -$sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.task_duration) as nb"; +$sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.element_duration) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; -$sql .= ", ".MAIN_DB_PREFIX."projet_task_time as tt"; +$sql .= ", ".MAIN_DB_PREFIX."element_time as tt"; $sql .= " WHERE t.fk_projet = p.rowid"; $sql .= " AND p.entity = ".((int) $conf->entity); -$sql .= " AND tt.fk_task = t.rowid"; +$sql .= " AND tt.fk_element = t.rowid"; +$sql .= " AND tt.elementtype = 'task'"; $sql .= " AND tt.fk_user = ".((int) $user->id); -$sql .= " AND task_date BETWEEN '".$db->idate(dol_time_plus_duree(dol_mktime(0, 0, 0, $month, $day, $year), -1, 'd'))."' AND '".$db->idate(dol_time_plus_duree(dol_mktime(23, 59, 59, $month, $day, $year), -1, 'd'))."'"; +$sql .= " AND element_date BETWEEN '".$db->idate(dol_time_plus_duree(dol_mktime(0, 0, 0, $month, $day, $year), -1, 'd'))."' AND '".$db->idate(dol_time_plus_duree(dol_mktime(23, 59, 59, $month, $day, $year), -1, 'd'))."'"; $sql .= " AND p.rowid in (".$db->sanitize($projectsListId).")"; $sql .= " GROUP BY p.rowid, p.ref, p.title, p.public"; @@ -281,15 +284,16 @@ if (!empty($conf->global->PROJECT_TASK_TIME_MONTH)) { print ''.$langs->trans("Time").''; print "\n"; - $sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.task_duration) as nb"; + $sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.element_duration) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; - $sql .= ", ".MAIN_DB_PREFIX."projet_task_time as tt"; + $sql .= ", ".MAIN_DB_PREFIX."element_time as tt"; $sql .= " WHERE t.fk_projet = p.rowid"; $sql .= " AND p.entity = ".((int) $conf->entity); - $sql .= " AND tt.fk_task = t.rowid"; + $sql .= " AND tt.fk_element = t.rowid"; + $sql .= " AND tt.elementtype = 'task'"; $sql .= " AND tt.fk_user = ".((int) $user->id); - $sql .= " AND task_date BETWEEN '".$db->idate(dol_get_first_day($year, $month))."' AND '".$db->idate(dol_get_last_day($year, $month))."'"; + $sql .= " AND element_date BETWEEN '".$db->idate(dol_get_first_day($year, $month))."' AND '".$db->idate(dol_get_last_day($year, $month))."'"; $sql .= " AND p.rowid in (".$db->sanitize($projectsListId).")"; $sql .= " GROUP BY p.rowid, p.ref, p.title, p.public"; @@ -327,15 +331,16 @@ if (!empty($conf->global->PROJECT_TASK_TIME_YEAR)) { print ''.$langs->trans("Time").''; print "\n"; - $sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.task_duration) as nb"; + $sql = "SELECT p.rowid, p.ref, p.title, p.public, SUM(tt.element_duration) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; - $sql .= ", ".MAIN_DB_PREFIX."projet_task_time as tt"; + $sql .= ", ".MAIN_DB_PREFIX."element_time as tt"; $sql .= " WHERE t.fk_projet = p.rowid"; $sql .= " AND p.entity = ".((int) $conf->entity); - $sql .= " AND tt.fk_task = t.rowid"; + $sql .= " AND tt.fk_element = t.rowid"; + $sql .= " AND tt.elementtype = 'task'"; $sql .= " AND tt.fk_user = ".((int) $user->id); - $sql .= " AND YEAR(task_date) = '".strftime("%Y", $now)."'"; + $sql .= " AND YEAR(element_date) = '".strftime("%Y", $now)."'"; $sql .= " AND p.rowid in (".$db->sanitize($projectsListId).")"; $sql .= " GROUP BY p.rowid, p.ref, p.title, p.public"; @@ -407,11 +412,11 @@ if (empty($conf->global->PROJECT_HIDE_TASKS) && !empty($conf->global->PROJECT_SH $max = (empty($conf->global->PROJECT_LIMIT_TASK_PROJECT_AREA) ? 1000 : $conf->global->PROJECT_LIMIT_TASK_PROJECT_AREA); $sql = "SELECT p.ref, p.title, p.rowid as projectid, p.fk_statut as status, p.fk_opp_status as opp_status, p.public, p.dateo as projdateo, p.datee as projdatee,"; - $sql .= " t.label, t.rowid as taskid, t.planned_workload, t.duration_effective, t.progress, t.dateo, t.datee, SUM(tasktime.task_duration) as timespent"; + $sql .= " t.label, t.rowid as taskid, t.planned_workload, t.duration_effective, t.progress, t.dateo, t.datee, SUM(tasktime.element_duration) as timespent"; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tasktime on tasktime.fk_task = t.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_time as tasktime on (tasktime.fk_element = t.rowid AND tasktime.elementtype = 'task')"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on tasktime.fk_user = u.rowid"; if ($mine) { $sql .= ", ".MAIN_DB_PREFIX."element_contact as ect"; diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index 5784e15040a..f9e2656d1f5 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -7,6 +7,7 @@ * Copyright (C) 2017 Ferran Marcet * Copyright (C) 2019 Juanjo Menent * Copyright (C) 2022 Charlene Benke + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -782,8 +783,8 @@ class Project extends CommonObject $sql = "SELECT ed.rowid FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND e.entity IN (".getEntity('expensereport').") AND ed.fk_projet IN (".$this->db->sanitize($ids).")"; } elseif ($type == 'project_task') { $sql = "SELECT DISTINCT pt.rowid FROM ".MAIN_DB_PREFIX."projet_task as pt WHERE pt.fk_projet IN (".$this->db->sanitize($ids).")"; - } elseif ($type == 'project_task_time') { // Case we want to duplicate line foreach user - $sql = "SELECT DISTINCT pt.rowid, ptt.fk_user FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet_task_time as ptt WHERE pt.rowid = ptt.fk_task AND pt.fk_projet IN (".$this->db->sanitize($ids).")"; + } elseif ($type == 'element_time') { // Case we want to duplicate line foreach user + $sql = "SELECT DISTINCT pt.rowid, ptt.fk_user FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."element_time as ptt WHERE pt.rowid = ptt.fk_element AND ptt.elementtype = 'task' AND pt.fk_projet IN (".$this->db->sanitize($ids).")"; } elseif ($type == 'stock_mouvement') { $sql = "SELECT ms.rowid, ms.fk_user_author as fk_user FROM ".MAIN_DB_PREFIX."stock_mouvement as ms, ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = ms.fk_entrepot AND e.entity IN (".getEntity('stock').") AND ms.origintype = 'project' AND ms.fk_origin IN (".$this->db->sanitize($ids).") AND ms.type_mouvement = 1"; } elseif ($type == 'loan') { @@ -1041,8 +1042,8 @@ class Project extends CommonObject $sql = "SELECT COUNT(ed.rowid) as nb FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND e.entity IN (".getEntity('expensereport').") AND ed.fk_projet = ".((int) $this->id); } elseif ($type == 'project_task') { $sql = "SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX."projet_task as pt WHERE pt.fk_projet = ".((int) $this->id); - } elseif ($type == 'project_task_time') { // Case we want to duplicate line foreach user - $sql = "SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet_task_time as ptt WHERE pt.rowid = ptt.fk_task AND pt.fk_projet = ".((int) $this->id); + } elseif ($type == 'element_time') { // Case we want to duplicate line foreach user + $sql = "SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."element_time as ptt WHERE pt.rowid = ptt.fk_element AND ptt.elementtype = 'task' AND pt.fk_projet = ".((int) $this->id); } elseif ($type == 'stock_mouvement') { $sql = "SELECT COUNT(ms.rowid) as nb FROM ".MAIN_DB_PREFIX."stock_mouvement as ms, ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = ms.fk_entrepot AND e.entity IN (".getEntity('stock').") AND ms.origintype = 'project' AND ms.fk_origin = ".((int) $this->id)." AND ms.type_mouvement = 1"; } elseif ($type == 'loan') { @@ -2017,14 +2018,15 @@ class Project extends CommonObject dol_print_error('', 'Error datestart parameter is empty'); } - $sql = "SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.task_datehour, ptt.fk_task"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time AS ptt, ".MAIN_DB_PREFIX."projet_task as pt"; - $sql .= " WHERE ptt.fk_task = pt.rowid"; + $sql = "SELECT ptt.rowid as taskid, ptt.element_duration, ptt.element_date, ptt.element_datehour, ptt.fk_element"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time AS ptt, ".MAIN_DB_PREFIX."projet_task as pt"; + $sql .= " WHERE ptt.fk_element = pt.rowid"; + $sql .= " AND ptt.elementtype = 'task'"; $sql .= " AND pt.fk_projet = ".((int) $this->id); - $sql .= " AND (ptt.task_date >= '".$this->db->idate($datestart)."' "; - $sql .= " AND ptt.task_date <= '".$this->db->idate(dol_time_plus_duree($datestart, 1, 'w') - 1)."')"; + $sql .= " AND (ptt.element_date >= '".$this->db->idate($datestart)."' "; + $sql .= " AND ptt.element_date <= '".$this->db->idate(dol_time_plus_duree($datestart, 1, 'w') - 1)."')"; if ($taskid) { - $sql .= " AND ptt.fk_task=".((int) $taskid); + $sql .= " AND ptt.fk_element=".((int) $taskid); } if (is_numeric($userid)) { $sql .= " AND ptt.fk_user=".((int) $userid); @@ -2040,13 +2042,13 @@ class Project extends CommonObject // Loop on each record found, so each couple (project id, task id) while ($i < $num) { $obj = $this->db->fetch_object($resql); - $day = $this->db->jdate($obj->task_date); // task_date is date without hours + $day = $this->db->jdate($obj->element_date); // task_date is date without hours if (empty($daylareadyfound[$day])) { - $this->weekWorkLoad[$day] = $obj->task_duration; - $this->weekWorkLoadPerTask[$day][$obj->fk_task] = $obj->task_duration; + $this->weekWorkLoad[$day] = $obj->element_duration; + $this->weekWorkLoadPerTask[$day][$obj->fk_element] = $obj->element_duration; } else { - $this->weekWorkLoad[$day] += $obj->task_duration; - $this->weekWorkLoadPerTask[$day][$obj->fk_task] += $obj->task_duration; + $this->weekWorkLoad[$day] += $obj->element_duration; + $this->weekWorkLoadPerTask[$day][$obj->fk_element] += $obj->element_duration; } $daylareadyfound[$day] = 1; $i++; @@ -2080,14 +2082,15 @@ class Project extends CommonObject dol_print_error('', 'Error datestart parameter is empty'); } - $sql = "SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.task_datehour, ptt.fk_task"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time AS ptt, ".MAIN_DB_PREFIX."projet_task as pt"; - $sql .= " WHERE ptt.fk_task = pt.rowid"; + $sql = "SELECT ptt.rowid as taskid, ptt.element_duration, ptt.element_date, ptt.element_datehour, ptt.fk_element"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time AS ptt, ".MAIN_DB_PREFIX."projet_task as pt"; + $sql .= " WHERE ptt.fk_element = pt.rowid"; + $sql .= " AND ptt.elementtype = 'task'"; $sql .= " AND pt.fk_projet = ".((int) $this->id); - $sql .= " AND (ptt.task_date >= '".$this->db->idate($datestart)."' "; - $sql .= " AND ptt.task_date <= '".$this->db->idate(dol_time_plus_duree($datestart, 1, 'm') - 1)."')"; + $sql .= " AND (ptt.element_date >= '".$this->db->idate($datestart)."' "; + $sql .= " AND ptt.element_date <= '".$this->db->idate(dol_time_plus_duree($datestart, 1, 'm') - 1)."')"; if ($taskid) { - $sql .= " AND ptt.fk_task=".((int) $taskid); + $sql .= " AND ptt.fk_element=".((int) $taskid); } if (is_numeric($userid)) { $sql .= " AND ptt.fk_user=".((int) $userid); @@ -2103,16 +2106,16 @@ class Project extends CommonObject // Loop on each record found, so each couple (project id, task id) while ($i < $num) { $obj = $this->db->fetch_object($resql); - if (!empty($obj->task_date)) { - $date = explode('-', $obj->task_date); + if (!empty($obj->element_date)) { + $date = explode('-', $obj->element_date); $week_number = getWeekNumber($date[2], $date[1], $date[0]); } if (empty($weekalreadyfound[$week_number])) { - $this->monthWorkLoad[$week_number] = $obj->task_duration; - $this->monthWorkLoadPerTask[$week_number][$obj->fk_task] = $obj->task_duration; + $this->monthWorkLoad[$week_number] = $obj->element_duration; + $this->monthWorkLoadPerTask[$week_number][$obj->fk_element] = $obj->element_duration; } else { - $this->monthWorkLoad[$week_number] += $obj->task_duration; - $this->monthWorkLoadPerTask[$week_number][$obj->fk_task] += $obj->task_duration; + $this->monthWorkLoad[$week_number] += $obj->element_duration; + $this->monthWorkLoadPerTask[$week_number][$obj->fk_element] += $obj->element_duration; } $weekalreadyfound[$week_number] = 1; $i++; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index d74aafdab6a..89a189a98c8 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -5,6 +5,7 @@ * Copyright (C) 2018-2023 Frédéric France * Copyright (C) 2020 Juanjo Menent * Copyright (C) 2022 Charlene Benke + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/timespent.class.php'; /** @@ -49,7 +51,7 @@ class Task extends CommonObjectLine /** * @var string Field with ID of parent key if this field has a parent */ - public $fk_element = 'fk_task'; + public $fk_element = 'fk_element'; /** * @var string String with name of icon for myobject. @@ -60,7 +62,7 @@ class Task extends CommonObjectLine * @var array List of child tables. To test if we can delete object. */ protected $childtables = array( - 'projet_task_time' => array('name' => 'Task', 'parent' => 'projet_task', 'parentkey' => 'fk_task') + 'element_time' => array('name' => 'Task', 'parent' => 'projet_task', 'parentkey' => 'fk_element', 'parenttypefield' => 'elementtype', 'parenttypevalue' => 'task') ); /** @@ -558,8 +560,8 @@ class Task extends CommonObjectLine } if (!$error) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time"; - $sql .= " WHERE fk_task = ".((int) $this->id); + $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_time"; + $sql .= " WHERE fk_element = ".((int) $this->id)." AND elementtype = 'task'"; $resql = $this->db->query($sql); if (!$resql) { @@ -675,8 +677,9 @@ class Task extends CommonObjectLine $ret = 0; $sql = "SELECT COUNT(*) as nb"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time"; - $sql .= " WHERE fk_task = ".((int) $this->id); + $sql .= " FROM ".MAIN_DB_PREFIX."element_time"; + $sql .= " WHERE fk_element = ".((int) $this->id); + $sql .= " AND elementtype = 'task'"; dol_syslog(get_class($this)."::hasTimeSpent", LOG_DEBUG); $resql = $this->db->query($sql); @@ -879,7 +882,7 @@ class Task extends CommonObjectLine } } if ($includebilltime) { - $sql .= ", SUM(tt.task_duration * ".$this->db->ifsql("invoice_id IS NULL", "1", "0").") as tobill, SUM(tt.task_duration * ".$this->db->ifsql("invoice_id IS NULL", "0", "1").") as billed"; + $sql .= ", SUM(tt.element_duration * ".$this->db->ifsql("invoice_id IS NULL", "1", "0").") as tobill, SUM(tt.element_duration * ".$this->db->ifsql("invoice_id IS NULL", "0", "1").") as billed"; } $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; @@ -893,7 +896,7 @@ class Task extends CommonObjectLine } $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; if ($includebilltime) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype='task')"; } if ($filterontaskuser > 0) { $sql .= ", ".MAIN_DB_PREFIX."element_contact as ec2"; @@ -910,14 +913,14 @@ class Task extends CommonObjectLine if ($filterontaskuser > 0) { $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; if ($includebilltime) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype='task')"; } $sql .= ", ".MAIN_DB_PREFIX."element_contact as ec2"; $sql .= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2"; } else { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; if ($includebilltime) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype = 'task')"; } } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_extrafields as efpt ON (t.rowid = efpt.fk_object)"; @@ -1263,31 +1266,20 @@ class Task extends CommonObjectLine $this->db->begin(); - $sql = "INSERT INTO ".MAIN_DB_PREFIX."projet_task_time ("; - $sql .= "fk_task"; - $sql .= ", task_date"; - $sql .= ", task_datehour"; - $sql .= ", task_date_withhour"; - $sql .= ", task_duration"; - $sql .= ", fk_user"; - $sql .= ", fk_product"; - $sql .= ", note"; - $sql .= ", datec"; - $sql .= ") VALUES ("; - $sql .= ((int) $this->id); - $sql .= ", '".$this->db->idate($this->timespent_date)."'"; - $sql .= ", '".$this->db->idate($this->timespent_datehour)."'"; - $sql .= ", ".(empty($this->timespent_withhour) ? 0 : 1); - $sql .= ", ".((int) $this->timespent_duration); - $sql .= ", ".((int) $this->timespent_fk_user); - $sql .= ", ".((int) $this->timespent_fk_product); - $sql .= ", ".(isset($this->timespent_note) ? "'".$this->db->escape($this->timespent_note)."'" : "null"); - $sql .= ", '".$this->db->idate($now)."'"; - $sql .= ")"; + $timespent = new TimeSpent($this->db); + $timespent->fk_element = $this->id; + $timespent->elementtype = 'task'; + $timespent->element_date = $this->timespent_date; + $timespent->element_datehour = $this->timespent_datehour; + $timespent->element_date_withhour = $this->timespent_withhour; + $timespent->element_duration = $this->timespent_duration; + $timespent->fk_user = $this->timespent_fk_user; + $timespent->fk_product = $this->timespent_fk_product; + $timespent->note = $this->timespent_note; + $timespent->datec = $this->db->idate($now); - $resql = $this->db->query($sql); - if ($resql) { - $tasktime_id = $this->db->last_insert_id(MAIN_DB_PREFIX."projet_task_time"); + if ($timespent->create($user) > 0) { + $tasktime_id = $this->db->last_insert_id(MAIN_DB_PREFIX."element_time"); $ret = $tasktime_id; $this->timespent_id = $ret; @@ -1307,7 +1299,7 @@ class Task extends CommonObjectLine if ($ret > 0) { // Recalculate amount of time spent for task and update denormalized field $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task"; - $sql .= " SET duration_effective = (SELECT SUM(task_duration) FROM ".MAIN_DB_PREFIX."projet_task_time as ptt where ptt.fk_task = ".((int) $this->id).")"; + $sql .= " SET duration_effective = (SELECT SUM(element_duration) FROM ".MAIN_DB_PREFIX."element_time as ptt where ptt.elementtype = 'task' AND ptt.fk_element = ".((int) $this->id).")"; if (isset($this->progress)) { $sql .= ", progress = ".((float) $this->progress); // Do not overwrite value if not provided } @@ -1320,12 +1312,15 @@ class Task extends CommonObjectLine } // Update hourly rate of this time spent entry - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time"; - $sql .= " SET thm = (SELECT thm FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".((int) $this->timespent_fk_user).")"; // set average hour rate of user - $sql .= " WHERE rowid = ".((int) $tasktime_id); + $resql_thm_user = $this->db->query("SELECT thm FROM " . MAIN_DB_PREFIX . "user WHERE rowid = " . ((int) $timespent->fk_user)); + if (!empty($resql_thm_user)) { + $obj_thm_user = $this->db->fetch_object($resql_thm_user); + $timespent->thm = $obj_thm_user->thm; + } + $res_update = $timespent->update($user); dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); - if (!$this->db->query($sql)) { + if ($res_update <= 0) { $this->error = $this->db->lasterror(); $ret = -2; } @@ -1356,11 +1351,11 @@ class Task extends CommonObjectLine $sql .= " s.nom as thirdparty_name,"; $sql .= " s.email as thirdparty_email,"; $sql .= " ptt.rowid,"; - $sql .= " ptt.fk_task,"; - $sql .= " ptt.task_date,"; - $sql .= " ptt.task_datehour,"; - $sql .= " ptt.task_date_withhour,"; - $sql .= " ptt.task_duration,"; + $sql .= " ptt.fk_element as fk_task,"; + $sql .= " ptt.element_date as task_date,"; + $sql .= " ptt.element_datehour as task_datehour,"; + $sql .= " ptt.element_date_withhour as task_date_withhour,"; + $sql .= " ptt.element_duration as task_duration,"; $sql .= " ptt.fk_user,"; $sql .= " ptt.note,"; $sql .= " ptt.thm,"; @@ -1371,9 +1366,10 @@ class Task extends CommonObjectLine $sql .= " p.ref as project_ref,"; $sql .= " p.title as project_label,"; $sql .= " p.public as public"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet as p"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as ptt, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; - $sql .= " WHERE ptt.fk_task = pt.rowid AND pt.fk_projet = p.rowid"; + $sql .= " WHERE ptt.fk_element = pt.rowid AND pt.fk_projet = p.rowid"; + $sql .= " AND ptt.elementtype = 'task'"; $sql .= " AND pt.rowid = ".((int) $this->id); $sql .= " AND pt.entity IN (".getEntity('project').")"; if ($morewherefilter) { @@ -1454,19 +1450,19 @@ class Task extends CommonObjectLine $result = array(); $sql = "SELECT"; - $sql .= " MIN(t.task_datehour) as min_date,"; - $sql .= " MAX(t.task_datehour) as max_date,"; - $sql .= " SUM(t.task_duration) as total_duration,"; - $sql .= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as total_amount,"; + $sql .= " MIN(t.element_datehour) as min_date,"; + $sql .= " MAX(t.element_datehour) as max_date,"; + $sql .= " SUM(t.element_duration) as total_duration,"; + $sql .= " SUM(t.element_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as total_amount,"; $sql .= " COUNT(t.rowid) as nblines,"; $sql .= " SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; - $sql .= " WHERE 1 = 1"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t"; + $sql .= " WHERE t.elementtype='task'"; if ($morewherefilter) { $sql .= $morewherefilter; } if ($id > 0) { - $sql .= " AND t.fk_task = ".((int) $id); + $sql .= " AND t.fk_element = ".((int) $id); } if ($userid > 0) { $sql .= " AND t.fk_user = ".((int) $userid); @@ -1514,19 +1510,19 @@ class Task extends CommonObjectLine $result = array(); $sql = "SELECT"; - $sql .= " SUM(t.task_duration) as nbseconds,"; - $sql .= " SUM(t.task_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as amount, SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; - $sql .= " WHERE t.fk_task = ".((int) $id); + $sql .= " SUM(t.element_duration) as nbseconds,"; + $sql .= " SUM(t.element_duration / 3600 * ".$this->db->ifsql("t.thm IS NULL", 0, "t.thm").") as amount, SUM(".$this->db->ifsql("t.thm IS NULL", 1, 0).") as nblinesnull"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t"; + $sql .= " WHERE t.elementtype='task' AND t.fk_element = ".((int) $id); if (is_object($fuser) && $fuser->id > 0) { $sql .= " AND fk_user = ".((int) $fuser->id); } if ($dates > 0) { - $datefieldname = "task_datehour"; + $datefieldname = "element_datehour"; $sql .= " AND (".$datefieldname." >= '".$this->db->idate($dates)."' OR ".$datefieldname." IS NULL)"; } if ($datee > 0) { - $datefieldname = "task_datehour"; + $datefieldname = "element_datehour"; $sql .= " AND (".$datefieldname." <= '".$this->db->idate($datee)."' OR ".$datefieldname." IS NULL)"; } //print $sql; @@ -1558,45 +1554,27 @@ class Task extends CommonObjectLine { global $langs; - $sql = "SELECT"; - $sql .= " t.rowid,"; - $sql .= " t.fk_task,"; - $sql .= " t.task_date,"; - $sql .= " t.task_datehour,"; - $sql .= " t.task_date_withhour,"; - $sql .= " t.task_duration,"; - $sql .= " t.fk_user,"; - $sql .= " t.fk_product,"; - $sql .= " t.thm,"; - $sql .= " t.note"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; - $sql .= " WHERE t.rowid = ".((int) $id); + $timespent = new TimeSpent($this->db); + $timespent->fetch($id); dol_syslog(get_class($this)."::fetchTimeSpent", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - if ($this->db->num_rows($resql)) { - $obj = $this->db->fetch_object($resql); - $this->timespent_id = $obj->rowid; - $this->id = $obj->fk_task; - $this->timespent_date = $this->db->jdate($obj->task_date); - $this->timespent_datehour = $this->db->jdate($obj->task_datehour); - $this->timespent_withhour = $obj->task_date_withhour; - $this->timespent_duration = $obj->task_duration; - $this->timespent_fk_user = $obj->fk_user; - $this->timespent_fk_product = $obj->fk_product; - $this->timespent_thm = $obj->thm; // hourly rate - $this->timespent_note = $obj->note; - } - - $this->db->free($resql); + if ($timespent->id > 0) { + $this->timespent_id = $timespent->id; + $this->id = $timespent->fk_element; + $this->timespent_date = $this->db->jdate($timespent->element_date); + $this->timespent_datehour = $this->db->jdate($timespent->element_datehour); + $this->timespent_withhour = $timespent->element_date_withhour; + $this->timespent_duration = $timespent->element_duration; + $this->timespent_fk_user = $timespent->fk_user; + $this->timespent_fk_product = $timespent->fk_product; + $this->timespent_thm = $timespent->thm; // hourly rate + $this->timespent_note = $timespent->note; return 1; - } else { - $this->error = "Error ".$this->db->lasterror(); - return -1; } + + return 0; } /** @@ -1615,11 +1593,11 @@ class Task extends CommonObjectLine $sql .= " s.nom as thirdparty_name,"; $sql .= " s.email as thirdparty_email,"; $sql .= " ptt.rowid,"; - $sql .= " ptt.fk_task,"; - $sql .= " ptt.task_date,"; - $sql .= " ptt.task_datehour,"; - $sql .= " ptt.task_date_withhour,"; - $sql .= " ptt.task_duration,"; + $sql .= " ptt.fk_element as fk_task,"; + $sql .= " ptt.element_date as task_date,"; + $sql .= " ptt.element_datehour as task_datehour,"; + $sql .= " ptt.element_date_withhour as task_date_withhour,"; + $sql .= " ptt.element_duration as task_duration,"; $sql .= " ptt.fk_user,"; $sql .= " ptt.note,"; $sql .= " ptt.thm,"; @@ -1630,9 +1608,10 @@ class Task extends CommonObjectLine $sql .= " p.ref as project_ref,"; $sql .= " p.title as project_label,"; $sql .= " p.public as public"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as ptt, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet as p"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as ptt, ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid"; - $sql .= " WHERE ptt.fk_task = pt.rowid AND pt.fk_projet = p.rowid"; + $sql .= " WHERE ptt.fk_element = pt.rowid AND pt.fk_projet = p.rowid"; + $sql .= " AND ptt.elementtype = 'task'"; $sql .= " AND ptt.fk_user = ".((int) $userobj->id); $sql .= " AND pt.entity IN (".getEntity('project').")"; if ($morewherefilter) { @@ -1731,20 +1710,20 @@ class Task extends CommonObjectLine $this->db->begin(); - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time SET"; - $sql .= " task_date = '".$this->db->idate($this->timespent_date)."',"; - $sql .= " task_datehour = '".$this->db->idate($this->timespent_datehour)."',"; - $sql .= " task_date_withhour = ".(empty($this->timespent_withhour) ? 0 : 1).","; - $sql .= " task_duration = ".((int) $this->timespent_duration).","; - $sql .= " fk_user = ".((int) $this->timespent_fk_user).","; - $sql .= " fk_product = ".((int) $this->timespent_fk_product).","; - $sql .= " invoice_id = ".((int) $this->timespent_invoiceid).","; - $sql .= " invoice_line_id = ".((int) $this->timespent_invoicelineid).","; - $sql .= " note = ".(isset($this->timespent_note) ? "'".$this->db->escape($this->timespent_note)."'" : "null"); - $sql .= " WHERE rowid = ".((int) $this->timespent_id); + $timespent = new TimeSpent($this->db); + $timespent->fetch($this->timespent_id); + $timespent->element_date = $this->timespent_date; + $timespent->element_datehour = $this->timespent_datehour; + $timespent->element_date_withhour = $this->timespent_withhour; + $timespent->element_duration = $this->timespent_duration; + $timespent->fk_user = $this->timespent_fk_user; + $timespent->fk_product = $this->timespent_fk_product; + $timespent->note = $this->timespent_note; + $timespent->invoice_id = $this->timespent_invoiceid; + $timespent->invoice_line_id = $this->timespent_invoicelineid; dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG); - if ($this->db->query($sql)) { + if ($timespent->update($user) > 0) { if (!$notrigger) { // Call trigger $result = $this->call_trigger('TASK_TIMESPENT_MODIFY', $user); @@ -1768,7 +1747,7 @@ class Task extends CommonObjectLine if ($this->timespent_old_duration != $this->timespent_duration) { // Recalculate amount of time spent for task and update denormalized field $sql = "UPDATE " . MAIN_DB_PREFIX . "projet_task"; - $sql .= " SET duration_effective = (SELECT SUM(task_duration) FROM " . MAIN_DB_PREFIX . "projet_task_time as ptt where ptt.fk_task = " . ((int) $this->id) . ")"; + $sql .= " SET duration_effective = (SELECT SUM(element_duration) FROM " . MAIN_DB_PREFIX . "element_time as ptt where ptt.elementtype = 'task' AND ptt.fk_element = " . ((int) $this->id) . ")"; if (isset($this->progress)) { $sql .= ", progress = " . ((float) $this->progress); // Do not overwrite value if not provided } @@ -1783,15 +1762,18 @@ class Task extends CommonObjectLine } // Update hourly rate of this time spent entry, but only if it was not set initialy - $sql = "UPDATE ".MAIN_DB_PREFIX."projet_task_time"; - $sql .= " SET thm = (SELECT thm FROM ".MAIN_DB_PREFIX."user WHERE rowid = ".((int) $this->timespent_fk_user).")"; // set average hour rate of user - $sql .= " WHERE rowid = ".((int) $this->timespent_id); - if (empty($conf->global->TIMESPENT_ALWAYS_UPDATE_THM)) { // then if not empty we always update, in case of new thm for user, or change user of task time line - $sql .= " AND (thm IS NULL OR thm = 0)"; + $res_update = 1; + if (empty($timespent->thm) || !empty($conf->global->TIMESPENT_ALWAYS_UPDATE_THM)) { + $resql_thm_user = $this->db->query("SELECT thm FROM " . MAIN_DB_PREFIX . "user WHERE rowid = " . ((int) $timespent->fk_user)); + if (!empty($resql_thm_user)) { + $obj_thm_user = $this->db->fetch_object($resql_thm_user); + $timespent->thm = $obj_thm_user->thm; + } + $res_update = $timespent->update($user); } - dol_syslog(get_class($this)."::addTimeSpent", LOG_DEBUG); - if (!$this->db->query($sql)) { + dol_syslog(get_class($this)."::updateTimeSpent", LOG_DEBUG); + if ($res_update <= 0) { $this->error = $this->db->lasterror(); $ret = -2; } @@ -1839,12 +1821,12 @@ class Task extends CommonObjectLine } if (!$error) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time"; - $sql .= " WHERE rowid = ".((int) $this->timespent_id); + $timespent = new TimeSpent($this->db); + $timespent->fetch($this->timespent_id); - dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { + $res_del = $timespent->delete($user); + + if ($res_del < 0) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } } diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 7d6d33be834..1bea15888bd 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -8,6 +8,7 @@ * Copyright (C) 2016 Josep Lluís Amador * Copyright (C) 2021 Gauthier VERDOL * Copyright (C) 2021 Noé Cendrier + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -575,7 +576,7 @@ $listofreferent = array( 'class'=>'Task', 'margin'=>'minus', 'table'=>'projet_task', - 'datefieldname'=>'task_date', + 'datefieldname'=>'element_date', 'disableamount'=>0, 'urlnew'=>DOL_URL_ROOT.'/projet/tasks/time.php?withproject=1&action=createtime&projectid='.$id.'&backtopage='.urlencode($_SERVER['PHP_SELF'].'?id='.$id), 'buttonnew'=>'AddTimeSpent', @@ -1337,7 +1338,7 @@ foreach ($listofreferent as $key => $value) { $tmpuser2->fetch($element->fk_user_author); print $tmpuser2->getNomUrl(1, '', 48); } - } elseif ($tablename == 'projet_task' && $key == 'project_task_time') { // if $key == 'project_task', we don't want details per user + } elseif ($tablename == 'projet_task' && $key == 'element_time') { // if $key == 'project_task', we don't want details per user print $elementuser->getNomUrl(1); } print ''; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 1f203113b3a..d0075b57ed7 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -192,6 +192,8 @@ foreach ($object->fields as $key => $val) { // Add name object fields to "search in all" $fieldstosearchall['s.nom'] = "ThirdPartyName"; +$fieldstosearchall['s.name_alias'] = "AliasNameShort"; +$fieldstosearchall['s.code_client'] = "CustomerCode"; // Definition of array of fields for columns $arrayfields = array(); diff --git a/htdocs/projet/tasks.php b/htdocs/projet/tasks.php index 7be9a3c93f5..9e448b6cf45 100644 --- a/htdocs/projet/tasks.php +++ b/htdocs/projet/tasks.php @@ -1111,11 +1111,11 @@ if ($action == 'create' && $user->rights->projet->creer && (empty($object->third $j = 0; $level = 0; $nboftaskshown = projectLinesa($j, 0, $tasksarray, $level, true, 0, $tasksrole, $object->id, 1, $object->id, $filterprogresscalc, ($object->usage_bill_time ? 1 : 0), $arrayfields, $arrayofselected); } else { - $colspan = 10; + $colspan = 11; if ($object->usage_bill_time) { $colspan += 2; } - print ''.$langs->trans("NoTasks").''; + print ''.$langs->trans("NoTasks").''; } print ""; diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 00449a30a17..a860f1205c7 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -4,6 +4,7 @@ * Copyright (C) 2006-2010 Regis Houssin * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2021 Alexandre Spangaro + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -345,7 +346,7 @@ $sql .= " t.description, t.fk_task_parent"; $sql .= " ,t.budget_amount"; // Add sum fields if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked'])) { - $sql .= " , SUM(tt.task_duration * ".$db->ifsql("invoice_id IS NULL", "1", "0").") as tobill, SUM(tt.task_duration * ".$db->ifsql("invoice_id IS NULL", "0", "1").") as billed"; + $sql .= " , SUM(tt.element_duration * ".$db->ifsql("invoice_id IS NULL", "1", "0").") as tobill, SUM(tt.element_duration * ".$db->ifsql("invoice_id IS NULL", "0", "1").") as billed"; } // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { @@ -361,7 +362,7 @@ $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; if (!empty($arrayfields['t.tobill']['checked']) || !empty($arrayfields['t.billed']['checked'])) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_time as tt ON (tt.fk_element = t.rowid AND tt.elementtype = 'task')"; } if (isset($extrafields->attributes[$object->table_element]['label']) && is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (t.rowid = ef.fk_object)"; diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index 9755e633f05..17a58f3a1e9 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -6,6 +6,7 @@ * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2018 Frédéric France * Copyright (C) 2019-2021 Christophe Battarel + * Copyright (C) 2023 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -104,7 +105,7 @@ $offset = $limit * $page; $pageprev = $page - 1; $pagenext = $page + 1; if (!$sortfield) { - $sortfield = 't.task_date,t.task_datehour,t.rowid'; + $sortfield = 't.element_date,t.element_datehour,t.rowid'; } if (!$sortorder) { $sortorder = 'DESC,DESC,DESC'; @@ -565,7 +566,7 @@ if ($action == 'confirm_generateinvoice') { } // Update lineid into line of timespent - $sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id); + $sql = 'UPDATE '.MAIN_DB_PREFIX.'element_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id); $sql .= ' WHERE rowid IN ('.$db->sanitize(join(',', $toselect)).') AND fk_user = '.((int) $userid); $result = $db->query($sql); if (!$result) { @@ -669,7 +670,7 @@ if ($action == 'confirm_generateinvoice') { //var_dump($lineid);exit; // Update lineid into line of timespent - $sql = 'UPDATE '.MAIN_DB_PREFIX.'projet_task_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id); + $sql = 'UPDATE '.MAIN_DB_PREFIX.'element_time SET invoice_line_id = '.((int) $lineid).', invoice_id = '.((int) $tmpinvoice->id); $sql .= ' WHERE rowid IN ('.$db->sanitize(join(',', $toselect)).') AND fk_user = '.((int) $userid); $result = $db->query($sql); if (!$result) { @@ -768,7 +769,7 @@ if ($action == 'confirm_generateinvoice') { if (!$error) { // Update lineid into line of timespent - $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'projet_task_time SET invoice_line_id = ' . ((int) $lineid) . ', invoice_id = ' . ((int) $tmpinvoice->id); + $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'element_time SET invoice_line_id = ' . ((int) $lineid) . ', invoice_id = ' . ((int) $tmpinvoice->id); $sql .= ' WHERE rowid IN (' . $db->sanitize(join(',', $toselect)) . ')'; $result = $db->query($sql); if (!$result) { @@ -1266,7 +1267,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Definition of fields for list $arrayfields = array(); - $arrayfields['t.task_date'] = array('label'=>$langs->trans("Date"), 'checked'=>1); + $arrayfields['t.element_date'] = array('label'=>$langs->trans("Date"), 'checked'=>1); $arrayfields['p.fk_soc'] = array('label'=>$langs->trans("ThirdParty"), 'type'=>'integer:Societe:/societe/class/societe.class.php:1','checked'=>1); $arrayfields['s.name_alias'] = array('label'=>$langs->trans("AliasNameShort"), 'type'=>'integer:Societe:/societe/class/societe.class.php:1'); if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task @@ -1274,15 +1275,15 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $arrayfields['p.project_ref'] = ['label' => $langs->trans('RefProject'), 'checked' => 1]; $arrayfields['p.project_label'] = ['label' => $langs->trans('ProjectLabel'), 'checked' => 1]; } - $arrayfields['t.task_ref'] = array('label'=>$langs->trans("RefTask"), 'checked'=>1); - $arrayfields['t.task_label'] = array('label'=>$langs->trans("LabelTask"), 'checked'=>1); + $arrayfields['t.element_ref'] = array('label'=>$langs->trans("RefTask"), 'checked'=>1); + $arrayfields['t.element_label'] = array('label'=>$langs->trans("LabelTask"), 'checked'=>1); } $arrayfields['author'] = array('label'=>$langs->trans("By"), 'checked'=>1); $arrayfields['t.note'] = array('label'=>$langs->trans("Note"), 'checked'=>1); if (isModEnabled('service') && !empty($projectstatic->thirdparty) && $projectstatic->thirdparty->id > 0 && $projectstatic->usage_bill_time) { $arrayfields['t.fk_product'] = array('label' => $langs->trans("Product"), 'checked' => 1); } - $arrayfields['t.task_duration'] = array('label'=>$langs->trans("Duration"), 'checked'=>1); + $arrayfields['t.element_duration'] = array('label'=>$langs->trans("Duration"), 'checked'=>1); $arrayfields['value'] = array('label'=>$langs->trans("Value"), 'checked'=>1, 'enabled'=>(empty($conf->salaries->enabled) ? 0 : 1)); $arrayfields['valuebilled'] = array('label'=>$langs->trans("Billed"), 'checked'=>1, 'enabled'=>(((!empty($conf->global->PROJECT_HIDE_TASKS) || empty($conf->global->PROJECT_BILL_TIME_SPENT)) ? 0 : 1) && $projectstatic->usage_bill_time)); // Extra fields @@ -1551,7 +1552,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage; $selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage, getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN', '')); // This also change content of $arrayfields - $sql = "SELECT t.rowid, t.fk_task, t.task_date, t.task_datehour, t.task_date_withhour, t.task_duration, t.fk_user, t.note, t.thm,"; + $sql = "SELECT t.rowid, t.fk_element, t.element_date, t.element_datehour, t.element_date_withhour, t.element_duration, t.fk_user, t.note, t.thm,"; $sql .= " t.fk_product,"; $sql .= " pt.ref, pt.label, pt.fk_projet,"; $sql .= " u.lastname, u.firstname, u.login, u.photo, u.statut as user_status,"; @@ -1563,11 +1564,11 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t"; + $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facturedet as il ON il.rowid = t.invoice_line_id"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as inv ON inv.rowid = il.fk_facture"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as prod ON prod.rowid = t.fk_product"; - $sql .= " INNER JOIN ".MAIN_DB_PREFIX."projet_task as pt ON pt.rowid = t.fk_task"; + $sql .= " INNER JOIN ".MAIN_DB_PREFIX."projet_task as pt ON pt.rowid = t.fk_element"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = pt.fk_projet"; $sql .= " INNER JOIN ".MAIN_DB_PREFIX."user as u ON t.fk_user = u.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = p.fk_soc"; @@ -1576,10 +1577,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; - $sql .= " WHERE 1 = 1 "; + $sql .= " WHERE elementtype='task' "; if (empty($projectidforalltimes) && empty($allprojectforuser)) { // Limit on one task - $sql .= " AND t.fk_task =".((int) $object->id); + $sql .= " AND t.fk_element =".((int) $object->id); } elseif (!empty($projectidforalltimes)) { // Limit on one project $sql .= " AND pt.fk_projet IN (".$db->sanitize($projectidforalltimes).")"; @@ -1630,27 +1631,27 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } if ($search_date_start) { - $sql .= " AND t.task_date >= '".$db->idate($search_date_start)."'"; + $sql .= " AND t.element_date >= '".$db->idate($search_date_start)."'"; } if ($search_date_end) { - $sql .= " AND t.task_date <= '".$db->idate($search_date_end)."'"; + $sql .= " AND t.element_date <= '".$db->idate($search_date_end)."'"; } - if (!empty($arrayfields['t.task_duration']['checked'])) { + if (!empty($arrayfields['t.element_duration']['checked'])) { if ($search_timespent_starthour || $search_timespent_startmin) { $timespent_duration_start = $search_timespent_starthour * 60 * 60; // We store duration in seconds $timespent_duration_start += ($search_timespent_startmin ? $search_timespent_startmin : 0) * 60; // We store duration in seconds - $sql .= " AND t.task_duration >= " . $timespent_duration_start; + $sql .= " AND t.element_duration >= " . $timespent_duration_start; } if ($search_timespent_endhour || $search_timespent_endmin) { $timespent_duration_end = $search_timespent_endhour * 60 * 60; // We store duration in seconds $timespent_duration_end += ($search_timespent_endmin ? $search_timespent_endmin : 0) * 60; // We store duration in seconds - $sql .= " AND t.task_duration <= " . $timespent_duration_end; + $sql .= " AND t.element_duration <= " . $timespent_duration_end; } } - $sql .= dolSqlDateFilter('t.task_datehour', $search_day, $search_month, $search_year); + $sql .= dolSqlDateFilter('t.element_datehour', $search_day, $search_month, $search_year); // Add where from hooks $parameters = array(); @@ -1878,7 +1879,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; } // Date - if (!empty($arrayfields['t.task_date']['checked'])) { + if (!empty($arrayfields['t.element_date']['checked'])) { print ''; print '
'; print $form->selectDate($search_date_start ? $search_date_start : -1, 'search_date_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans('From')); @@ -1908,10 +1909,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Task if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task - if (!empty($arrayfields['t.task_ref']['checked'])) { + if (!empty($arrayfields['t.element_ref']['checked'])) { print ''; } - if (!empty($arrayfields['t.task_label']['checked'])) { + if (!empty($arrayfields['t.element_label']['checked'])) { print ''; } } @@ -1924,7 +1925,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; } // Duration - if (!empty($arrayfields['t.task_duration']['checked'])) { + if (!empty($arrayfields['t.element_duration']['checked'])) { // Duration - Time spent print ''; @@ -1980,12 +1981,12 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', '', 'width="80"', $sortfield, $sortorder, 'center maxwidthsearch '); } - if (!empty($arrayfields['t.task_date']['checked'])) { - print_liste_field_titre($arrayfields['t.task_date']['label'], $_SERVER['PHP_SELF'], 't.task_date,t.task_datehour,t.rowid', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['t.element_date']['checked'])) { + print_liste_field_titre($arrayfields['t.element_date']['label'], $_SERVER['PHP_SELF'], 't.element_date,t.element_datehour,t.rowid', '', $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['p.fk_soc']['checked'])) { - print_liste_field_titre($arrayfields['p.fk_soc']['label'], $_SERVER['PHP_SELF'], 't.task_date,t.task_datehour,t.rowid', '', $param, '', $sortfield, $sortorder); + print_liste_field_titre($arrayfields['p.fk_soc']['label'], $_SERVER['PHP_SELF'], 't.element_date,t.element_datehour,t.rowid', '', $param, '', $sortfield, $sortorder); } if (!empty($arrayfields['s.name_alias']['checked'])) { print_liste_field_titre($arrayfields['s.name_alias']['label'], $_SERVER['PHP_SELF'], 's.name_alias', '', $param, '', $sortfield, $sortorder); @@ -1999,11 +2000,11 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task - if (!empty($arrayfields['t.task_ref']['checked'])) { - print_liste_field_titre($arrayfields['t.task_ref']['label'], $_SERVER['PHP_SELF'], 'pt.ref', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['t.element_ref']['checked'])) { + print_liste_field_titre($arrayfields['t.element_ref']['label'], $_SERVER['PHP_SELF'], 'pt.ref', '', $param, '', $sortfield, $sortorder); } - if (!empty($arrayfields['t.task_label']['checked'])) { - print_liste_field_titre($arrayfields['t.task_label']['label'], $_SERVER['PHP_SELF'], 'pt.label', '', $param, '', $sortfield, $sortorder); + if (!empty($arrayfields['t.element_label']['checked'])) { + print_liste_field_titre($arrayfields['t.element_label']['label'], $_SERVER['PHP_SELF'], 'pt.label', '', $param, '', $sortfield, $sortorder); } } if (!empty($arrayfields['author']['checked'])) { @@ -2012,8 +2013,8 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (!empty($arrayfields['t.note']['checked'])) { print_liste_field_titre($arrayfields['t.note']['label'], $_SERVER['PHP_SELF'], 't.note', '', $param, '', $sortfield, $sortorder); } - if (!empty($arrayfields['t.task_duration']['checked'])) { - print_liste_field_titre($arrayfields['t.task_duration']['label'], $_SERVER['PHP_SELF'], 't.task_duration', '', $param, '', $sortfield, $sortorder, 'right '); + if (!empty($arrayfields['t.element_duration']['checked'])) { + print_liste_field_titre($arrayfields['t.element_duration']['label'], $_SERVER['PHP_SELF'], 't.element_duration', '', $param, '', $sortfield, $sortorder, 'right '); } if (!empty($arrayfields['t.fk_product']['checked'])) { print_liste_field_titre($arrayfields['t.fk_product']['label'], $_SERVER['PHP_SELF'], 't.fk_product', '', $param, '', $sortfield, $sortorder); @@ -2051,8 +2052,8 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser break; } - $date1 = $db->jdate($task_time->task_date); - $date2 = $db->jdate($task_time->task_datehour); + $date1 = $db->jdate($task_time->element_date); + $date2 = $db->jdate($task_time->element_datehour); print ''; @@ -2073,11 +2074,11 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; } - print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; + print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; print img_edit('default', 0, 'class="pictofixedwidth paddingleft"'); print ''; - print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; + print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; print img_delete('default', 'class="pictodelete paddingleft"'); print ''; @@ -2093,16 +2094,16 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } } // Date - if (!empty($arrayfields['t.task_date']['checked'])) { + if (!empty($arrayfields['t.element_date']['checked'])) { print ''; if ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) { - if (empty($task_time->task_date_withhour)) { + if (empty($task_time->element_date_withhour)) { print $form->selectDate(($date2 ? $date2 : $date1), 'timeline', 3, 3, 2, "timespent_date", 1, 0); } else { print $form->selectDate(($date2 ? $date2 : $date1), 'timeline', 1, 1, 2, "timespent_date", 1, 0); } } else { - print dol_print_date(($date2 ? $date2 : $date1), ($task_time->task_date_withhour ? 'dayhour' : 'day')); + print dol_print_date(($date2 ? $date2 : $date1), ($task_time->element_date_withhour ? 'dayhour' : 'day')); } print ''; if (!$i) { @@ -2183,13 +2184,13 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Task ref - if (!empty($arrayfields['t.task_ref']['checked'])) { + if (!empty($arrayfields['t.element_ref']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task print ''; if ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) { - $formproject->selectTasks(-1, GETPOST('taskid', 'int') ? GETPOST('taskid', 'int') : $task_time->fk_task, 'taskid', 0, 0, 1, 1, 0, 0, 'maxwidth300', $projectstatic->id, ''); + $formproject->selectTasks(-1, GETPOST('taskid', 'int') ? GETPOST('taskid', 'int') : $task_time->fk_element, 'taskid', 0, 0, 1, 1, 0, 0, 'maxwidth300', $projectstatic->id, ''); } else { - $tasktmp->id = $task_time->fk_task; + $tasktmp->id = $task_time->fk_element; $tasktmp->ref = $task_time->ref; $tasktmp->label = $task_time->label; print $tasktmp->getNomUrl(1, 'withproject', 'time'); @@ -2204,7 +2205,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Task label - if (!empty($arrayfields['t.task_label']['checked'])) { + if (!empty($arrayfields['t.element_label']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task print ''; print dol_escape_htmltag($task_time->label); @@ -2263,33 +2264,33 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Time spent - if (!empty($arrayfields['t.task_duration']['checked'])) { + if (!empty($arrayfields['t.element_duration']['checked'])) { print ''; if ($action == 'editline' && GETPOST('lineid', 'int') == $task_time->rowid) { - print ''; - print $form->select_duration('new_duration', $task_time->task_duration, 0, 'text'); + print ''; + print $form->select_duration('new_duration', $task_time->element_duration, 0, 'text'); } else { - print convertSecondToTime($task_time->task_duration, 'allhourmin'); + print convertSecondToTime($task_time->element_duration, 'allhourmin'); } print ''; if (!$i) { $totalarray['nbfield']++; } if (!$i) { - $totalarray['pos'][$totalarray['nbfield']] = 't.task_duration'; + $totalarray['pos'][$totalarray['nbfield']] = 't.element_duration'; } - if (empty($totalarray['val']['t.task_duration'])) { - $totalarray['val']['t.task_duration'] = $task_time->task_duration; + if (empty($totalarray['val']['t.element_duration'])) { + $totalarray['val']['t.element_duration'] = $task_time->element_duration; } else { - $totalarray['val']['t.task_duration'] += $task_time->task_duration; + $totalarray['val']['t.element_duration'] += $task_time->element_duration; } if (!$i) { $totalarray['totaldurationfield'] = $totalarray['nbfield']; } if (empty($totalarray['totalduration'])) { - $totalarray['totalduration'] = $task_time->task_duration; + $totalarray['totalduration'] = $task_time->element_duration; } else { - $totalarray['totalduration'] += $task_time->task_duration; + $totalarray['totalduration'] += $task_time->element_duration; } } @@ -2313,7 +2314,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser // Value spent if (!empty($arrayfields['value']['checked'])) { $langs->load("salaries"); - $value = price2num($task_time->thm * $task_time->task_duration / 3600, 'MT', 1); + $value = price2num($task_time->thm * $task_time->element_duration / 3600, 'MT', 1); print ''; print 'thm).'">'; @@ -2403,11 +2404,11 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; } - print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; + print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; print img_edit('default', 0, 'class="pictofixedwidth paddingleft"'); print ''; - print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; + print 'rowid.$param.((empty($id) || $tab == 'timespent') ? '&tab=timespent' : '').'">'; print img_delete('default', 'class="pictodelete paddingleft"'); print ''; @@ -2436,16 +2437,16 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; // Date - if (!empty($arrayfields['t.task_date']['checked'])) { + if (!empty($arrayfields['t.element_date']['checked'])) { print ''; if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) { - if (empty($task_time->task_date_withhour)) { + if (empty($task_time->element_date_withhour)) { print $form->selectDate(($date2 ? $date2 : $date1), 'timeline', 3, 3, 2, "timespent_date", 1, 0); } else { print $form->selectDate(($date2 ? $date2 : $date1), 'timeline', 1, 1, 2, "timespent_date", 1, 0); } } else { - print dol_print_date(($date2 ? $date2 : $date1), ($task_time->task_date_withhour ? 'dayhour' : 'day')); + print dol_print_date(($date2 ? $date2 : $date1), ($task_time->element_date_withhour ? 'dayhour' : 'day')); } print ''; } @@ -2459,10 +2460,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Task ref - if (!empty($arrayfields['t.task_ref']['checked'])) { + if (!empty($arrayfields['t.element_ref']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task print ''; - $tasktmp->id = $task_time->fk_task; + $tasktmp->id = $task_time->fk_element; $tasktmp->ref = $task_time->ref; $tasktmp->label = $task_time->label; print $tasktmp->getNomUrl(1, 'withproject', 'time'); @@ -2471,7 +2472,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Task label - if (!empty($arrayfields['t.task_label']['checked'])) { + if (!empty($arrayfields['t.element_label']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task print ''; print dol_escape_htmltag($task_time->label); @@ -2521,13 +2522,13 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Time spent - if (!empty($arrayfields['t.task_duration']['checked'])) { + if (!empty($arrayfields['t.element_duration']['checked'])) { print ''; if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) { - print ''; - print $form->select_duration('new_duration', $task_time->task_duration, 0, 'text'); + print ''; + print $form->select_duration('new_duration', $task_time->element_duration, 0, 'text'); } else { - print convertSecondToTime($task_time->task_duration, 'allhourmin'); + print convertSecondToTime($task_time->element_duration, 'allhourmin'); } print ''; } @@ -2536,7 +2537,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if (!empty($arrayfields['value']['checked'])) { print ''; print ''; - $value = price2num($task_time->thm * $task_time->task_duration / 3600, 'MT', 1); + $value = price2num($task_time->thm * $task_time->element_duration / 3600, 'MT', 1); print price($value, 1, $langs, 1, -1, -1, $conf->currency); print ''; print ''; @@ -2574,16 +2575,16 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print ''; // Date - if (!empty($arrayfields['t.task_date']['checked'])) { + if (!empty($arrayfields['t.element_date']['checked'])) { print ''; if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) { - if (empty($task_time->task_date_withhour)) { + if (empty($task_time->element_date_withhour)) { print $form->selectDate(($date2 ? $date2 : $date1), 'timeline_2', 3, 3, 2, "timespent_date", 1, 0); } else { print $form->selectDate(($date2 ? $date2 : $date1), 'timeline_2', 1, 1, 2, "timespent_date", 1, 0); } } else { - print dol_print_date(($date2 ? $date2 : $date1), ($task_time->task_date_withhour ? 'dayhour' : 'day')); + print dol_print_date(($date2 ? $date2 : $date1), ($task_time->element_date_withhour ? 'dayhour' : 'day')); } print ''; } @@ -2597,10 +2598,10 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Task ref - if (!empty($arrayfields['t.task_ref']['checked'])) { + if (!empty($arrayfields['t.element_ref']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task print ''; - $tasktmp->id = $task_time->fk_task; + $tasktmp->id = $task_time->fk_element; $tasktmp->ref = $task_time->ref; $tasktmp->label = $task_time->label; print $tasktmp->getNomUrl(1, 'withproject', 'time'); @@ -2609,7 +2610,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Task label - if (!empty($arrayfields['t.task_label']['checked'])) { + if (!empty($arrayfields['t.element_label']['checked'])) { if ((empty($id) && empty($ref)) || !empty($projectidforalltimes)) { // Not a dedicated task print ''; print $task_time->label; @@ -2659,13 +2660,13 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser } // Time spent - if (!empty($arrayfields['t.task_duration']['checked'])) { + if (!empty($arrayfields['t.element_duration']['checked'])) { print ''; if ($action == 'splitline' && GETPOST('lineid', 'int') == $task_time->rowid) { print ''; print $form->select_duration('new_duration_2', 0, 0, 'text'); } else { - print convertSecondToTime($task_time->task_duration, 'allhourmin'); + print convertSecondToTime($task_time->element_duration, 'allhourmin'); } print ''; } diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php index 80ea664292b..2bb574def50 100644 --- a/htdocs/public/ticket/create_ticket.php +++ b/htdocs/public/ticket/create_ticket.php @@ -512,7 +512,7 @@ $arrayofcss = array('/opensurvey/css/style.css', '/ticket/css/styles.css.php'); llxHeaderTicket($langs->trans("CreateTicket"), "", 0, 0, $arrayofjs, $arrayofcss); -print '
'; +print '
'; if ($action != "infos_success") { $formticket->withfromsocid = isset($socid) ? $socid : $user->socid; diff --git a/htdocs/public/ticket/index.php b/htdocs/public/ticket/index.php index 97af18c0bb6..a36a0023324 100644 --- a/htdocs/public/ticket/index.php +++ b/htdocs/public/ticket/index.php @@ -80,7 +80,7 @@ $arrayofcss = array('/ticket/css/styles.css.php'); llxHeaderTicket($langs->trans("Tickets"), "", 0, 0, $arrayofjs, $arrayofcss); -print '
'; +print '
'; print '

'.(getDolGlobalString("TICKET_PUBLIC_TEXT_HOME", ''.$langs->trans("TicketPublicDesc")).'

').'

'; print '
'; diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index aafea0365e0..8e56d57e871 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -193,9 +193,8 @@ $arrayofcss = array('/ticket/css/styles.css.php'); llxHeaderTicket($langs->trans("Tickets"), "", 0, 0, $arrayofjs, $arrayofcss); - if ($action == "view_ticketlist") { - print '
'; + print '
'; print '
'; if ($display_ticket_list) { @@ -426,6 +425,7 @@ if ($action == "view_ticketlist") { $reshook=$hookmanager->executeHooks('printFieldListHeader', $parameters, $object, $action); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; + print '
'; print ''; // Filter bar @@ -697,6 +697,8 @@ if ($action == "view_ticketlist") { } print '
'; + print '
'; + print ''; print '
'; } else { - print '
'; + print '
'; print '

'.$langs->trans("TicketPublicMsgViewLogIn").'

'; print '
'; diff --git a/htdocs/public/ticket/view.php b/htdocs/public/ticket/view.php index 1bfc235ff65..b8f5b48fbac 100644 --- a/htdocs/public/ticket/view.php +++ b/htdocs/public/ticket/view.php @@ -218,6 +218,9 @@ include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php'; $form = new Form($db); $formticket = new FormTicket($db); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('ticketpublicview', 'globalcard')); + if (!$conf->global->TICKET_ENABLE_PUBLIC_INTERFACE) { print '
'.$langs->trans('TicketPublicInterfaceForbidden').'
'; $db->close(); @@ -229,7 +232,7 @@ $arrayofcss = array('/ticket/css/styles.css.php'); llxHeaderTicket($langs->trans("Tickets"), "", 0, 0, $arrayofjs, $arrayofcss); -print '
'; +print '
'; if ($action == "view_ticket" || $action == "presend" || $action == "close" || $action == "confirm_public_close") { if ($display_ticket) { @@ -332,6 +335,9 @@ if ($action == "view_ticket" || $action == "presend" || $action == "close" || $a print ($object->dao->progress > 0 ? dol_escape_htmltag($object->dao->progress) : '0').'%'; print ''; + // Other attributes + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; + print ''; print '
'; @@ -376,7 +382,7 @@ if ($action == "view_ticket" || $action == "presend" || $action == "close" || $a // Close ticket if ($object->dao->fk_statut >= Ticket::STATUS_NOT_READ && $object->dao->fk_statut < Ticket::STATUS_CLOSED) { - print ''; + print ''; } } @@ -390,10 +396,11 @@ if ($action == "view_ticket" || $action == "presend" || $action == "close" || $a print ''; } } else { - print '
'.$langs->trans("TicketPublicMsgViewLogIn").'
'; + print '
'.$langs->trans("TicketPublicMsgViewLogIn").'
'; print '
'; print ''; + print ''; print ''; diff --git a/htdocs/public/users/view.php b/htdocs/public/users/view.php index 0eaeb1b6c8f..c62420c76d8 100644 --- a/htdocs/public/users/view.php +++ b/htdocs/public/users/view.php @@ -205,7 +205,7 @@ $arrayofjs = array(); $arrayofcss = array(); $replacemainarea = (empty($conf->dol_hide_leftmenu) ? '
' : '').'
'; -llxHeader($head, $object->getFullName($langs).' - '.$langs->trans("PublicVirtualCard"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'.(GETPOST('mode')=='preview' ? ' scalepreview nopointervent' : ''), $replacemainarea, 1, 1); +llxHeader($head, $object->getFullName($langs).' - '.$langs->trans("PublicVirtualCard"), '', '', 0, 0, '', '', '', 'onlinepaymentbody'.(GETPOST('mode')=='preview' ? ' scalepreview cursorpointer virtualcardpreview' : ''), $replacemainarea, 1, 1); print ''."\n"; print '
'."\n"; @@ -451,8 +451,6 @@ print '
'."\n"; print '
'; -//htmlPrintOnlinePaymentFooter($mysoc, $langs); - print ''; print '
'; +$fullexternaleurltovirtualcard = $object->getOnlineVirtualCardUrl('', 'external'); +$fullinternalurltovirtualcard = $object->getOnlineVirtualCardUrl('', 'internal'); + +print ''; + llxFooter('', 'public'); $db->close(); diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index d1631d94d94..878ae857ac0 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -523,6 +523,8 @@ if (!$ret) { $fichinter->fetch($element_id, $element_ref); $fichinter->fetch_thirdparty(); + $usercancreate = $user->hasRight('fichinter', 'creer'); + if (is_object($fichinter)) { $head = fichinter_prepare_head($fichinter); print dol_get_fiche_head($head, 'resource', $langs->trans("InterventionCard"), -1, 'intervention'); @@ -533,40 +535,30 @@ if (!$ret) { $morehtmlref = '
'; // Ref customer - //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', 0, 1); - //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $object->ref_client, $object, 0, 'string', '', null, null, '', 1); + //$morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $fichinter->ref_client, $fichinter, $user->rights->ficheinter->creer, 'string', '', 0, 1); + //$morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $fichinter->ref_client, $fichinter, $user->rights->ficheinter->creer, 'string', '', null, null, '', 1); + $morehtmlref.=$form->editfieldkey("RefCustomer", 'ref_client', $fichinter->ref_client, $fichinter, 0, 'string', '', 0, 1); + $morehtmlref.=$form->editfieldval("RefCustomer", 'ref_client', $fichinter->ref_client, $fichinter, 0, 'string', '', null, null, '', 1); // Thirdparty - $morehtmlref .= $langs->trans('ThirdParty').' : '.$fichinter->thirdparty->getNomUrl(1); + $morehtmlref .= '
'.$fichinter->thirdparty->getNomUrl(1, 'customer'); // Project if (isModEnabled('project')) { $langs->load("projects"); - $morehtmlref .= '
'.$langs->trans('Project').' '; - if ($user->hasRight('commande', 'creer')) { + $morehtmlref .= '
'; + if ($usercancreate && 0) { + $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"'); if ($action != 'classify') { - //$morehtmlref.='
' . img_edit($langs->transnoentitiesnoconv('SetProject')) . ' : '; - $morehtmlref .= ' : '; - } - if ($action == 'classify') { - //$morehtmlref.=$form->form_project($_SERVER['PHP_SELF'] . '?id=' . $fichinter->id, $fichinter->socid, $fichinter->fk_project, 'projectid', 0, 0, 1, 1); - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= ''; - $morehtmlref .= $formproject->select_projects($fichinter->socid, $fichinter->fk_project, 'projectid', $maxlength, 0, 1, 0, 1, 0, 0, '', 1); - $morehtmlref .= ''; - $morehtmlref .= ''; - } else { - $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$fichinter->id, $fichinter->socid, $fichinter->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300'); + $morehtmlref .= ''.img_edit($langs->transnoentitiesnoconv('SetProject')).' '; } + $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$fichinter->id, $fichinter->socid, $fichinter->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300'); } else { if (!empty($fichinter->fk_project)) { $proj = new Project($db); $proj->fetch($fichinter->fk_project); - $morehtmlref .= ' : '.$proj->getNomUrl(1); + $morehtmlref .= $proj->getNomUrl(1); if ($proj->title) { - $morehtmlref .= ' - '.$proj->title; + $morehtmlref .= ' - '.dol_escape_htmltag($proj->title).''; } - } else { - $morehtmlref .= ''; } } } diff --git a/htdocs/takepos/css/pos.css.php b/htdocs/takepos/css/pos.css.php index 5a773fc3347..769c343f1fe 100644 --- a/htdocs/takepos/css/pos.css.php +++ b/htdocs/takepos/css/pos.css.php @@ -248,6 +248,9 @@ div.wrapper{ text-align: center; box-sizing: border-box; background-color:#fff; + display: flex; + align-items: center; + justify-content: center; } div.wrapper2{ @@ -262,10 +265,14 @@ div.wrapper2{ text-align: center; box-sizing: border-box; background-color:#fff; + display: flex; + align-items: center; + justify-content: center; } img.imgwrapper { max-width: 100%; + max-height: 100%; } button:active{ @@ -927,6 +934,7 @@ div#moreinfo, div#infowarehouse { display: inline-flex; align-items: center; padding: 10px; + justify-content: normal; } .div5 .wrapper2.divempty { diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php index fb3049715cf..bbbf9e0cd33 100644 --- a/htdocs/takepos/index.php +++ b/htdocs/takepos/index.php @@ -1388,7 +1388,7 @@ if (!empty($conf->global->TAKEPOS_WEIGHING_SCALE)) { echo ''; } else { if (!getDolGlobalString('TAKEPOS_HIDE_CATEGORY_IMAGES')) { - echo ''; + echo ''; } } ?> @@ -1433,7 +1433,7 @@ if (!empty($conf->global->TAKEPOS_WEIGHING_SCALE)) { echo ''; } else { print '
'; - print ''; + print ''; } } ?> diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index aafabf45d63..cab0cb247ca 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -4259,10 +4259,14 @@ div.liste_titre_bydiv { border-collapse: collapse; padding: 2px 0px 2px 0; box-shadow: none; - /*width: calc(100% - 1px); 1px less because display is table and with100%, it generated a right border 1px left compared to the div-table-responsive under */ + /*width: calc(100% - 1px); 1px less because display is table and with 100%, it generated a right border 1px left compared to the div-table-responsive under */ width: unset; - /* display: table; */ } +div.liste_titre_bydiv_inlineblock { + display: inline-block; + width: 100%; +} + tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable.tr, tagtr.liste_titre { height: 26px !important; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 2a46cf83911..29e460a7c4f 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -4375,8 +4375,15 @@ div.liste_titre_bydiv { display: table; padding: 2px 0px 2px 0; box-shadow: none; - width: calc(100% - 2px); /* -3px because the width for table class="tagtable" under this is cal(100% - 2px) so it is aligned. */ + width: calc(100% - 2px); /* -2px because the width for table class="tagtable" under this is cal(100% - 2px) so it is aligned. */ } +/* +div.liste_titre_bydiv_inlineblock { + display: inline-block; + width: 100%; +} +*/ + tr.liste_titre, tr.liste_titre_sel, form.liste_titre, form.liste_titre_sel, table.dataTable.tr, tagtr.liste_titre { height: 26px !important; diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index 42afd27304b..8e2114f9bae 100755 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -1248,10 +1248,12 @@ if ($action == 'create' || $action == 'presend') { } print ''; // Group - print ''.$langs->trans("TicketCategory").''; + $s = ''; if (!empty($object->category_code)) { - print $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code); + $s = $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code); } + print ''.$langs->trans("TicketCategory").''; + print dol_escape_htmltag($s); print ''; // Severity print ''.$langs->trans("TicketSeverity").''; diff --git a/htdocs/ticket/css/styles.css.php b/htdocs/ticket/css/styles.css.php index 81d7d21748f..2ebc3420a14 100644 --- a/htdocs/ticket/css/styles.css.php +++ b/htdocs/ticket/css/styles.css.php @@ -124,4 +124,10 @@ div.ticketform .index_create, div.ticketform .index_display { @media only screen and (max-width: 767px) { #form_create_ticket input.text, #form_create_ticket textarea { width: unset;} + + #form_create_ticket, #form_view_ticket + { + margin-left: 0; + margin-right: 0; + } } diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 8db29a87449..dfd90b4dc0f 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -1046,13 +1046,13 @@ if ($action == 'create' || $action == 'adduserldap') { if (preg_match('/http/', $dolibarr_main_authentication)) { $valuetoshow .= ($valuetoshow ? ' + ' : '').$langs->trans("HTTPBasicPassword"); } - if (preg_match('/dolibarr/', $dolibarr_main_authentication)) { + if (preg_match('/dolibarr/', $dolibarr_main_authentication) || preg_match('/forceuser/', $dolibarr_main_authentication)) { if (!empty($ldap_pass)) { // For very old system comaptibilty. Now clear password can't be viewed from LDAP read $valuetoshow .= ($valuetoshow ? ' + ' : '').''; // Dolibarr password is preffiled with LDAP known password $valuetoshow .= preg_replace('/./i', '*', $ldap_pass); } else { // We do not use a field password but a field text to show new password to use. - $valuetoshow .= ($valuetoshow ? ' + '.$langs->trans("DolibarrPassword") : '').''; + $valuetoshow .= ($valuetoshow ? ' + '.$langs->trans("DolibarrPassword") : '').''; if (!empty($conf->use_javascript_ajax)) { $valuetoshow .= ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_password" class="linkobject"'); } @@ -1076,7 +1076,7 @@ if ($action == 'create' || $action == 'adduserldap') { //$generated_password = getRandomPassword(false); print ''.$langs->trans("ApiKey").''; print ''; - print ''; + print ''; if (!empty($conf->use_javascript_ajax)) { print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"'); } @@ -2423,14 +2423,16 @@ if ($action == 'create' || $action == 'adduserldap') { if (preg_match('/http/', $dolibarr_main_authentication)) { $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').$form->textwithpicto($text, $langs->trans("DolibarrInHttpAuthenticationSoPasswordUseless", $dolibarr_main_authentication), 1, 'warning'); } - if (preg_match('/dolibarr/', $dolibarr_main_authentication)) { + if (preg_match('/dolibarr/', $dolibarr_main_authentication) || preg_match('/forceuser/', $dolibarr_main_authentication)) { if ($caneditpassword) { $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').''; + if (!empty($conf->use_javascript_ajax)) { + $valuetoshow .= ' '.img_picto((getDolGlobalString('USER_PASSWORD_GENERATED') === 'none' ? $langs->trans('NoPasswordGenerationRuleConfigured') : $langs->trans('Generate')), 'refresh', 'id="generate_password" class="'.(getDolGlobalString('USER_PASSWORD_GENERATED') === 'none' ? ' opacitymedium' : ' linkobject').'"'); + } } else { $valuetoshow .= ($valuetoshow ? (' '.$langs->trans("or").' ') : '').preg_replace('/./i', '*', $object->pass); } } - // Other form for user password $parameters = array('valuetoshow' => $valuetoshow, 'caneditpassword' => $caneditpassword); $reshook = $hookmanager->executeHooks('printUserPasswordField', $parameters, $object, $action); // Note that $action and $object may have been modified by hook diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index c4c0b4e2b92..1186cf7a914 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -35,9 +35,11 @@ * \ingroup core */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; require_once DOL_DOCUMENT_ROOT.'/user/class/usergroup.class.php'; + /** * Class to manage Dolibarr users */ @@ -509,7 +511,7 @@ class User extends CommonObject $this->pass_indatabase_crypted = $obj->pass_crypted; $this->pass = $obj->pass; $this->pass_temp = $obj->pass_temp; - $this->api_key = $obj->api_key; + $this->api_key = dolDecrypt($obj->api_key); $this->address = $obj->address; $this->zip = $obj->zip; @@ -1963,7 +1965,7 @@ class User extends CommonObject $sql .= ", national_registration_number = '".$this->db->escape($this->national_registration_number)."'"; $sql .= ", employee = ".(int) $this->employee; $sql .= ", login = '".$this->db->escape($this->login)."'"; - $sql .= ", api_key = ".($this->api_key ? "'".$this->db->escape($this->api_key)."'" : "null"); + $sql .= ", api_key = ".($this->api_key ? "'".$this->db->escape(dolEncrypt($this->api_key, '', '', 'dolibarr'))."'" : "null"); $sql .= ", gender = ".($this->gender != -1 ? "'".$this->db->escape($this->gender)."'" : "null"); // 'man' or 'woman' $sql .= ", birth=".(strval($this->birth) != '' ? "'".$this->db->idate($this->birth, 'tzserver')."'" : 'null'); if (!empty($user->admin)) { @@ -3867,9 +3869,10 @@ class User extends CommonObject * Return string with full Url to virtual card * * @param string $mode Mode for link + * @param string $typeofurl 'external' or 'internal' * @return string Url string link */ - public function getOnlineVirtualCardUrl($mode = '') + public function getOnlineVirtualCardUrl($mode = '', $typeofurl = 'external') { global $dolibarr_main_instance_unique_id, $dolibarr_main_url_root; global $conf; @@ -3885,6 +3888,10 @@ class User extends CommonObject $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + if ($typeofurl == 'internal') { + $urlwithroot = DOL_URL_ROOT; + } + return $urlwithroot.'/public/users/view.php?id='.$this->id.'&securekey='.$encodedsecurekey.$entity_qr.($mode ? '&mode='.urlencode($mode) : ''); } diff --git a/htdocs/user/list.php b/htdocs/user/list.php index 981c3744028..3ea1307224c 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -1152,10 +1152,13 @@ while ($i < $imaxinloop) { } } if (!empty($arrayfields['u.api_key']['checked'])) { - print ''; - if ($obj->api_key) { + $api_key = dolDecrypt($obj->api_key); + print ''; + if ($api_key) { if ($canreadsecretapi) { - print dol_escape_htmltag($obj->api_key); + print ''; + print showValueWithClipboardCPButton($object->api_key, 1, dol_trunc($api_key, 3)); // TODO Add an option to also reveal the hash, not only copy paste + print ''; } else { print ''.$langs->trans("Hidden").''; } diff --git a/htdocs/user/virtualcard.php b/htdocs/user/virtualcard.php index 252ae3aca80..55d63c3d40a 100644 --- a/htdocs/user/virtualcard.php +++ b/htdocs/user/virtualcard.php @@ -165,7 +165,8 @@ if (getDolUserInt('USER_ENABLE_PUBLIC', 0, $object)) { //print $langs->trans('FollowingLinksArePublic').'
'; print img_picto('', 'globe').' '.$langs->trans('PublicVirtualCardUrl').'
'; - $fullexternaleurltovirtualcard = $object->getOnlineVirtualCardUrl(); + $fullexternaleurltovirtualcard = $object->getOnlineVirtualCardUrl('', 'external'); + $fullinternalurltovirtualcard = $object->getOnlineVirtualCardUrl('', 'internal'); print '