diff --git a/.gitignore b/.gitignore index e9603bd2d8f..3315a7eed88 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ yarn.lock package-lock.json doc/install.lock +/.asciidoctorconfig.adoc 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/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 897f60e8aaa..7e2cdc56543 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -2088,7 +2088,7 @@ class BookKeeping extends CommonObject * FIXME: This function takes the parent of parent to get the root account ! * * @param string $account Accounting account - * @return array Array with root account information (max 2 upper level) + * @return array|int Array with root account information (max 2 upper level), <0 if KO */ public function getRootAccount($account = null) { diff --git a/htdocs/accountancy/class/lettering.class.php b/htdocs/accountancy/class/lettering.class.php index 5749518e2b9..272c067807d 100644 --- a/htdocs/accountancy/class/lettering.class.php +++ b/htdocs/accountancy/class/lettering.class.php @@ -329,6 +329,7 @@ class Lettering extends BookKeeping // Update request $now = dol_now(); + $affected_rows = 0; if (!$error) { $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_bookkeeping SET"; @@ -341,6 +342,8 @@ class Lettering extends BookKeeping if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); + } else { + $affected_rows = $this->db->affected_rows($resql); } } @@ -352,7 +355,7 @@ class Lettering extends BookKeeping } return -1 * $error; } else { - return 1; + return $affected_rows; } } @@ -387,7 +390,7 @@ class Lettering extends BookKeeping } return -1 * $error; } else { - return 1; + return $this->db->affected_rows($resql); } } @@ -482,7 +485,7 @@ class Lettering extends BookKeeping else $result = $this->updateLettering($bookkeeping_lines); if ($result < 0) { $group_error++; - } else { + } elseif ($result > 0) { $nb_lettering++; } } 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/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 544f077f1ea..0137e63406f 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -805,6 +805,12 @@ if (!$error && $action == 'writebookkeeping') { require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; $lettering_static = new Lettering($db); $nb_lettering = $lettering_static->bookkeepingLetteringAll(array($bookkeeping->id)); + + if ($nb_lettering < 0) { + $error++; + $errorforline++; + setEventMessages($lettering_static->error, $lettering_static->errors, 'errors'); + } } } } diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index d00a968571f..12303089dca 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -381,6 +381,12 @@ if ($action == 'writebookkeeping') { require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; $lettering_static = new Lettering($db); $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id)); + + if ($nb_lettering < 0) { + $error++; + $errorforline++; + setEventMessages($lettering_static->error, $lettering_static->errors, 'errors'); + } } } } diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 9eb6688c63b..565a3a59222 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -463,7 +463,15 @@ if ($action == 'writebookkeeping') { if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) { require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php'; $lettering_static = new Lettering($db); + $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id)); + + if ($nb_lettering < 0) { + $error++; + $errorforline++; + $errorforinvoice[$key] = 'other'; + setEventMessages($lettering_static->error, $lettering_static->errors, 'errors'); + } } } } diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 89a1ed2904d..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 = '') @@ -3303,11 +3303,11 @@ class Adherent extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { + global $selected; $return = '
'; $return .= '
'; $return .= ''; - if (property_exists($this, 'photo') || !empty($this->photo)) { $return.= Form::showphoto('memberphoto', $this, 0, 60, 0, 'photokanban photoref photowithmargin photologintooltip', 'small', 0, 1); } else { @@ -3316,6 +3316,7 @@ class Adherent extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'type')) { $return .= '
'.$this->type.''; } diff --git a/htdocs/adherents/class/adherent_type.class.php b/htdocs/adherents/class/adherent_type.class.php index 396dea45b0e..141a2264113 100644 --- a/htdocs/adherents/class/adherent_type.class.php +++ b/htdocs/adherents/class/adherent_type.class.php @@ -991,7 +991,10 @@ class AdherentType extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { - global $langs,$user; + global $langs, $user; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -999,6 +1002,7 @@ class AdherentType extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if ($user->rights->adherent->configurer) { $return .= 'ref.'">'.img_edit().''; } else { diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index c8994283fe1..5f8dbf07249 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -515,6 +515,8 @@ class Subscription extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -523,6 +525,7 @@ class Subscription extends CommonObject $return .= '
'; $return .= ''.(property_exists($this, 'fk_adherent')? $this->fk_adherent: $this->ref ).''; + $return .= ''; if (property_exists($this, 'dateh') || property_exists($this, 'datef')) { $return .= '
'.dol_print_date($this->dateh, 'day').' - '.dol_print_date($this->datef, 'day').''; } diff --git a/htdocs/admin/supplier_invoice.php b/htdocs/admin/supplier_invoice.php index bbb97e293fe..99bbb6d9cb1 100644 --- a/htdocs/admin/supplier_invoice.php +++ b/htdocs/admin/supplier_invoice.php @@ -38,9 +38,11 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; // Load translation files required by the page $langs->loadLangs(array("admin", "other", "orders")); +$action = GETPOST('action', 'aZ09'); + $type = GETPOST('type', 'alpha'); $value = GETPOST('value', 'alpha'); -$action = GETPOST('action', 'aZ09'); +$modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php $label = GETPOST('label', 'alpha'); $scandir = GETPOST('scan_dir', 'alpha'); @@ -98,7 +100,9 @@ if ($action == 'specimen') { // For invoices $facture->thirdparty = $specimenthirdparty; // Define who should has build the invoice (so the supplier) // Search template files - $file = ''; $classname = ''; $filefound = 0; + $file = ''; + $classname = ''; + $filefound = 0; $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); foreach ($dirmodels as $reldir) { $file = dol_buildpath($reldir."core/modules/supplier_invoice/doc/pdf_".$modele.".modules.php", 0); @@ -185,12 +189,12 @@ if ($action == 'set_SUPPLIER_INVOICE_FREE_TEXT') { * View */ +$form = new Form($db); + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); llxHeader("", ""); -$form = new Form($db); - $linkback = ''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans("SuppliersSetup"), $linkback, 'title_setup'); @@ -205,6 +209,7 @@ print dol_get_fiche_head($head, 'invoice', $langs->trans("Suppliers"), -1, 'comp print load_fiche_titre($langs->trans("SuppliersInvoiceNumberingModel"), '', ''); +print '
'; print ''; print ''; print ''; @@ -244,7 +249,7 @@ foreach ($dirmodels as $reldir) { print $module->info(); print ''; - // Show example of numbering model + // Show example of numbering module print '
'.$langs->trans("Name").''; $tmp = $module->getExample(); if (preg_match('/^Error/', $tmp)) { @@ -297,13 +302,13 @@ foreach ($dirmodels as $reldir) { } } -print '

'; +print '

'; /* - * Modeles documents for supplier invoices + * Documents models for supplier invoices */ print load_fiche_titre($langs->trans("BillsPDFModules"), '', ''); @@ -329,6 +334,7 @@ if ($resql) { dol_print_error($db); } +print '
'; print ''."\n"; print ''."\n"; print ''."\n"; @@ -380,7 +386,7 @@ foreach ($dirmodels as $reldir) { //if ($conf->global->INVOICE_SUPPLIER_ADDON_PDF != "$name") //{ // Even if choice is the default value, we allow to disable it: For supplier invoice, we accept to have no doc generation at all - print 'scandir).'&label='.urlencode($module->name).'&type=invoice_supplier">'; + print 'scandir).'&label='.urlencode($module->name).'&type=invoice_supplier">'; print img_picto($langs->trans("Enabled"), 'switch_on'); print ''; /*} @@ -391,7 +397,7 @@ foreach ($dirmodels as $reldir) { print ""; } else { print '"; } @@ -400,9 +406,9 @@ foreach ($dirmodels as $reldir) { if (getDolGlobalString("INVOICE_SUPPLIER_ADDON_PDF") == "$name") { //print img_picto($langs->trans("Default"),'on'); // Even if choice is the default value, we allow to disable it: For supplier invoice, we accept to have no doc generation at all - print 'scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; + print 'scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Disable").'">'.img_picto($langs->trans("Enabled"), 'on').''; } else { - print 'scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; + print 'scandir.'&label='.urlencode($module->name).'&type=invoice_supplier"" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"), 'off').''; } print ''; @@ -420,7 +426,7 @@ foreach ($dirmodels as $reldir) { print $form->textwithpicto('', $htmltooltip, 1, 0); print ''; print ''; print "\n"; @@ -432,7 +438,7 @@ foreach ($dirmodels as $reldir) { } } -print '
'.$langs->trans("Name").''."\n"; - print 'scandir).'&label='.urlencode($module->name).'&type=invoice_supplier">'.img_picto($langs->trans("Disabled"), 'switch_off').''; + print 'scandir).'&label='.urlencode($module->name).'&type=invoice_supplier">'.img_picto($langs->trans("Disabled"), 'switch_off').''; print "'; - print ''.img_object($langs->trans("Preview"), 'pdf').''; + print ''.img_object($langs->trans("Preview"), 'pdf').''; print '

'; +print '

'; /* * Other options @@ -443,6 +449,8 @@ print ''; print ''; print load_fiche_titre($langs->trans("OtherOptions"), '', ''); + +print '
'; print ''; print ''; print ''; @@ -472,7 +480,7 @@ print '\n"; -print '
'.$langs->trans("Parameter").''; print ''; print "

'; +print '

'; print ''; @@ -482,6 +490,8 @@ print ''; */ print load_fiche_titre($langs->trans("Notifications"), '', ''); + +print '
'; print ''; print ''; print ''; @@ -495,6 +505,7 @@ print '\n"; print '
'.$langs->trans("Parameter").''; print "
'; +print '
'; // End of page llxFooter(); diff --git a/htdocs/admin/supplier_order.php b/htdocs/admin/supplier_order.php index abee8200cef..171ad4035a9 100644 --- a/htdocs/admin/supplier_order.php +++ b/htdocs/admin/supplier_order.php @@ -38,25 +38,28 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; // Load translation files required by the page $langs->loadLangs(array("admin", "other", "orders", "stocks")); -if (!$user->admin) { - accessforbidden(); -} +$action = GETPOST('action', 'aZ09'); $type = GETPOST('type', 'alpha'); $value = GETPOST('value', 'alpha'); $modulepart = GETPOST('modulepart', 'aZ09'); // Used by actions_setmoduleoptions.inc.php $label = GETPOST('label', 'alpha'); -$action = GETPOST('action', 'aZ09'); $scandir = GETPOST('scan_dir', 'alpha'); $specimenthirdparty = new Societe($db); $specimenthirdparty->initAsSpecimen(); +$error = 0; + +if (!$user->admin) { + accessforbidden(); +} + /* -* Actions -*/ + * Actions + */ include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php'; @@ -77,7 +80,9 @@ if ($action == 'updateMask') { } else { setEventMessages($langs->trans("Error"), null, 'errors'); } -} elseif ($action == 'specimen') { // For orders +} + +if ($action == 'specimen') { // For orders $modele = GETPOST('module', 'alpha'); $commande = new CommandeFournisseur($db); @@ -317,8 +322,8 @@ print '

'; /* -* Documents models for supplier orders -*/ + * Documents models for supplier orders + */ print load_fiche_titre($langs->trans("OrdersModelModule"), '', ''); 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/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php index 361ac64928e..c00b9781756 100644 --- a/htdocs/bom/class/bom.class.php +++ b/htdocs/bom/class/bom.class.php @@ -1567,6 +1567,9 @@ class BOM extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $db,$langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $prod = new Product($db); $prod->fetch($this->fk_product); @@ -1577,6 +1580,7 @@ class BOM extends CommonObject $return .= '
'; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : '').''; + $return .= ''; if (property_exists($this, 'fields') && !empty($this->fields['bomtype']['arrayofkeyval'])) { $return .= '
'.$langs->trans("Type").' : '; if ($this->bomtype == 0) { 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 5833072e8be..e65a1b5e1a3 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1809,7 +1809,7 @@ if ($action == 'create') { print img_picto('', 'company', 'class="pictofixedwidth"').$form->select_company('', 'socid', '((s.client = 1 OR s.client = 2 OR s.client = 3) AND status=1)', 'SelectThirdParty', 1, 0, null, 0, 'minwidth300 maxwidth500 widthcentpercentminusxx'); // reload page to retrieve customer informations if (empty($conf->global->RELOAD_PAGE_ON_CUSTOMER_CHANGE_DISABLED)) { - print ''; + $result .= ''; } return $result; @@ -467,15 +467,15 @@ class Form /** * Output edit in place form * - * @param object $object Object - * @param string $value Value to show/edit - * @param string $htmlname DIV ID (field name) - * @param int $condition Condition to edit - * @param string $inputType Type of input ('string', 'numeric', 'datepicker' ('day' do not work, don't know why), 'textarea:rows:cols', 'ckeditor:dolibarr_zzz:width:height:?:1:rows:cols', 'select:loadmethod:savemethod:buttononly') - * @param string $editvalue When in edit mode, use this value as $value instead of value - * @param object $extObject External object - * @param mixed $custommsg String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage') - * @return string HTML edit in place + * @param object $object Object + * @param string $value Value to show/edit + * @param string $htmlname DIV ID (field name) + * @param int $condition Condition to edit + * @param string $inputType Type of input ('string', 'numeric', 'datepicker' ('day' do not work, don't know why), 'textarea:rows:cols', 'ckeditor:dolibarr_zzz:width:height:?:1:rows:cols', 'select:loadmethod:savemethod:buttononly') + * @param string $editvalue When in edit mode, use this value as $value instead of value + * @param object $extObject External object + * @param mixed $custommsg String or Array of custom messages : eg array('success' => 'MyMessage', 'error' => 'MyMessage') + * @return string HTML edit in place */ protected function editInPlace($object, $value, $htmlname, $condition, $inputType = 'textarea', $editvalue = null, $extObject = null, $custommsg = null) { @@ -495,11 +495,11 @@ class Form if ($condition) { $element = false; $table_element = false; - $fk_element = false; - $loadmethod = false; - $savemethod = false; - $ext_element = false; - $button_only = false; + $fk_element = false; + $loadmethod = false; + $savemethod = false; + $ext_element = false; + $button_only = false; $inputOption = ''; $rows = ''; $cols = ''; @@ -523,7 +523,7 @@ class Form if (!empty($tmp[2])) { $savemethod = $tmp[2]; } - $out .= ''."\n"; + $out .= '' . "\n"; } elseif ((preg_match('/^day$/', $inputType)) || (preg_match('/^datepicker/', $inputType)) || (preg_match('/^datehourpicker/', $inputType))) { $tmp = explode(':', $inputType); $inputType = $tmp[0]; @@ -534,7 +534,7 @@ class Form $savemethod = $tmp[2]; } - $out .= ''."\n"; // Use for timestamp format + $out .= '' . "\n"; // Use for timestamp format } elseif (preg_match('/^(select|autocomplete)/', $inputType)) { $tmp = explode(':', $inputType); $inputType = $tmp[0]; @@ -565,40 +565,40 @@ class Form } if (isModEnabled('fckeditor')) { - $out .= ''."\n"; + $out .= '' . "\n"; } else { $inputType = 'textarea'; } } - $out .= ''."\n"; - $out .= ''."\n"; - $out .= ''."\n"; - $out .= ''."\n"; + $out .= '' . "\n"; + $out .= '' . "\n"; + $out .= '' . "\n"; + $out .= '' . "\n"; if (!empty($savemethod)) { - $out .= ''."\n"; + $out .= '' . "\n"; } if (!empty($ext_element)) { - $out .= ''."\n"; + $out .= '' . "\n"; } if (!empty($custommsg)) { if (is_array($custommsg)) { if (!empty($custommsg['success'])) { - $out .= ''."\n"; + $out .= '' . "\n"; } if (!empty($custommsg['error'])) { - $out .= ''."\n"; + $out .= '' . "\n"; } } else { - $out .= ''."\n"; + $out .= '' . "\n"; } } if ($inputType == 'textarea') { - $out .= ''."\n"; - $out .= ''."\n"; + $out .= '' . "\n"; + $out .= '' . "\n"; } - $out .= ''.$value.''."\n"; - $out .= ''.(!empty($editvalue) ? $editvalue : $value).''."\n"; + $out .= '' . $value . '' . "\n"; + $out .= '' . (!empty($editvalue) ? $editvalue : $value) . '' . "\n"; } else { $out = $value; } @@ -607,32 +607,32 @@ class Form } /** - * Show a text and picto with tooltip on text or picto. + * Show a text and picto with tooltip on text or picto. * Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip * - * @param string $text Text to show - * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. - * @param int $tooltipon 1=tooltip on text, 2=tooltip on image, 3=tooltip sur les 2 - * @param int $direction -1=image is before, 0=no image, 1=image is after - * @param string $img Html code for image (use img_xxx() function to get it) - * @param string $extracss Add a CSS style to td tags - * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span - * @param string $incbefore Include code before the text - * @param int $noencodehtmltext Do not encode into html entity the htmltext - * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) - * @param int $forcenowrap Force no wrap between text and picto (works with notabs=2 only) - * @return string Code html du tooltip (texte+picto) - * @see textwithpicto() Use thisfunction if you can. + * @param string $text Text to show + * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. + * @param int $tooltipon 1=tooltip on text, 2=tooltip on image, 3=tooltip sur les 2 + * @param int $direction -1=image is before, 0=no image, 1=image is after + * @param string $img Html code for image (use img_xxx() function to get it) + * @param string $extracss Add a CSS style to td tags + * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span + * @param string $incbefore Include code before the text + * @param int $noencodehtmltext Do not encode into html entity the htmltext + * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) + * @param int $forcenowrap Force no wrap between text and picto (works with notabs=2 only) + * @return string Code html du tooltip (texte+picto) + * @see textwithpicto() Use thisfunction if you can. */ public function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 3, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger = '', $forcenowrap = 0) { if ($incbefore) { - $text = $incbefore.$text; + $text = $incbefore . $text; } if (!$htmltext) { return $text; } - $direction = (int) $direction; // For backward compatibility when $direction was set to '' instead of 0 + $direction = (int) $direction; // For backward compatibility when $direction was set to '' instead of 0 $tag = 'td'; if ($notabs == 2) { @@ -646,11 +646,11 @@ class Form $extrastyle = ''; if ($direction < 0) { - $extracss = ($extracss ? $extracss.' ' : '').($notabs != 3 ? 'inline-block' : ''); + $extracss = ($extracss ? $extracss . ' ' : '') . ($notabs != 3 ? 'inline-block' : ''); $extrastyle = 'padding: 0px; padding-left: 3px;'; } if ($direction > 0) { - $extracss = ($extracss ? $extracss.' ' : '').($notabs != 3 ? 'inline-block' : ''); + $extracss = ($extracss ? $extracss . ' ' : '') . ($notabs != 3 ? 'inline-block' : ''); $extrastyle = 'padding: 0px; padding-right: 3px;'; } @@ -663,53 +663,53 @@ class Form $htmltext = str_replace('"', '"', $htmltext); } else { $classfortooltip = 'classfortooltiponclick'; - $textfordialog .= ''; + $textfordialog .= ''; } if ($tooltipon == 2 || $tooltipon == 3) { - $paramfortooltipimg = ' class="'.$classfortooltip.($notabs != 3 ? ' inline-block' : '').($extracss ? ' '.$extracss : '').'" style="padding: 0px;'.($extrastyle ? ' '.$extrastyle : '').'"'; + $paramfortooltipimg = ' class="' . $classfortooltip . ($notabs != 3 ? ' inline-block' : '') . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '"'; if ($tooltiptrigger == '') { - $paramfortooltipimg .= ' title="'.($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)).'"'; // Attribut to put on img tag to store tooltip + $paramfortooltipimg .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribut to put on img tag to store tooltip } else { - $paramfortooltipimg .= ' dolid="'.$tooltiptrigger.'"'; + $paramfortooltipimg .= ' dolid="' . $tooltiptrigger . '"'; } } else { - $paramfortooltipimg = ($extracss ? ' class="'.$extracss.'"' : '').($extrastyle ? ' style="'.$extrastyle.'"' : ''); // Attribut to put on td text tag + $paramfortooltipimg = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribut to put on td text tag } if ($tooltipon == 1 || $tooltipon == 3) { - $paramfortooltiptd = ' class="'.($tooltipon == 3 ? 'cursorpointer ' : '').$classfortooltip.' inline-block'.($extracss ? ' '.$extracss : '').'" style="padding: 0px;'.($extrastyle ? ' '.$extrastyle : '').'" '; + $paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ' inline-block' . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" '; if ($tooltiptrigger == '') { - $paramfortooltiptd .= ' title="'.($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)).'"'; // Attribut to put on td tag to store tooltip + $paramfortooltiptd .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribut to put on td tag to store tooltip } else { - $paramfortooltiptd .= ' dolid="'.$tooltiptrigger.'"'; + $paramfortooltiptd .= ' dolid="' . $tooltiptrigger . '"'; } } else { - $paramfortooltiptd = ($extracss ? ' class="'.$extracss.'"' : '').($extrastyle ? ' style="'.$extrastyle.'"' : ''); // Attribut to put on td text tag + $paramfortooltiptd = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribut to put on td text tag } if (empty($notabs)) { $s .= ''; } elseif ($notabs == 2) { - $s .= '
'; + $s .= '
'; } // Define value if value is before if ($direction < 0) { - $s .= '<'.$tag.$paramfortooltipimg; + $s .= '<' . $tag . $paramfortooltipimg; if ($tag == 'td') { $s .= ' class="valigntop" width="14"'; } - $s .= '>'.$textfordialog.$img.''; + $s .= '>' . $textfordialog . $img . ''; } // Use another method to help avoid having a space in value in order to use this value with jquery // Define label if ((string) $text != '') { - $s .= '<'.$tag.$paramfortooltiptd.'>'.$text.''; + $s .= '<' . $tag . $paramfortooltiptd . '>' . $text . ''; } // Define value if value is after if ($direction > 0) { - $s .= '<'.$tag.$paramfortooltipimg; + $s .= '<' . $tag . $paramfortooltipimg; if ($tag == 'td') { $s .= ' class="valignmiddle" width="14"'; } - $s .= '>'.$textfordialog.$img.''; + $s .= '>' . $textfordialog . $img . ''; } if (empty($notabs)) { $s .= '
'; @@ -721,18 +721,18 @@ class Form } /** - * Show a text with a picto and a tooltip on picto + * Show a text with a picto and a tooltip on picto * - * @param string $text Text to show - * @param string $htmltext Content of tooltip - * @param int $direction 1=Icon is after text, -1=Icon is before text, 0=no icon - * @param string $type Type of picto ('info', 'infoclickable', 'help', 'helpclickable', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath or 'none' - * @param string $extracss Add a CSS style to td, div or span tag - * @param int $noencodehtmltext Do not encode into html entity the htmltext - * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span - * @param string $tooltiptrigger ''=Tooltip on hover and hidden on smartphone, 'abconsmartphone'=Tooltip on hover and on click on smartphone, 'abc'=Tooltip on click (abc is a unique key, clickable link is on image or on link if param $type='none' or on both if $type='xxxclickable') - * @param int $forcenowrap Force no wrap between text and picto (works with notabs=2 only) - * @return string HTML code of text, picto, tooltip + * @param string $text Text to show + * @param string $htmltext Content of tooltip + * @param int $direction 1=Icon is after text, -1=Icon is before text, 0=no icon + * @param string $type Type of picto ('info', 'infoclickable', 'help', 'helpclickable', 'warning', 'superadmin', 'mypicto@mymodule', ...) or image filepath or 'none' + * @param string $extracss Add a CSS style to td, div or span tag + * @param int $noencodehtmltext Do not encode into html entity the htmltext + * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span + * @param string $tooltiptrigger ''=Tooltip on hover and hidden on smartphone, 'abconsmartphone'=Tooltip on hover and on click on smartphone, 'abc'=Tooltip on click (abc is a unique key, clickable link is on image or on link if param $type='none' or on both if $type='xxxclickable') + * @param int $forcenowrap Force no wrap between text and picto (works with notabs=2 only) + * @return string HTML code of text, picto, tooltip */ public function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 3, $tooltiptrigger = '', $forcenowrap = 0) { @@ -799,12 +799,12 @@ class Form /** * Generate select HTML to choose massaction * - * @param string $selected Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default. - * @param array $arrayofaction array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action. - * @param int $alwaysvisible 1=select button always visible - * @param string $name Name for massaction - * @param string $cssclass CSS class used to check for select - * @return string|void Select list + * @param string $selected Value auto selected when at least one record is selected. Not a preselected value. Use '0' by default. + * @param array $arrayofaction array('code'=>'label', ...). The code is the key stored into the GETPOST('massaction') when submitting action. + * @param int $alwaysvisible 1=select button always visible + * @param string $name Name for massaction + * @param string $cssclass CSS class used to check for select + * @return string|void Select list */ public function selectMassAction($selected, $arrayofaction, $alwaysvisible = 0, $name = 'massaction', $cssclass = 'checkforselect') { @@ -813,7 +813,7 @@ class Form $disabled = 0; $ret = '
'; - $ret .= ''; // Complete list with data from external modules. THe module can use $_SERVER['PHP_SELF'] to know on which page we are, or use the $parameters['currentcontext'] completed by executeHooks. $parameters = array(); @@ -823,9 +823,9 @@ class Form return; } if (empty($reshook)) { - $ret .= ''; + $ret .= ''; foreach ($arrayofaction as $code => $label) { - $ret .= ''; + $ret .= ''; } } $ret .= $hookmanager->resPrint; @@ -833,17 +833,17 @@ class Form $ret .= ''; if (empty($conf->dol_optimize_smallscreen)) { - $ret .= ajax_combobox('.'.$name.'select'); + $ret .= ajax_combobox('.' . $name . 'select'); } // Warning: if you set submit button to disabled, post using 'Enter' will no more work if there is no another input submit. So we add a hidden button $ret .= ''; // Hidden button BEFORE so it is the one used when we submit with ENTER. - $ret .= 'use_javascript_ajax) ? '' : ' style="display: none"').' class="button smallpaddingimp'.(empty($conf->use_javascript_ajax) ? '' : ' hideobject').' '.$name.' '.$name.'confirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">'; + $ret .= 'use_javascript_ajax) ? '' : ' style="display: none"') . ' class="button smallpaddingimp' . (empty($conf->use_javascript_ajax) ? '' : ' hideobject') . ' ' . $name . ' ' . $name . 'confirmed" value="' . dol_escape_htmltag($langs->trans("Confirm")) . '">'; $ret .= '
'; if (!empty($conf->use_javascript_ajax)) { $ret .= ' - '; $out .= $this->select_dolusers('', $htmlname, $show_empty, $exclude, $disabled, $include, $enableonly, $force_entity, $maxlength, $showstatus, $morefilter); - $out .= ' '; + $out .= ' '; $out .= '
'; } @@ -2288,32 +2302,33 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Return list of products for customer in Ajax if Ajax activated or go to select_produits_list * - * @param int $selected Preselected products - * @param string $htmlname Name of HTML select field (must be unique in page). - * @param int|string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) - * @param int $limit Limit on number of returned lines - * @param int $price_level Level of price to show - * @param int $status Sell status -1=Return all products, 0=Products not on sell, 1=Products on sell - * @param int $finished 2=all, 1=finished, 0=raw material - * @param string $selected_input_value Value of preselected input text (for use with ajax) - * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) - * @param array $ajaxoptions Options for ajax_autocompleter - * @param int $socid Thirdparty Id (to get also price dedicated to this customer) - * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. - * @param int $forcecombo Force to use combo box - * @param string $morecss Add more css on select - * @param int $hidepriceinlabel 1=Hide prices in label - * @param string $warehouseStatus Warehouse status filter to count the quantity in stock. Following comma separated filter options can be used - * 'warehouseopen' = count products from open warehouses, - * 'warehouseclosed' = count products from closed warehouses, - * 'warehouseinternal' = count products from warehouses for internal correct/transfer only - * @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...]) - * @param string $nooutput No print, return the output into a string - * @param int $status_purchase Purchase status -1=Return all products, 0=Products not on purchase, 1=Products on purchase - * @return void|string + * @param int $selected Preselected products + * @param string $htmlname Name of HTML select field (must be unique in page). + * @param int|string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param int $limit Limit on number of returned lines + * @param int $price_level Level of price to show + * @param int $status Sell status -1=Return all products, 0=Products not on sell, 1=Products on sell + * @param int $finished 2=all, 1=finished, 0=raw material + * @param string $selected_input_value Value of preselected input text (for use with ajax) + * @param int $hidelabel Hide label (0=no, 1=yes, 2=show search icon (before) and placeholder, 3 search icon after) + * @param array $ajaxoptions Options for ajax_autocompleter + * @param int $socid Thirdparty Id (to get also price dedicated to this customer) + * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. + * @param int $forcecombo Force to use combo box + * @param string $morecss Add more css on select + * @param int $hidepriceinlabel 1=Hide prices in label + * @param string $warehouseStatus Warehouse status filter to count the quantity in stock. Following comma separated filter options can be used + * 'warehouseopen' = count products from open warehouses, + * 'warehouseclosed' = count products from closed warehouses, + * 'warehouseinternal' = count products from warehouses for internal correct/transfer only + * @param array $selected_combinations Selected combinations. Format: array([attrid] => attrval, [...]) + * @param string $nooutput No print, return the output into a string + * @param int $status_purchase Purchase status -1=Return all products, 0=Products not on purchase, 1=Products on purchase + * @return void|string */ public function select_produits($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 0, $price_level = 0, $status = 1, $finished = 2, $selected_input_value = '', $hidelabel = 0, $ajaxoptions = array(), $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $hidepriceinlabel = 0, $warehouseStatus = '', $selected_combinations = null, $nooutput = 0, $status_purchase = -1) { @@ -2340,7 +2355,7 @@ class Form $placeholder = ''; if ($selected && empty($selected_input_value)) { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $producttmpselect = new Product($this->db); $producttmpselect->fetch($selected); $selected_input_value = $producttmpselect->ref; @@ -2355,17 +2370,17 @@ class Form } } // mode=1 means customers products - $urloption = ($socid > 0 ? 'socid='.$socid.'&' : '').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=1&status='.$status.'&status_purchase='.$status_purchase.'&finished='.$finished.'&hidepriceinlabel='.$hidepriceinlabel.'&warehousestatus='.$warehouseStatus; - $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 1, $ajaxoptions); + $urloption = ($socid > 0 ? 'socid=' . $socid . '&' : '') . 'htmlname=' . $htmlname . '&outjson=1&price_level=' . $price_level . '&type=' . $filtertype . '&mode=1&status=' . $status . '&status_purchase=' . $status_purchase . '&finished=' . $finished . '&hidepriceinlabel=' . $hidepriceinlabel . '&warehousestatus=' . $warehouseStatus; + $out .= ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 1, $ajaxoptions); if (isModEnabled('variants') && is_array($selected_combinations)) { // Code to automatically insert with javascript the select of attributes under the select of product // when a parent of variant has been selected. $out .= ' - '; } if (empty($hidelabel)) { - $out .= $langs->trans("RefOrLabel").' : '; + $out .= $langs->trans("RefOrLabel") . ' : '; } elseif ($hidelabel > 1) { - $placeholder = ' placeholder="'.$langs->trans("RefOrLabel").'"'; + $placeholder = ' placeholder="' . $langs->trans("RefOrLabel") . '"'; if ($hidelabel == 2) { $out .= img_picto($langs->trans("Search"), 'search'); } } - $out .= 'global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '').' />'; + $out .= 'global->PRODUCT_SEARCH_AUTOFOCUS) ? 'autofocus' : '') . ' />'; if ($hidelabel == 3) { $out .= img_picto($langs->trans("Search"), 'search'); } @@ -2471,7 +2486,7 @@ class Form * @param string $morecss Add more css on select * @param string $nooutput No print, return the output into a string * @param int $forcecombo Force to use combo box - * @param array $TProducts Add filter on a defined product + * @param array $TProducts Add filter on a defined product * @return void|string */ public function select_bom($selected = '', $htmlname = 'bom_id', $limit = 0, $status = 1, $type = 0, $showempty = '1', $morecss = '', $nooutput = '', $forcecombo = 0, $TProducts = []) @@ -2479,29 +2494,29 @@ class Form // phpcs:enable global $conf, $user, $langs, $db; - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $error = 0; $out = ''; if (!$forcecombo) { - include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $events = array(); $out .= ajax_combobox($htmlname, $events, getDolGlobalInt("PRODUIT_USE_SEARCH_TO_SELECT")); } - $out .= ''; $sql = 'SELECT b.rowid, b.ref, b.label, b.fk_product'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'bom_bom as b'; - $sql.= ' WHERE b.entity IN ('.getEntity('bom').')'; - if (!empty($status)) $sql.= ' AND status = '. (int) $status; - if (!empty($type)) $sql.= ' AND bomtype = '. (int) $type; - if (!empty($TProducts)) $sql .= ' AND fk_product IN ('.$this->db->sanitize(implode(',', $TProducts)).')'; - if (!empty($limit)) $sql.= ' LIMIT '. (int) $limit; + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'bom_bom as b'; + $sql .= ' WHERE b.entity IN (' . getEntity('bom') . ')'; + if (!empty($status)) $sql .= ' AND status = ' . (int) $status; + if (!empty($type)) $sql .= ' AND bomtype = ' . (int) $type; + if (!empty($TProducts)) $sql .= ' AND fk_product IN (' . $this->db->sanitize(implode(',', $TProducts)) . ')'; + if (!empty($limit)) $sql .= ' LIMIT ' . (int) $limit; $resql = $db->query($sql); if ($resql) { - if ($showempty) { + if ($showempty) { $out .= ''; + $out .= '>' . $obj->ref . ' - ' . $product->label . ' - ' . $obj->label . ''; } } else { $error++; @@ -2525,30 +2540,31 @@ class Form } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** - * Return list of products for a customer. + * Return list of products for a customer. * Called by select_produits. * - * @param int $selected Preselected product - * @param string $htmlname Name of select html - * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) - * @param int $limit Limit on number of returned lines - * @param int $price_level Level of price to show - * @param string $filterkey Filter on product - * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell - * @param int $finished Filter on finished field: 2=No filter - * @param int $outputmode 0=HTML select string, 1=Array - * @param int $socid Thirdparty Id (to get also price dedicated to this customer) - * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. - * @param int $forcecombo Force to use combo box - * @param string $morecss Add more css on select - * @param int $hidepriceinlabel 1=Hide prices in label - * @param string $warehouseStatus Warehouse status filter to group/count stock. Following comma separated filter options can be used. - * 'warehouseopen' = count products from open warehouses, - * 'warehouseclosed' = count products from closed warehouses, - * 'warehouseinternal' = count products from warehouses for internal correct/transfer only - * @param int $status_purchase Purchase status -1=Return all products, 0=Products not on purchase, 1=Products on purchase - * @return array|string Array of keys for json + * @param int $selected Preselected product + * @param string $htmlname Name of select html + * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param int $limit Limit on number of returned lines + * @param int $price_level Level of price to show + * @param string $filterkey Filter on product + * @param int $status -1=Return all products, 0=Products not on sell, 1=Products on sell + * @param int $finished Filter on finished field: 2=No filter + * @param int $outputmode 0=HTML select string, 1=Array + * @param int $socid Thirdparty Id (to get also price dedicated to this customer) + * @param string $showempty '' to not show empty line. Translation key to show an empty line. '1' show empty line with no text. + * @param int $forcecombo Force to use combo box + * @param string $morecss Add more css on select + * @param int $hidepriceinlabel 1=Hide prices in label + * @param string $warehouseStatus Warehouse status filter to group/count stock. Following comma separated filter options can be used. + * 'warehouseopen' = count products from open warehouses, + * 'warehouseclosed' = count products from closed warehouses, + * 'warehouseinternal' = count products from warehouses for internal correct/transfer only + * @param int $status_purchase Purchase status -1=Return all products, 0=Products not on purchase, 1=Products on purchase + * @return array|string Array of keys for json */ public function select_produits_list($selected = '', $htmlname = 'productid', $filtertype = '', $limit = 20, $price_level = 0, $filterkey = '', $status = 1, $finished = 2, $outputmode = 0, $socid = 0, $showempty = '1', $forcecombo = 0, $morecss = '', $hidepriceinlabel = 0, $warehouseStatus = '', $status_purchase = -1) { @@ -2566,7 +2582,7 @@ class Form $warehouseStatusArray = array(); if (!empty($warehouseStatus)) { - require_once DOL_DOCUMENT_ROOT.'/product/stock/class/entrepot.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/stock/class/entrepot.class.php'; if (preg_match('/warehouseclosed/', $warehouseStatus)) { $warehouseStatusArray[] = Entrepot::STATUS_CLOSED; } @@ -2580,22 +2596,28 @@ class Form $selectFields = " p.rowid, p.ref, p.label, p.description, p.barcode, p.fk_country, p.fk_product_type, p.price, p.price_ttc, p.price_base_type, p.tva_tx, p.default_vat_code, p.duration, p.fk_price_expression"; if (count($warehouseStatusArray)) { - $selectFieldsGrouped = ", sum(".$this->db->ifsql("e.statut IS NULL", "0", "ps.reel").") as stock"; // e.statut is null if there is no record in stock + $selectFieldsGrouped = ", sum(" . $this->db->ifsql("e.statut IS NULL", "0", "ps.reel") . ") as stock"; // e.statut is null if there is no record in stock } else { - $selectFieldsGrouped = ", ".$this->db->ifsql("p.stock IS NULL", 0, "p.stock")." AS stock"; + $selectFieldsGrouped = ", " . $this->db->ifsql("p.stock IS NULL", 0, "p.stock") . " AS stock"; } $sql = "SELECT "; + + // Add select from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('selectProductsListSelect', $parameters); // Note that $action and $object may have been modified by hook - $sql .= $selectFields.$selectFieldsGrouped.$hookmanager->resPrint; + if ($reshook > 0) { + $sql .= $selectFields.$selectFieldsGrouped.$hookmanager->resPrint; + } else { + $sql .= $hookmanager->resPrint; + } if (!empty($conf->global->PRODUCT_SORT_BY_CATEGORY)) { //Product category - $sql .= ", (SELECT ".$this->db->prefix()."categorie_product.fk_categorie - FROM ".$this->db->prefix()."categorie_product - WHERE ".$this->db->prefix()."categorie_product.fk_product=p.rowid + $sql .= ", (SELECT " . $this->db->prefix() . "categorie_product.fk_categorie + FROM " . $this->db->prefix() . "categorie_product + WHERE " . $this->db->prefix() . "categorie_product.fk_product=p.rowid LIMIT 1 ) AS categorie_product_id "; } @@ -2621,87 +2643,89 @@ class Form } // Price by quantity if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { - $sql .= ", (SELECT pp.rowid FROM ".$this->db->prefix()."product_price as pp WHERE pp.fk_product = p.rowid"; + $sql .= ", (SELECT pp.rowid FROM " . $this->db->prefix() . "product_price as pp WHERE pp.fk_product = p.rowid"; if ($price_level >= 1 && !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { - $sql .= " AND price_level = ".((int) $price_level); + $sql .= " AND price_level = " . ((int) $price_level); } $sql .= " ORDER BY date_price"; $sql .= " DESC LIMIT 1) as price_rowid"; - $sql .= ", (SELECT pp.price_by_qty FROM ".$this->db->prefix()."product_price as pp WHERE pp.fk_product = p.rowid"; // price_by_qty is 1 if some prices by qty exists in subtable + $sql .= ", (SELECT pp.price_by_qty FROM " . $this->db->prefix() . "product_price as pp WHERE pp.fk_product = p.rowid"; // price_by_qty is 1 if some prices by qty exists in subtable if ($price_level >= 1 && !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) { - $sql .= " AND price_level = ".((int) $price_level); + $sql .= " AND price_level = " . ((int) $price_level); } $sql .= " ORDER BY date_price"; $sql .= " DESC LIMIT 1) as price_by_qty"; $selectFields .= ", price_rowid, price_by_qty"; } + $sql .= " FROM ".$this->db->prefix()."product as p"; // Add from (left join) from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('selectProductsListFrom', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; + if (count($warehouseStatusArray)) { - $sql .= " LEFT JOIN ".$this->db->prefix()."product_stock as ps on ps.fk_product = p.rowid"; - $sql .= " LEFT JOIN ".$this->db->prefix()."entrepot as e on ps.fk_entrepot = e.rowid AND e.entity IN (".getEntity('stock').")"; - $sql .= ' AND e.statut IN ('.$this->db->sanitize($this->db->escape(implode(',', $warehouseStatusArray))).')'; // Return line if product is inside the selected stock. If not, an empty line will be returned so we will count 0. + $sql .= " LEFT JOIN " . $this->db->prefix() . "product_stock as ps on ps.fk_product = p.rowid"; + $sql .= " LEFT JOIN " . $this->db->prefix() . "entrepot as e on ps.fk_entrepot = e.rowid AND e.entity IN (" . getEntity('stock') . ")"; + $sql .= ' AND e.statut IN (' . $this->db->sanitize($this->db->escape(implode(',', $warehouseStatusArray))) . ')'; // Return line if product is inside the selected stock. If not, an empty line will be returned so we will count 0. } // include search in supplier ref if (!empty($conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF)) { - $sql .= " LEFT JOIN ".$this->db->prefix()."product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; + $sql .= " LEFT JOIN " . $this->db->prefix() . "product_fournisseur_price as pfp ON p.rowid = pfp.fk_product"; } //Price by customer if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { - $sql .= " LEFT JOIN ".$this->db->prefix()."product_customer_price as pcp ON pcp.fk_soc=".((int) $socid)." AND pcp.fk_product=p.rowid"; + $sql .= " LEFT JOIN " . $this->db->prefix() . "product_customer_price as pcp ON pcp.fk_soc=" . ((int) $socid) . " AND pcp.fk_product=p.rowid"; } // Units if (getDolGlobalInt('PRODUCT_USE_UNITS')) { - $sql .= " LEFT JOIN ".$this->db->prefix()."c_units u ON u.rowid = p.fk_unit"; + $sql .= " LEFT JOIN " . $this->db->prefix() . "c_units u ON u.rowid = p.fk_unit"; } // Multilang : we add translation if (getDolGlobalInt('MAIN_MULTILANGS')) { - $sql .= " LEFT JOIN ".$this->db->prefix()."product_lang as pl ON pl.fk_product = p.rowid "; + $sql .= " LEFT JOIN " . $this->db->prefix() . "product_lang as pl ON pl.fk_product = p.rowid "; if (!empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE) && !empty($socid)) { - require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; $soc = new Societe($this->db); $result = $soc->fetch($socid); if ($result > 0 && !empty($soc->default_lang)) { - $sql .= " AND pl.lang = '".$this->db->escape($soc->default_lang)."'"; + $sql .= " AND pl.lang = '" . $this->db->escape($soc->default_lang) . "'"; } else { - $sql .= " AND pl.lang = '".$this->db->escape($langs->getDefaultLang())."'"; + $sql .= " AND pl.lang = '" . $this->db->escape($langs->getDefaultLang()) . "'"; } } else { - $sql .= " AND pl.lang = '".$this->db->escape($langs->getDefaultLang())."'"; + $sql .= " AND pl.lang = '" . $this->db->escape($langs->getDefaultLang()) . "'"; } } if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { - $sql .= " LEFT JOIN ".$this->db->prefix()."product_attribute_combination pac ON pac.fk_product_child = p.rowid"; + $sql .= " LEFT JOIN " . $this->db->prefix() . "product_attribute_combination pac ON pac.fk_product_child = p.rowid"; } - $sql .= ' WHERE p.entity IN ('.getEntity('product').')'; + $sql .= ' WHERE p.entity IN (' . getEntity('product') . ')'; if (!empty($conf->global->PRODUIT_ATTRIBUTES_HIDECHILD)) { $sql .= " AND pac.rowid IS NULL"; } if ($finished == 0) { - $sql .= " AND p.finished = ".((int) $finished); + $sql .= " AND p.finished = " . ((int) $finished); } elseif ($finished == 1) { - $sql .= " AND p.finished = ".((int) $finished); + $sql .= " AND p.finished = " . ((int) $finished); if ($status >= 0) { - $sql .= " AND p.tosell = ".((int) $status); + $sql .= " AND p.tosell = " . ((int) $status); } } elseif ($status >= 0) { - $sql .= " AND p.tosell = ".((int) $status); + $sql .= " AND p.tosell = " . ((int) $status); } if ($status_purchase >= 0) { - $sql .= " AND p.tobuy = ".((int) $status_purchase); + $sql .= " AND p.tobuy = " . ((int) $status_purchase); } // Filter by product type if (strval($filtertype) != '') { - $sql .= " AND p.fk_product_type = ".((int) $filtertype); + $sql .= " AND p.fk_product_type = " . ((int) $filtertype); } elseif (!isModEnabled('product')) { // when product module is disabled, show services only $sql .= " AND p.fk_product_type = 1"; } elseif (!isModEnabled('service')) { // when service module is disabled, show products only @@ -2725,21 +2749,21 @@ class Form if ($i > 0) { $sql .= " AND "; } - $sql .= "(p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= "(p.ref LIKE '" . $this->db->escape($prefix . $crit) . "%' OR p.label LIKE '" . $this->db->escape($prefix . $crit) . "%'"; if (getDolGlobalInt('MAIN_MULTILANGS')) { - $sql .= " OR pl.label LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= " OR pl.label LIKE '" . $this->db->escape($prefix . $crit) . "%'"; } if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES) && !empty($socid)) { - $sql .= " OR pcp.ref_customer LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= " OR pcp.ref_customer LIKE '" . $this->db->escape($prefix . $crit) . "%'"; } if (!empty($conf->global->PRODUCT_AJAX_SEARCH_ON_DESCRIPTION)) { - $sql .= " OR p.description LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= " OR p.description LIKE '" . $this->db->escape($prefix . $crit) . "%'"; if (getDolGlobalInt('MAIN_MULTILANGS')) { - $sql .= " OR pl.description LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= " OR pl.description LIKE '" . $this->db->escape($prefix . $crit) . "%'"; } } if (!empty($conf->global->MAIN_SEARCH_PRODUCT_BY_FOURN_REF)) { - $sql .= " OR pfp.ref_fourn LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= " OR pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) . "%'"; } $sql .= ")"; $i++; @@ -2748,12 +2772,12 @@ class Form $sql .= ")"; } if (isModEnabled('barcode')) { - $sql .= " OR p.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; + $sql .= " OR p.barcode LIKE '" . $this->db->escape($prefix . $filterkey) . "%'"; } $sql .= ')'; } if (count($warehouseStatusArray)) { - $sql .= " GROUP BY ".$selectFields; + $sql .= " GROUP BY " . $selectFields; } //Sort by category @@ -2768,23 +2792,23 @@ class Form $sql .= $this->db->plimit($limit, 0); // Build output string - dol_syslog(get_class($this)."::select_produits_list search products", LOG_DEBUG); + dol_syslog(get_class($this) . "::select_produits_list search products", LOG_DEBUG); $result = $this->db->query($sql); if ($result) { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; - require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; $num = $this->db->num_rows($result); $events = null; if (!$forcecombo) { - include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $out .= ajax_combobox($htmlname, $events, getDolGlobalInt("PRODUIT_USE_SEARCH_TO_SELECT")); } - $out .= ''; $textifempty = ''; // Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. @@ -2801,7 +2825,7 @@ class Form } } if ($showempty) { - $out .= ''; + $out .= ''; } $i = 0; @@ -2812,11 +2836,11 @@ class Form if ((!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) && !empty($objp->price_by_qty) && $objp->price_by_qty == 1) { // Price by quantity will return many prices for the same product $sql = "SELECT rowid, quantity, price, unitprice, remise_percent, remise, price_base_type"; - $sql .= " FROM ".$this->db->prefix()."product_price_by_qty"; - $sql .= " WHERE fk_product_price = ".((int) $objp->price_rowid); + $sql .= " FROM " . $this->db->prefix() . "product_price_by_qty"; + $sql .= " WHERE fk_product_price = " . ((int) $objp->price_rowid); $sql .= " ORDER BY quantity ASC"; - dol_syslog(get_class($this)."::select_produits_list search prices by qty", LOG_DEBUG); + dol_syslog(get_class($this) . "::select_produits_list search prices by qty", LOG_DEBUG); $result2 = $this->db->query($sql); if ($result2) { $nb_prices = $this->db->num_rows($result2); @@ -2854,7 +2878,7 @@ class Form $price_product = new Product($this->db); $price_product->fetch($objp->rowid, '', '', 1); - require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php'; $priceparser = new PriceParser($this->db); $price_result = $priceparser->parseProduct($price_product); if ($price_result >= 0) { @@ -2898,15 +2922,15 @@ class Form * This define value for &$opt and &$optJson. * This function is called by select_produits_list(). * - * @param object $objp Resultset of fetch - * @param string $opt Option (var used for returned value in string option format) - * @param string $optJson Option (var used for returned value in json format) - * @param int $price_level Price level - * @param string $selected Preselected value - * @param int $hidepriceinlabel Hide price in label - * @param string $filterkey Filter key to highlight - * @param int $novirtualstock Do not load virtual stock, even if slow option STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO is on. - * @return void + * @param object $objp Resultset of fetch + * @param string $opt Option (var used for returned value in string option format) + * @param string $optJson Option (var used for returned value in json format) + * @param int $price_level Price level + * @param string $selected Preselected value + * @param int $hidepriceinlabel Hide price in label + * @param string $filterkey Filter key to highlight + * @param int $novirtualstock Do not load virtual stock, even if slow option STOCK_SHOW_VIRTUAL_STOCK_IN_PRODUCTS_COMBO is on. + * @return void */ protected function constructProductListOption(&$objp, &$opt, &$optJson, $price_level, $selected, $hidepriceinlabel = 0, $filterkey = '', $novirtualstock = 0) { @@ -2938,7 +2962,7 @@ class Form $label = $objp->label_translated; } if (!empty($filterkey) && $filterkey != '') { - $label = preg_replace('/('.preg_quote($filterkey, '/').')/i', '$1', $label, 1); + $label = preg_replace('/(' . preg_quote($filterkey, '/') . ')/i', '$1', $label, 1); } $outkey = $objp->rowid; @@ -2955,36 +2979,36 @@ class Form $outpbq = empty($objp->price_by_qty_rowid) ? '' : $objp->price_by_qty_rowid; $outtype = $objp->fk_product_type; - $outdurationvalue = $outtype == Product::TYPE_SERVICE ?substr($objp->duration, 0, dol_strlen($objp->duration) - 1) : ''; - $outdurationunit = $outtype == Product::TYPE_SERVICE ?substr($objp->duration, -1) : ''; + $outdurationvalue = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, 0, dol_strlen($objp->duration) - 1) : ''; + $outdurationunit = $outtype == Product::TYPE_SERVICE ? substr($objp->duration, -1) : ''; if ($outorigin && !empty($conf->global->PRODUCT_SHOW_ORIGIN_IN_COMBO)) { - require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; } // Units $outvalUnits = ''; if (getDolGlobalInt('PRODUCT_USE_UNITS')) { if (!empty($objp->unit_short)) { - $outvalUnits .= ' - '.$objp->unit_short; + $outvalUnits .= ' - ' . $objp->unit_short; } } if (!empty($conf->global->PRODUCT_SHOW_DIMENSIONS_IN_COMBO)) { if (!empty($objp->weight) && $objp->weight_units !== null) { $unitToShow = showDimensionInBestUnit($objp->weight, $objp->weight_units, 'weight', $langs); - $outvalUnits .= ' - '.$unitToShow; + $outvalUnits .= ' - ' . $unitToShow; } if ((!empty($objp->length) || !empty($objp->width) || !empty($objp->height)) && $objp->length_units !== null) { - $unitToShow = $objp->length.' x '.$objp->width.' x '.$objp->height.' '.measuringUnitString(0, 'size', $objp->length_units); - $outvalUnits .= ' - '.$unitToShow; + $unitToShow = $objp->length . ' x ' . $objp->width . ' x ' . $objp->height . ' ' . measuringUnitString(0, 'size', $objp->length_units); + $outvalUnits .= ' - ' . $unitToShow; } if (!empty($objp->surface) && $objp->surface_units !== null) { $unitToShow = showDimensionInBestUnit($objp->surface, $objp->surface_units, 'surface', $langs); - $outvalUnits .= ' - '.$unitToShow; + $outvalUnits .= ' - ' . $unitToShow; } if (!empty($objp->volume) && $objp->volume_units !== null) { $unitToShow = showDimensionInBestUnit($objp->volume, $objp->volume_units, 'volume', $langs); - $outvalUnits .= ' - '.$unitToShow; + $outvalUnits .= ' - ' . $unitToShow; } } if ($outdurationvalue && $outdurationunit) { @@ -2996,14 +3020,14 @@ class Form 'y' => $langs->trans('Year') ); if (isset($da[$outdurationunit])) { - $outvalUnits .= ' - '.$outdurationvalue.' '.$langs->transnoentities($da[$outdurationunit].($outdurationvalue > 1 ? 's' : '')); + $outvalUnits .= ' - ' . $outdurationvalue . ' ' . $langs->transnoentities($da[$outdurationunit] . ($outdurationvalue > 1 ? 's' : '')); } } - $opt = '\n"; $optJson = array( - 'key'=>$outkey, - 'value'=>$outref, - 'label'=>$outval, - 'label2'=>$outlabel, - 'desc'=>$outdesc, - 'type'=>$outtype, - 'price_ht'=>price2num($outprice_ht), - 'price_ttc'=>price2num($outprice_ttc), - 'price_ht_locale'=>price(price2num($outprice_ht)), - 'price_ttc_locale'=>price(price2num($outprice_ttc)), - 'pricebasetype'=>$outpricebasetype, - 'tva_tx'=>$outtva_tx, - 'default_vat_code'=>$outdefault_vat_code, - 'qty'=>$outqty, - 'discount'=>$outdiscount, - 'duration_value'=>$outdurationvalue, - 'duration_unit'=>$outdurationunit, - 'pbq'=>$outpbq, - 'labeltrans'=>$outlabel_translated, - 'desctrans'=>$outdesc_translated, - 'ref_customer'=>$outrefcust + 'key' => $outkey, + 'value' => $outref, + 'label' => $outval, + 'label2' => $outlabel, + 'desc' => $outdesc, + 'type' => $outtype, + 'price_ht' => price2num($outprice_ht), + 'price_ttc' => price2num($outprice_ttc), + 'price_ht_locale' => price(price2num($outprice_ht)), + 'price_ttc_locale' => price(price2num($outprice_ttc)), + 'pricebasetype' => $outpricebasetype, + 'tva_tx' => $outtva_tx, + 'default_vat_code' => $outdefault_vat_code, + 'qty' => $outqty, + 'discount' => $outdiscount, + 'duration_value' => $outdurationvalue, + 'duration_unit' => $outdurationunit, + 'pbq' => $outpbq, + 'labeltrans' => $outlabel_translated, + 'desctrans' => $outdesc_translated, + 'ref_customer' => $outrefcust ); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** - * Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list) + * Return list of products for customer (in Ajax if Ajax activated or go to select_produits_fournisseurs_list) * - * @param int $socid Id third party - * @param string $selected Preselected product - * @param string $htmlname Name of HTML Select - * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) - * @param string $filtre For a SQL filter - * @param array $ajaxoptions Options for ajax_autocompleter - * @param int $hidelabel Hide label (0=no, 1=yes) - * @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices - * @param string $morecss More CSS - * @param string $placeholder Placeholder - * @return void + * @param int $socid Id third party + * @param string $selected Preselected product + * @param string $htmlname Name of HTML Select + * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param string $filtre For a SQL filter + * @param array $ajaxoptions Options for ajax_autocompleter + * @param int $hidelabel Hide label (0=no, 1=yes) + * @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices + * @param string $morecss More CSS + * @param string $placeholder Placeholder + * @return void */ public function select_produits_fournisseurs($socid, $selected = '', $htmlname = 'productid', $filtertype = '', $filtre = '', $ajaxoptions = array(), $hidelabel = 0, $alsoproductwithnosupplierprice = 0, $morecss = '', $placeholder = '') { @@ -3260,7 +3285,7 @@ class Form $selected_input_value = ''; if (!empty($conf->use_javascript_ajax) && !empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT)) { if ($selected > 0) { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $producttmpselect = new Product($this->db); $producttmpselect->fetch($selected); $selected_input_value = $producttmpselect->ref; @@ -3268,33 +3293,34 @@ class Form } // mode=2 means suppliers products - $urloption = ($socid > 0 ? 'socid='.$socid.'&' : '').'htmlname='.$htmlname.'&outjson=1&price_level='.$price_level.'&type='.$filtertype.'&mode=2&status='.$status.'&finished='.$finished.'&alsoproductwithnosupplierprice='.$alsoproductwithnosupplierprice; - print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT.'/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); + $urloption = ($socid > 0 ? 'socid=' . $socid . '&' : '') . 'htmlname=' . $htmlname . '&outjson=1&price_level=' . $price_level . '&type=' . $filtertype . '&mode=2&status=' . $status . '&finished=' . $finished . '&alsoproductwithnosupplierprice=' . $alsoproductwithnosupplierprice; + print ajax_autocompleter($selected, $htmlname, DOL_URL_ROOT . '/product/ajax/products.php', $urloption, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT, 0, $ajaxoptions); - print ($hidelabel ? '' : $langs->trans("RefOrLabel").' : ').''; + print ($hidelabel ? '' : $langs->trans("RefOrLabel") . ' : ') . ''; } else { print $this->select_produits_fournisseurs_list($socid, $selected, $htmlname, $filtertype, $filtre, '', $status, 0, 0, $alsoproductwithnosupplierprice, $morecss, 0, $placeholder); } } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** - * Return list of suppliers products + * Return list of suppliers products * - * @param int $socid Id of supplier thirdparty (0 = no filter) - * @param int $selected Product price pre-selected (must be 'id' in product_fournisseur_price or 'idprod_IDPROD') - * @param string $htmlname Name of HTML select - * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) - * @param string $filtre Generic filter. Data must not come from user input. - * @param string $filterkey Filter of produdts - * @param int $statut -1=Return all products, 0=Products not on buy, 1=Products on buy - * @param int $outputmode 0=HTML select string, 1=Array - * @param int $limit Limit of line number - * @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices - * @param string $morecss Add more CSS - * @param int $showstockinlist Show stock information (slower). - * @param string $placeholder Placeholder - * @return array|string Array of keys for json or HTML component + * @param int $socid Id of supplier thirdparty (0 = no filter) + * @param int $selected Product price pre-selected (must be 'id' in product_fournisseur_price or 'idprod_IDPROD') + * @param string $htmlname Name of HTML select + * @param string $filtertype Filter on product type (''=nofilter, 0=product, 1=service) + * @param string $filtre Generic filter. Data must not come from user input. + * @param string $filterkey Filter of produdts + * @param int $statut -1=Return all products, 0=Products not on buy, 1=Products on buy + * @param int $outputmode 0=HTML select string, 1=Array + * @param int $limit Limit of line number + * @param int $alsoproductwithnosupplierprice 1=Add also product without supplier prices + * @param string $morecss Add more CSS + * @param int $showstockinlist Show stock information (slower). + * @param string $placeholder Placeholder + * @return array|string Array of keys for json or HTML component */ public function select_produits_fournisseurs_list($socid, $selected = '', $htmlname = 'productid', $filtertype = '', $filtre = '', $filterkey = '', $statut = -1, $outputmode = 0, $limit = 100, $alsoproductwithnosupplierprice = 0, $morecss = '', $showstockinlist = 0, $placeholder = '') { @@ -3330,25 +3356,25 @@ class Form if (isModEnabled('barcode')) { $sql .= ", pfp.barcode"; } - $sql .= " FROM ".$this->db->prefix()."product as p"; - $sql .= " LEFT JOIN ".$this->db->prefix()."product_fournisseur_price as pfp ON ( p.rowid = pfp.fk_product AND pfp.entity IN (".getEntity('product').") )"; + $sql .= " FROM " . $this->db->prefix() . "product as p"; + $sql .= " LEFT JOIN " . $this->db->prefix() . "product_fournisseur_price as pfp ON ( p.rowid = pfp.fk_product AND pfp.entity IN (" . getEntity('product') . ") )"; if ($socid > 0) { - $sql .= " AND pfp.fk_soc = ".((int) $socid); + $sql .= " AND pfp.fk_soc = " . ((int) $socid); } - $sql .= " LEFT JOIN ".$this->db->prefix()."societe as s ON pfp.fk_soc = s.rowid"; + $sql .= " LEFT JOIN " . $this->db->prefix() . "societe as s ON pfp.fk_soc = s.rowid"; // Units if (getDolGlobalInt('PRODUCT_USE_UNITS')) { - $sql .= " LEFT JOIN ".$this->db->prefix()."c_units u ON u.rowid = p.fk_unit"; + $sql .= " LEFT JOIN " . $this->db->prefix() . "c_units u ON u.rowid = p.fk_unit"; } - $sql .= " WHERE p.entity IN (".getEntity('product').")"; + $sql .= " WHERE p.entity IN (" . getEntity('product') . ")"; if ($statut != -1) { - $sql .= " AND p.tobuy = ".((int) $statut); + $sql .= " AND p.tobuy = " . ((int) $statut); } if (strval($filtertype) != '') { - $sql .= " AND p.fk_product_type = ".((int) $filtertype); + $sql .= " AND p.fk_product_type = " . ((int) $filtertype); } if (!empty($filtre)) { - $sql .= " ".$filtre; + $sql .= " " . $filtre; } // Add where from hooks $parameters = array(); @@ -3368,9 +3394,9 @@ class Form if ($i > 0) { $sql .= " AND "; } - $sql .= "(pfp.ref_fourn LIKE '".$this->db->escape($prefix.$crit)."%' OR p.ref LIKE '".$this->db->escape($prefix.$crit)."%' OR p.label LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= "(pfp.ref_fourn LIKE '" . $this->db->escape($prefix . $crit) . "%' OR p.ref LIKE '" . $this->db->escape($prefix . $crit) . "%' OR p.label LIKE '" . $this->db->escape($prefix . $crit) . "%'"; if (!empty($conf->global->PRODUIT_FOURN_TEXTS)) { - $sql .= " OR pfp.desc_fourn LIKE '".$this->db->escape($prefix.$crit)."%'"; + $sql .= " OR pfp.desc_fourn LIKE '" . $this->db->escape($prefix . $crit) . "%'"; } $sql .= ")"; $i++; @@ -3379,8 +3405,8 @@ class Form $sql .= ")"; } if (isModEnabled('barcode')) { - $sql .= " OR p.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; - $sql .= " OR pfp.barcode LIKE '".$this->db->escape($prefix.$filterkey)."%'"; + $sql .= " OR p.barcode LIKE '" . $this->db->escape($prefix . $filterkey) . "%'"; + $sql .= " OR pfp.barcode LIKE '" . $this->db->escape($prefix . $filterkey) . "%'"; } $sql .= ')'; } @@ -3389,20 +3415,20 @@ class Form // Build output string - dol_syslog(get_class($this)."::select_produits_fournisseurs_list", LOG_DEBUG); + dol_syslog(get_class($this) . "::select_produits_fournisseurs_list", LOG_DEBUG); $result = $this->db->query($sql); if ($result) { - require_once DOL_DOCUMENT_ROOT.'/product/dynamic_price/class/price_parser.class.php'; - require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/product/dynamic_price/class/price_parser.class.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/product.lib.php'; $num = $this->db->num_rows($result); //$out.=''; + $out .= ''; + $form = ''; + print ''; + print ''; + print ''; + $out .= ''; + $out .= ''; if ($user->admin && empty($noinfoadmin)) { - $out.= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); + $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); } - $out.= ajax_combobox($htmlname); + $out .= ajax_combobox($htmlname); if ($deposit_percent >= 0) { - $out .= '
'."\n"; + $more .= '
' . "\n"; $more .= $moreonecolumn; } @@ -5228,10 +5265,10 @@ class Form $button = $useajax; $useajax = 1; $autoOpen = false; - $dialogconfirm .= '-'.$button; + $dialogconfirm .= '-' . $button; } - $pageyes = $page.(preg_match('/\?/', $page) ? '&' : '?').'action='.urlencode($action).'&confirm=yes'; - $pageno = ($useajax == 2 ? $page.(preg_match('/\?/', $page) ? '&' : '?').'action='.urlencode($action).'&confirm=no' : ''); + $pageyes = $page . (preg_match('/\?/', $page) ? '&' : '?') . 'action=' . urlencode($action) . '&confirm=yes'; + $pageno = ($useajax == 2 ? $page . (preg_match('/\?/', $page) ? '&' : '?') . 'action=' . urlencode($action) . '&confirm=no' : ''); // Add input fields into list of fields to read during submit (inputok and inputko) if (is_array($formquestion)) { @@ -5253,24 +5290,24 @@ class Form } // Show JQuery confirm box. - $formconfirm .= '' . "\n"; - $formconfirm .= "\n\n"; - $formconfirm .= ''; $formconfirm .= "\n"; } else { - $formconfirm .= "\n\n"; + $formconfirm .= "\n\n"; if (empty($disableformtag)) { - $formconfirm .= ''."\n"; + $formconfirm .= '' . "\n"; } - $formconfirm .= ''."\n"; - $formconfirm .= ''."\n"; + $formconfirm .= '' . "\n"; + $formconfirm .= '' . "\n"; - $formconfirm .= ''."\n"; + $formconfirm .= '
' . "\n"; // Line title $formconfirm .= ''."\n"; + $formconfirm .= img_picto('', 'pictoconfirm') . ' ' . $title; + $formconfirm .= '' . "\n"; // Line text if (is_array($formquestion) && !empty($formquestion['text'])) { - $formconfirm .= ''."\n"; + $formconfirm .= '' . "\n"; } // Line form fields if ($more) { - $formconfirm .= ''."\n"; + $formconfirm .= '' . "\n"; } // Line with question $formconfirm .= ''; - $formconfirm .= ''; + $formconfirm .= ''; $formconfirm .= ''; - $formconfirm .= ''."\n"; + $formconfirm .= '' . "\n"; - $formconfirm .= '
'; - $formconfirm .= img_picto('', 'pictoconfirm').' '.$title; - $formconfirm .= '
'.$formquestion['text'].'
' . $formquestion['text'] . '
'."\n"; + $formconfirm .= '
' . "\n"; $formconfirm .= $more; - $formconfirm .= '
'.$question.'' . $question . ''; $formconfirm .= $this->selectyesno("confirm", $newselectedchoice, 0, false, 0, 0, 'marginleftonly marginrightonly', $labelbuttonyes, $labelbuttonno); - $formconfirm .= ''; + $formconfirm .= ''; $formconfirm .= '
'."\n"; + $formconfirm .= '' . "\n"; if (empty($disableformtag)) { $formconfirm .= "\n"; @@ -5424,7 +5461,7 @@ class Form if (!empty($conf->use_javascript_ajax)) { $formconfirm .= ''; - $formconfirm .= ''."\n"; + $formconfirm .= '' . "\n"; } $formconfirm .= "\n"; @@ -5447,28 +5484,29 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Show a form to select a project * - * @param int $page Page - * @param int $socid Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id) - * @param int $selected Id pre-selected project - * @param string $htmlname Name of select field - * @param int $discard_closed Discard closed projects (0=Keep,1=hide completely except $selected,2=Disable) - * @param int $maxlength Max length - * @param int $forcefocus Force focus on field (works with javascript only) - * @param int $nooutput No print is done. String is returned. - * @param string $textifnoproject Text to show if no project - * @param string $morecss More CSS - * @return string Return html content + * @param int $page Page + * @param int $socid Id third party (-1=all, 0=only projects not linked to a third party, id=projects not linked or linked to third party id) + * @param int $selected Id pre-selected project + * @param string $htmlname Name of select field + * @param int $discard_closed Discard closed projects (0=Keep,1=hide completely except $selected,2=Disable) + * @param int $maxlength Max length + * @param int $forcefocus Force focus on field (works with javascript only) + * @param int $nooutput No print is done. String is returned. + * @param string $textifnoproject Text to show if no project + * @param string $morecss More CSS + * @return string Return html content */ public function form_project($page, $socid, $selected = '', $htmlname = 'projectid', $discard_closed = 0, $maxlength = 20, $forcefocus = 0, $nooutput = 0, $textifnoproject = '', $morecss = '') { // phpcs:enable global $langs; - require_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; - require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/project.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/class/html.formprojet.class.php'; $out = ''; @@ -5476,11 +5514,11 @@ class Form $langs->load("project"); if ($htmlname != "none") { - $out .= '
'; + $out .= ''; $out .= ''; - $out .= ''; + $out .= ''; $out .= $formproject->select_projects($socid, $selected, $htmlname, $maxlength, 0, 1, $discard_closed, $forcefocus, 0, 0, '', 1, 0, $morecss); - $out .= ''; + $out .= ''; $out .= '
'; } else { $out .= ''; @@ -5489,7 +5527,7 @@ class Form $projet->fetch($selected); $out .= $projet->getNomUrl(0, '', 1); } else { - $out .= ''.$textifnoproject.''; + $out .= '' . $textifnoproject . ''; } $out .= ''; } @@ -5502,20 +5540,21 @@ class Form } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** - * Show a form to select payment conditions + * Show a form to select payment conditions * - * @param int $page Page - * @param string $selected Id condition pre-selectionne - * @param string $htmlname Name of select html field - * @param int $addempty Add empty entry - * @param string $type Type ('direct-debit' or 'bank-transfer') - * @param int $filtertype If > 0, include payment terms with deposit percentage (for objects other than invoices and invoice templates) - * @param string $deposit_percent < 0 : deposit_percent input makes no sense (for example, in list filters) - * 0 : use default deposit percentage from entry - * > 0 : force deposit percentage (for example, from company object) - * @param int $nooutput No print is done. String is returned. - * @return string HTML output or '' + * @param int $page Page + * @param string $selected Id condition pre-selectionne + * @param string $htmlname Name of select html field + * @param int $addempty Add empty entry + * @param string $type Type ('direct-debit' or 'bank-transfer') + * @param int $filtertype If > 0, include payment terms with deposit percentage (for objects other than invoices and invoice templates) + * @param string $deposit_percent < 0 : deposit_percent input makes no sense (for example, in list filters) + * 0 : use default deposit percentage from entry + * > 0 : force deposit percentage (for example, from company object) + * @param int $nooutput No print is done. String is returned. + * @return string HTML output or '' */ public function form_conditions_reglement($page, $selected = '', $htmlname = 'cond_reglement_id', $addempty = 0, $type = '', $filtertype = -1, $deposit_percent = -1, $nooutput = 0) { @@ -5525,14 +5564,14 @@ class Form $out = ''; if ($htmlname != "none") { - $out .= '
'; + $out .= ''; $out .= ''; - $out .= ''; + $out .= ''; if ($type) { - $out .= ''; + $out .= ''; } $out .= $this->getSelectConditionsPaiements($selected, $htmlname, $filtertype, $addempty, 0, '', $deposit_percent); - $out .= ''; + $out .= ''; $out .= '
'; } else { if ($selected) { @@ -5562,26 +5601,27 @@ class Form } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Show a form to select a delivery delay * - * @param int $page Page - * @param string $selected Id condition pre-selectionne - * @param string $htmlname Name of select html field - * @param int $addempty Ajoute entree vide - * @return void + * @param int $page Page + * @param string $selected Id condition pre-selectionne + * @param string $htmlname Name of select html field + * @param int $addempty Ajoute entree vide + * @return void */ public function form_availability($page, $selected = '', $htmlname = 'availability', $addempty = 0) { // phpcs:enable global $langs; if ($htmlname != "none") { - print '
'; + print ''; print ''; - print ''; + print ''; $this->selectAvailabilityDelay($selected, $htmlname, -1, $addempty); - print ''; - print ''; + print ''; + print ''; print '
'; } else { if ($selected) { @@ -5597,21 +5637,21 @@ class Form * Output HTML form to select list of input reason (events that triggered an object creation, like after sending an emailing, making an advert, ...) * List found into table c_input_reason loaded by loadCacheInputReason * - * @param string $page Page - * @param string $selected Id condition pre-selectionne - * @param string $htmlname Name of select html field - * @param int $addempty Add empty entry - * @return void + * @param string $page Page + * @param string $selected Id condition pre-selectionne + * @param string $htmlname Name of select html field + * @param int $addempty Add empty entry + * @return void */ public function formInputReason($page, $selected = '', $htmlname = 'demandreason', $addempty = 0) { global $langs; if ($htmlname != "none") { - print '
'; + print ''; print ''; - print ''; + print ''; $this->selectInputReason($selected, $htmlname, -1, $addempty); - print ''; + print ''; print '
'; } else { if ($selected) { @@ -5629,18 +5669,19 @@ class Form } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Show a form + html select a date * - * @param string $page Page - * @param string $selected Date preselected - * @param string $htmlname Html name of date input fields or 'none' - * @param int $displayhour Display hour selector - * @param int $displaymin Display minutes selector - * @param int $nooutput 1=No print output, return string - * @param string $type 'direct-debit' or 'bank-transfer' - * @return string - * @see selectDate() + * @param string $page Page + * @param string $selected Date preselected + * @param string $htmlname Html name of date input fields or 'none' + * @param int $displayhour Display hour selector + * @param int $displaymin Display minutes selector + * @param int $nooutput 1=No print output, return string + * @param string $type 'direct-debit' or 'bank-transfer' + * @return string + * @see selectDate() */ public function form_date($page, $selected, $htmlname, $displayhour = 0, $displaymin = 0, $nooutput = 0, $type = '') { @@ -5650,17 +5691,17 @@ class Form $ret = ''; if ($htmlname != "none") { - $ret .= '
'; - $ret .= ''; - $ret .= ''; + $ret .= ''; + $ret .= ''; + $ret .= ''; if ($type) { - $ret .= ''; + $ret .= ''; } $ret .= ''; $ret .= ''; - $ret .= ''; + $ret .= ''; $ret .= '
'; - $ret .= $this->selectDate($selected, $htmlname, $displayhour, $displaymin, 1, 'form'.$htmlname, 1, 0); + $ret .= $this->selectDate($selected, $htmlname, $displayhour, $displaymin, 1, 'form' . $htmlname, 1, 0); $ret .= '
'; } else { if ($displayhour) { @@ -5678,15 +5719,16 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Show a select form to choose a user * - * @param string $page Page - * @param string $selected Id of user preselected - * @param string $htmlname Name of input html field. If 'none', we just output the user link. - * @param array $exclude List of users id to exclude - * @param array $include List of users id to include - * @return void + * @param string $page Page + * @param string $selected Id of user preselected + * @param string $htmlname Name of input html field. If 'none', we just output the user link. + * @param array $exclude List of users id to exclude + * @param array $include List of users id to include + * @return void */ public function form_users($page, $selected = '', $htmlname = 'userid', $exclude = '', $include = '') { @@ -5694,15 +5736,15 @@ class Form global $langs; if ($htmlname != "none") { - print '
'; - print ''; - print ''; + print ''; + print ''; + print ''; print $this->select_dolusers($selected, $htmlname, 1, $exclude, 0, $include); - print ''; + print ''; print '
'; } else { if ($selected) { - require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php'; + require_once DOL_DOCUMENT_ROOT . '/user/class/user.class.php'; $theuser = new User($this->db); $theuser->fetch($selected); print $theuser->getNomUrl(1); @@ -5714,18 +5756,19 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Show form with payment mode * - * @param string $page Page - * @param int $selected Id mode pre-selectionne - * @param string $htmlname Name of select html field - * @param string $filtertype To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz)) - * @param int $active Active or not, -1 = all - * @param int $addempty 1=Add empty entry - * @param string $type Type ('direct-debit' or 'bank-transfer') - * @param int $nooutput 1=Return string, no output - * @return string HTML output or '' + * @param string $page Page + * @param int $selected Id mode pre-selectionne + * @param string $htmlname Name of select html field + * @param string $filtertype To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz)) + * @param int $active Active or not, -1 = all + * @param int $addempty 1=Add empty entry + * @param string $type Type ('direct-debit' or 'bank-transfer') + * @param int $nooutput 1=Return string, no output + * @return string HTML output or '' */ public function form_modes_reglement($page, $selected = '', $htmlname = 'mode_reglement_id', $filtertype = '', $active = 1, $addempty = 0, $type = '', $nooutput = 0) { @@ -5734,14 +5777,14 @@ class Form $out = ''; if ($htmlname != "none") { - $out .= '
'; + $out .= ''; $out .= ''; - $out .= ''; + $out .= ''; if ($type) { - $out .= ''; + $out .= ''; } $out .= $this->select_types_paiements($selected, $htmlname, $filtertype, 0, $addempty, 0, 0, $active, '', 1); - $out .= ''; + $out .= ''; $out .= '
'; } else { if ($selected) { @@ -5763,22 +5806,22 @@ class Form /** * Show form with transport mode * - * @param string $page Page - * @param int $selected Id mode pre-select - * @param string $htmlname Name of select html field - * @param int $active Active or not, -1 = all - * @param int $addempty 1=Add empty entry - * @return void + * @param string $page Page + * @param int $selected Id mode pre-select + * @param string $htmlname Name of select html field + * @param int $active Active or not, -1 = all + * @param int $addempty 1=Add empty entry + * @return void */ public function formSelectTransportMode($page, $selected = '', $htmlname = 'transport_mode_id', $active = 1, $addempty = 0) { global $langs; if ($htmlname != "none") { - print '
'; + print ''; print ''; - print ''; + print ''; $this->selectTransportMode($selected, $htmlname, 0, $addempty, 0, 0, $active); - print ''; + print ''; print '
'; } else { if ($selected) { @@ -5791,24 +5834,25 @@ class Form } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Show form with multicurrency code * - * @param string $page Page - * @param string $selected code pre-selectionne - * @param string $htmlname Name of select html field - * @return void + * @param string $page Page + * @param string $selected code pre-selectionne + * @param string $htmlname Name of select html field + * @return void */ public function form_multicurrency_code($page, $selected = '', $htmlname = 'multicurrency_code') { // phpcs:enable global $langs; if ($htmlname != "none") { - print '
'; + print ''; print ''; - print ''; + print ''; print $this->selectMultiCurrency($selected, $htmlname, 0); - print ''; + print ''; print '
'; } else { dol_include_once('/core/lib/company.lib.php'); @@ -5817,14 +5861,15 @@ class Form } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Show form with multicurrency rate * - * @param string $page Page - * @param double $rate Current rate - * @param string $htmlname Name of select html field - * @param string $currency Currency code to explain the rate - * @return void + * @param string $page Page + * @param double $rate Current rate + * @param string $htmlname Name of select html field + * @param string $currency Currency code to explain the rate + * @return void */ public function form_multicurrency_rate($page, $rate = '', $htmlname = 'multicurrency_tx', $currency = '') { @@ -5832,21 +5877,21 @@ class Form global $langs, $mysoc, $conf; if ($htmlname != "none") { - print '
'; + print ''; print ''; - print ''; - print ' '; + print ''; + print ' '; print ' '; - print ''; + print ''; print '
'; } else { if (!empty($rate)) { print price($rate, 1, $langs, 1, 0); if ($currency && $rate != 1) { - print '   ('.price($rate, 1, $langs, 1, 0).' '.$currency.' = 1 '.$conf->currency.')'; + print '   (' . price($rate, 1, $langs, 1, 0) . ' ' . $currency . ' = 1 ' . $conf->currency . ')'; } } else { print 1; @@ -5856,29 +5901,30 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** - * Show a select box with available absolute discounts + * Show a select box with available absolute discounts * - * @param string $page Page URL where form is shown - * @param int $selected Value pre-selected - * @param string $htmlname Name of SELECT component. If 'none', not changeable. Example 'remise_id'. - * @param int $socid Third party id - * @param float $amount Total amount available - * @param string $filter SQL filter on discounts - * @param int $maxvalue Max value for lines that can be selected - * @param string $more More string to add - * @param int $hidelist 1=Hide list - * @param int $discount_type 0 => customer discount, 1 => supplier discount - * @return void + * @param string $page Page URL where form is shown + * @param int $selected Value pre-selected + * @param string $htmlname Name of SELECT component. If 'none', not changeable. Example 'remise_id'. + * @param int $socid Third party id + * @param float $amount Total amount available + * @param string $filter SQL filter on discounts + * @param int $maxvalue Max value for lines that can be selected + * @param string $more More string to add + * @param int $hidelist 1=Hide list + * @param int $discount_type 0 => customer discount, 1 => supplier discount + * @return void */ public function form_remise_dispo($page, $selected, $htmlname, $socid, $amount, $filter = '', $maxvalue = 0, $more = '', $hidelist = 0, $discount_type = 0) { // phpcs:enable global $conf, $langs; if ($htmlname != "none") { - print '
'; + print ''; print ''; - print ''; + print ''; print '
'; if (!empty($discount_type)) { if (!empty($conf->global->FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS)) { @@ -5916,24 +5962,24 @@ class Form print '
'; if (empty($hidelist)) { print '
'; - $newfilter = 'discount_type='.intval($discount_type); + $newfilter = 'discount_type=' . intval($discount_type); if (!empty($discount_type)) { $newfilter .= ' AND fk_invoice_supplier IS NULL AND fk_invoice_supplier_line IS NULL'; // Supplier discounts available } else { $newfilter .= ' AND fk_facture IS NULL AND fk_facture_line IS NULL'; // Customer discounts available } if ($filter) { - $newfilter .= ' AND ('.$filter.')'; + $newfilter .= ' AND (' . $filter . ')'; } // output the combo of discounts $nbqualifiedlines = $this->select_remises($selected, $htmlname, $newfilter, $socid, $maxvalue); if ($nbqualifiedlines > 0) { - print '   '; @@ -5957,14 +6003,15 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Show forms to select a contact * - * @param string $page Page - * @param Societe $societe Filter on third party - * @param int $selected Id contact pre-selectionne - * @param string $htmlname Name of HTML select. If 'none', we just show contact link. - * @return void + * @param string $page Page + * @param Societe $societe Filter on third party + * @param int $selected Id contact pre-selectionne + * @param string $htmlname Name of HTML select. If 'none', we just show contact link. + * @return void */ public function form_contacts($page, $societe, $selected = '', $htmlname = 'contactid') { @@ -5972,23 +6019,23 @@ class Form global $langs, $conf; if ($htmlname != "none") { - print ''; + print ''; print ''; - print ''; + print ''; print ''; print ''; - print ''; + print ''; print '
'; print $this->selectcontacts($societe->id, $selected, $htmlname); $num = $this->num; if ($num == 0) { $addcontact = (!empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress")); - print ''.$addcontact.''; + print '' . $addcontact . ''; } print '
'; } else { if ($selected) { - require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; + require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php'; $contact = new Contact($this->db); $contact->fetch($selected); print $contact->getFullName($langs); @@ -5999,21 +6046,22 @@ class Form } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Output html select to select thirdparty * - * @param string $page Page - * @param string $selected Id preselected - * @param string $htmlname Name of HTML select - * @param string $filter Optional filters criteras. Do not use a filter coming from input of users. - * @param int $showempty Add an empty field - * @param int $showtype Show third party type in combolist (customer, prospect or supplier) - * @param int $forcecombo Force to use combo box - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @param int $nooutput No print output. Return it only. - * @param array $excludeids Exclude IDs from the select combo - * @param string $textifnothirdparty Text to show if no thirdparty - * @return string HTML output or '' + * @param string $page Page + * @param string $selected Id preselected + * @param string $htmlname Name of HTML select + * @param string $filter Optional filters criteras. Do not use a filter coming from input of users. + * @param int $showempty Add an empty field + * @param int $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int $forcecombo Force to use combo box + * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param int $nooutput No print output. Return it only. + * @param array $excludeids Exclude IDs from the select combo + * @param string $textifnothirdparty Text to show if no thirdparty + * @return string HTML output or '' */ public function form_thirdparty($page, $selected = '', $htmlname = 'socid', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $events = array(), $nooutput = 0, $excludeids = array(), $textifnothirdparty = '') { @@ -6022,20 +6070,20 @@ class Form $out = ''; if ($htmlname != "none") { - $out .= '
'; + $out .= ''; $out .= ''; - $out .= ''; + $out .= ''; $out .= $this->select_company($selected, $htmlname, $filter, $showempty, $showtype, $forcecombo, $events, 0, 'minwidth100', '', '', 1, array(), false, $excludeids); - $out .= ''; + $out .= ''; $out .= '
'; } else { if ($selected) { - require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + require_once DOL_DOCUMENT_ROOT . '/societe/class/societe.class.php'; $soc = new Societe($this->db); $soc->fetch($selected); $out .= $soc->getNomUrl(0, ''); } else { - $out .= ''.$textifnothirdparty.''; + $out .= '' . $textifnothirdparty . ''; } } @@ -6049,13 +6097,14 @@ class Form } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Retourne la liste des devises, dans la langue de l'utilisateur * - * @param string $selected preselected currency code - * @param string $htmlname name of HTML select list - * @deprecated - * @return void + * @param string $selected preselected currency code + * @param string $htmlname name of HTML select list + * @deprecated + * @return void */ public function select_currency($selected = '', $htmlname = 'currency_id') { @@ -6066,11 +6115,11 @@ class Form /** * Retourne la liste des devises, dans la langue de l'utilisateur * - * @param string $selected preselected currency code - * @param string $htmlname name of HTML select list - * @param string $mode 0 = Add currency symbol into label, 1 = Add 3 letter iso code - * @param string $useempty '1'=Allow empty value - * @return string + * @param string $selected preselected currency code + * @param string $htmlname name of HTML select list + * @param string $mode 0 = Add currency symbol into label, 1 = Add 3 letter iso code + * @param string $useempty '1'=Allow empty value + * @return string */ public function selectCurrency($selected = '', $htmlname = 'currency_id', $mode = 0, $useempty = '') { @@ -6084,22 +6133,22 @@ class Form $selected = 'EUR'; // Pour compatibilite } - $out .= ''; if ($useempty) { $out .= ''; } foreach ($langs->cache_currencies as $code_iso => $currency) { $labeltoshow = $currency['label']; if ($mode == 1) { - $labeltoshow .= ' ('.$code_iso.')'; + $labeltoshow .= ' (' . $code_iso . ')'; } else { - $labeltoshow .= ' ('.$langs->getCurrencySymbol($code_iso).')'; + $labeltoshow .= ' (' . $langs->getCurrencySymbol($code_iso) . ')'; } if ($selected && $selected == $code_iso) { - $out .= ''; @@ -6110,23 +6159,23 @@ class Form } // Make select dynamic - include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $out .= ajax_combobox($htmlname); return $out; } /** - * Return array of currencies in user language + * Return array of currencies in user language * - * @param string $selected Preselected currency code - * @param string $htmlname Name of HTML select list - * @param integer $useempty 1=Add empty line - * @param string $filter Optional filters criteras (example: 'code <> x', ' in (1,3)') - * @param bool $excludeConfCurrency false = If company current currency not in table, we add it into list. Should always be available. - * true = we are in currency_rate update , we don't want to see conf->currency in select - * @param string $morecss More css - * @return string + * @param string $selected Preselected currency code + * @param string $htmlname Name of HTML select list + * @param integer $useempty 1=Add empty line + * @param string $filter Optional filters criteras (example: 'code <> x', ' in (1,3)') + * @param bool $excludeConfCurrency false = If company current currency not in table, we add it into list. Should always be available. + * true = we are in currency_rate update , we don't want to see conf->currency in select + * @param string $morecss More css + * @return string */ public function selectMultiCurrency($selected = '', $htmlname = 'multicurrency_code', $useempty = 0, $filter = '', $excludeConfCurrency = false, $morecss = '') { @@ -6136,10 +6185,10 @@ class Form $TCurrency = array(); - $sql = "SELECT code FROM ".$this->db->prefix()."multicurrency"; - $sql .= " WHERE entity IN ('".getEntity('mutlicurrency')."')"; + $sql = "SELECT code FROM " . $this->db->prefix() . "multicurrency"; + $sql .= " WHERE entity IN ('" . getEntity('mutlicurrency') . "')"; if ($filter) { - $sql .= " AND ".$filter; + $sql .= " AND " . $filter; } $resql = $this->db->query($sql); if ($resql) { @@ -6149,7 +6198,7 @@ class Form } $out = ''; - $out .= ''; if ($useempty) { $out .= ''; } @@ -6161,13 +6210,13 @@ class Form foreach ($langs->cache_currencies as $code_iso => $currency) { if (isset($TCurrency[$code_iso])) { if (!empty($selected) && $selected == $code_iso) { - $out .= ''; } } @@ -6176,18 +6225,19 @@ class Form $out .= ''; // Make select dynamic - include_once DOL_DOCUMENT_ROOT.'/core/lib/ajax.lib.php'; + include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; $out .= ajax_combobox($htmlname); return $out; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Load into the cache vat rates of a country * - * @param string $country_code Country code with quotes ("'CA'", or "'CA,IN,...'") - * @return int Nb of loaded lines, 0 if already loaded, <0 if KO + * @param string $country_code Country code with quotes ("'CA'", or "'CA,IN,...'") + * @return int Nb of loaded lines, 0 if already loaded, <0 if KO */ public function load_cache_vatrates($country_code) { @@ -6202,10 +6252,10 @@ class Form dol_syslog(__METHOD__, LOG_DEBUG); $sql = "SELECT DISTINCT t.rowid, t.code, t.taux, t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.recuperableonly"; - $sql .= " FROM ".$this->db->prefix()."c_tva as t, ".$this->db->prefix()."c_country as c"; + $sql .= " FROM " . $this->db->prefix() . "c_tva as t, " . $this->db->prefix() . "c_country as c"; $sql .= " WHERE t.fk_pays = c.rowid"; $sql .= " AND t.active > 0"; - $sql .= " AND c.code IN (".$this->db->sanitize($country_code, 1).")"; + $sql .= " AND c.code IN (" . $this->db->sanitize($country_code, 1) . ")"; $sql .= " ORDER BY t.code ASC, t.taux ASC, t.recuperableonly ASC"; $resql = $this->db->query($sql); @@ -6214,65 +6264,66 @@ class Form if ($num) { for ($i = 0; $i < $num; $i++) { $obj = $this->db->fetch_object($resql); - $this->cache_vatrates[$i]['rowid'] = $obj->rowid; + $this->cache_vatrates[$i]['rowid'] = $obj->rowid; $this->cache_vatrates[$i]['code'] = $obj->code; - $this->cache_vatrates[$i]['txtva'] = $obj->taux; + $this->cache_vatrates[$i]['txtva'] = $obj->taux; $this->cache_vatrates[$i]['nprtva'] = $obj->recuperableonly; - $this->cache_vatrates[$i]['localtax1'] = $obj->localtax1; - $this->cache_vatrates[$i]['localtax1_type'] = $obj->localtax1_type; - $this->cache_vatrates[$i]['localtax2'] = $obj->localtax2; - $this->cache_vatrates[$i]['localtax2_type'] = $obj->localtax1_type; + $this->cache_vatrates[$i]['localtax1'] = $obj->localtax1; + $this->cache_vatrates[$i]['localtax1_type'] = $obj->localtax1_type; + $this->cache_vatrates[$i]['localtax2'] = $obj->localtax2; + $this->cache_vatrates[$i]['localtax2_type'] = $obj->localtax1_type; - $this->cache_vatrates[$i]['label'] = $obj->taux.'%'.($obj->code ? ' ('.$obj->code.')' : ''); // Label must contains only 0-9 , . % or * - $this->cache_vatrates[$i]['labelallrates'] = $obj->taux.'/'.($obj->localtax1 ? $obj->localtax1 : '0').'/'.($obj->localtax2 ? $obj->localtax2 : '0').($obj->code ? ' ('.$obj->code.')' : ''); // Must never be used as key, only label + $this->cache_vatrates[$i]['label'] = $obj->taux . '%' . ($obj->code ? ' (' . $obj->code . ')' : ''); // Label must contains only 0-9 , . % or * + $this->cache_vatrates[$i]['labelallrates'] = $obj->taux . '/' . ($obj->localtax1 ? $obj->localtax1 : '0') . '/' . ($obj->localtax2 ? $obj->localtax2 : '0') . ($obj->code ? ' (' . $obj->code . ')' : ''); // Must never be used as key, only label $positiverates = ''; if ($obj->taux) { - $positiverates .= ($positiverates ? '/' : '').$obj->taux; + $positiverates .= ($positiverates ? '/' : '') . $obj->taux; } if ($obj->localtax1) { - $positiverates .= ($positiverates ? '/' : '').$obj->localtax1; + $positiverates .= ($positiverates ? '/' : '') . $obj->localtax1; } if ($obj->localtax2) { - $positiverates .= ($positiverates ? '/' : '').$obj->localtax2; + $positiverates .= ($positiverates ? '/' : '') . $obj->localtax2; } if (empty($positiverates)) { $positiverates = '0'; } - $this->cache_vatrates[$i]['labelpositiverates'] = $positiverates.($obj->code ? ' ('.$obj->code.')' : ''); // Must never be used as key, only label + $this->cache_vatrates[$i]['labelpositiverates'] = $positiverates . ($obj->code ? ' (' . $obj->code . ')' : ''); // Must never be used as key, only label } return $num; } else { - $this->error = ''.$langs->trans("ErrorNoVATRateDefinedForSellerCountry", $country_code).''; + $this->error = '' . $langs->trans("ErrorNoVATRateDefinedForSellerCountry", $country_code) . ''; return -1; } } else { - $this->error = ''.$this->db->error().''; + $this->error = '' . $this->db->error() . ''; return -2; } } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** * Output an HTML select vat rate. * The name of this function should be selectVat. We keep bad name for compatibility purpose. * - * @param string $htmlname Name of HTML select field - * @param float|string $selectedrate Force preselected vat rate. Can be '8.5' or '8.5 (NOO)' for example. Use '' for no forcing. - * @param Societe $societe_vendeuse Thirdparty seller - * @param Societe $societe_acheteuse Thirdparty buyer - * @param int $idprod Id product. O if unknown of NA. - * @param int $info_bits Miscellaneous information on line (1 for NPR) - * @param int|string $type ''=Unknown, 0=Product, 1=Service (Used if idprod not defined) - * Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle. - * Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle. - * Si (vendeur et acheteur dans Communaute europeenne) et bien vendu = moyen de transports neuf (auto, bateau, avion), TVA par defaut=0 (La TVA doit etre paye par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de regle. - * Si vendeur et acheteur dans Communauté européenne et acheteur= particulier alors TVA par défaut=TVA du produit vendu. Fin de règle. - * Si vendeur et acheteur dans Communauté européenne et acheteur= entreprise alors TVA par défaut=0. Fin de règle. - * Sinon la TVA proposee par defaut=0. Fin de regle. - * @param bool $options_only Return HTML options lines only (for ajax treatment) - * @param int $mode 0=Use vat rate as key in combo list, 1=Add VAT code after vat rate into key, -1=Use id of vat line as key - * @return string + * @param string $htmlname Name of HTML select field + * @param float|string $selectedrate Force preselected vat rate. Can be '8.5' or '8.5 (NOO)' for example. Use '' for no forcing. + * @param Societe $societe_vendeuse Thirdparty seller + * @param Societe $societe_acheteuse Thirdparty buyer + * @param int $idprod Id product. O if unknown of NA. + * @param int $info_bits Miscellaneous information on line (1 for NPR) + * @param int|string $type ''=Unknown, 0=Product, 1=Service (Used if idprod not defined) + * Si vendeur non assujeti a TVA, TVA par defaut=0. Fin de regle. + * Si le (pays vendeur = pays acheteur) alors la TVA par defaut=TVA du produit vendu. Fin de regle. + * Si (vendeur et acheteur dans Communaute europeenne) et bien vendu = moyen de transports neuf (auto, bateau, avion), TVA par defaut=0 (La TVA doit etre paye par l'acheteur au centre d'impots de son pays et non au vendeur). Fin de regle. + * Si vendeur et acheteur dans Communauté européenne et acheteur= particulier alors TVA par défaut=TVA du produit vendu. Fin de règle. + * Si vendeur et acheteur dans Communauté européenne et acheteur= entreprise alors TVA par défaut=0. Fin de règle. + * Sinon la TVA proposee par defaut=0. Fin de regle. + * @param bool $options_only Return HTML options lines only (for ajax treatment) + * @param int $mode 0=Use vat rate as key in combo list, 1=Add VAT code after vat rate into key, -1=Use id of vat line as key + * @return string */ public function load_tva($htmlname = 'tauxtva', $selectedrate = '', $societe_vendeuse = '', $societe_acheteuse = '', $idprod = 0, $info_bits = 0, $type = '', $options_only = false, $mode = 0) { @@ -6298,9 +6349,9 @@ class Form // Check parameters if (is_object($societe_vendeuse) && !$societe_vendeuse->country_code) { if ($societe_vendeuse->id == $mysoc->id) { - $return .= ''.$langs->trans("ErrorYourCountryIsNotDefined").''; + $return .= '' . $langs->trans("ErrorYourCountryIsNotDefined") . ''; } else { - $return .= ''.$langs->trans("ErrorSupplierCountryIsNotDefined").''; + $return .= '' . $langs->trans("ErrorSupplierCountryIsNotDefined") . ''; } return $return; } @@ -6312,25 +6363,25 @@ class Form // Define list of countries to use to search VAT rates to show // First we defined code_country to use to find list if (is_object($societe_vendeuse)) { - $code_country = "'".$societe_vendeuse->country_code."'"; + $code_country = "'" . $societe_vendeuse->country_code . "'"; } else { - $code_country = "'".$mysoc->country_code."'"; // Pour compatibilite ascendente + $code_country = "'" . $mysoc->country_code . "'"; // Pour compatibilite ascendente } if (!empty($conf->global->SERVICE_ARE_ECOMMERCE_200238EC)) { // If option to have vat for end customer for services is on - require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; + require_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php'; if (!isInEEC($societe_vendeuse) && (!is_object($societe_acheteuse) || (isInEEC($societe_acheteuse) && !$societe_acheteuse->isACompany()))) { // We also add the buyer country code if (is_numeric($type)) { if ($type == 1) { // We know product is a service - $code_country .= ",'".$societe_acheteuse->country_code."'"; + $code_country .= ",'" . $societe_acheteuse->country_code . "'"; } } elseif (!$idprod) { // We don't know type of product - $code_country .= ",'".$societe_acheteuse->country_code."'"; + $code_country .= ",'" . $societe_acheteuse->country_code . "'"; } else { $prodstatic = new Product($this->db); $prodstatic->fetch($idprod); if ($prodstatic->type == Product::TYPE_SERVICE) { // We know product is a service - $code_country .= ",'".$societe_acheteuse->country_code."'"; + $code_country .= ",'" . $societe_acheteuse->country_code . "'"; } } } @@ -6382,13 +6433,13 @@ class Form // Override/enable VAT for expense report regardless of global setting - needed if expense report used for business expenses instead // of using supplier invoices (this is a very bad idea !) if (empty($conf->global->EXPENSEREPORT_OVERRIDE_VAT)) { - $title = ' title="'.dol_escape_htmltag($langs->trans('VATIsNotUsed')).'"'; + $title = ' title="' . dol_escape_htmltag($langs->trans('VATIsNotUsed')) . '"'; $disabled = true; } } if (!$options_only) { - $return .= ''; } $selectedfound = false; @@ -6402,13 +6453,13 @@ class Form $key = $rate['txtva']; $key .= $rate['nprtva'] ? '*' : ''; if ($mode > 0 && $rate['code']) { - $key .= ' ('.$rate['code'].')'; + $key .= ' (' . $rate['code'] . ')'; } if ($mode < 0) { $key = $rate['rowid']; } - $return .= '
'; - $retstring .= ''."\n"; - $retstring .= ''."\n"; - $retstring .= ''."\n"; + $retstring .= '' . "\n"; + $retstring .= '' . "\n"; + $retstring .= '' . "\n"; } else { $retstring .= "Bad value of MAIN_POPUP_CALENDAR"; } } else { // Show date with combo selects // Day - $retstring .= ''; + $retstring .= ''; if ($emptydate || $set_time == -1) { $retstring .= ''; } for ($day = 1; $day <= 31; $day++) { - $retstring .= ''; + $retstring .= ''; } $retstring .= ""; - $retstring .= ''; + $retstring .= ''; if ($emptydate || $set_time == -1) { $retstring .= ''; } // Month for ($month = 1; $month <= 12; $month++) { - $retstring .= '"; } @@ -6759,12 +6811,12 @@ class Form // Year if ($emptydate || $set_time == -1) { - $retstring .= ''; + $retstring .= ''; } else { - $retstring .= ''; + $retstring .= ''; for ($year = $syear - 10; $year < $syear + 10; $year++) { - $retstring .= ''; + $retstring .= ''; } $retstring .= "\n"; } @@ -6788,15 +6840,15 @@ class Form } } // Show hour - $retstring .= ''; + $retstring .= ''; if ($emptyhours) { $retstring .= ''; } for ($hour = $hourstart; $hour < $hourend; $hour++) { if (strlen($hour) < 2) { - $hour = "0".$hour; + $hour = "0" . $hour; } - $retstring .= ''; } @@ -6809,19 +6861,19 @@ class Form if ($m) { // Show minutes - $retstring .= ''; + $retstring .= ''; if ($emptyhours) { $retstring .= ''; } for ($min = 0; $min < 60; $min += $stepminutes) { if (strlen($min) < 2) { - $min = "0".$min; + $min = "0" . $min; } - $retstring .= ''; + $retstring .= ''; } $retstring .= ''; - $retstring .= ''; + $retstring .= ''; } if ($d && $h) { @@ -6844,10 +6896,10 @@ class Form // Generate the date part, depending on the use or not of the javascript calendar if ($addnowlink == 1) { // server time expressed in user time setup - $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date($nowgmt, 'day', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date($nowgmt, '%d', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date($nowgmt, '%m', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date($nowgmt, '%Y', 'tzuserrel').'\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . dol_print_date($nowgmt, 'day', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . dol_print_date($nowgmt, '%d', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . dol_print_date($nowgmt, '%m', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . dol_print_date($nowgmt, '%Y', 'tzuserrel') . '\');'; } elseif ($addnowlink == 2) { /* Disabled because the output does not use the string format defined by FormatDateShort key to forge the value into #prefix. * This break application for foreign languages. @@ -6856,10 +6908,10 @@ class Form $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(parseInt(d.getMonth().pad()) + 1);'; $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(d.getFullYear());'; */ - $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date($nowgmt, 'day', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date($nowgmt, '%d', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date($nowgmt, '%m', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date($nowgmt, '%Y', 'tzuserrel').'\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . dol_print_date($nowgmt, 'day', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . dol_print_date($nowgmt, '%d', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . dol_print_date($nowgmt, '%m', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . dol_print_date($nowgmt, '%Y', 'tzuserrel') . '\');'; } /*if ($usecalendar == "eldy") { @@ -6879,11 +6931,11 @@ class Form } //$reset_scripts .= 'this.form.elements[\''.$prefix.'hour\'].value=formatDate(new Date(), \'HH\'); '; if ($addnowlink == 1) { - $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date($nowgmt, '%H', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').change();'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(\'' . dol_print_date($nowgmt, '%H', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').change();'; } elseif ($addnowlink == 2) { - $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(d.getHours().pad());'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').change();'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(d.getHours().pad());'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').change();'; } if ($fullday) { @@ -6897,11 +6949,11 @@ class Form } //$reset_scripts .= 'this.form.elements[\''.$prefix.'min\'].value=formatDate(new Date(), \'mm\'); '; if ($addnowlink == 1) { - $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date($nowgmt, '%M', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').change();'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(\'' . dol_print_date($nowgmt, '%M', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').change();'; } elseif ($addnowlink == 2) { - $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(d.getMinutes().pad());'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').change();'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(d.getMinutes().pad());'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').change();'; } if ($fullday) { $reset_scripts .= ' } '; @@ -6909,7 +6961,7 @@ class Form } // If reset_scripts is not empty, print the link with the reset_scripts in the onClick if ($reset_scripts && empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { - $retstring .= ' '; } @@ -6921,16 +6973,16 @@ class Form $reset_scripts = ""; // Generate the date part, depending on the use or not of the javascript calendar - $reset_scripts .= 'jQuery(\'#'.$prefix.'\').val(\''.dol_print_date($nowgmt, 'dayinputnoreduce', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'day\').val(\''.dol_print_date($nowgmt, '%d', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'month\').val(\''.dol_print_date($nowgmt, '%m', 'tzuserrel').'\');'; - $reset_scripts .= 'jQuery(\'#'.$prefix.'year\').val(\''.dol_print_date($nowgmt, '%Y', 'tzuserrel').'\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . '\').val(\'' . dol_print_date($nowgmt, 'dayinputnoreduce', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'day\').val(\'' . dol_print_date($nowgmt, '%d', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'month\').val(\'' . dol_print_date($nowgmt, '%m', 'tzuserrel') . '\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'year\').val(\'' . dol_print_date($nowgmt, '%Y', 'tzuserrel') . '\');'; // Update the hour part if ($h) { if ($fullday) { $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; } - $reset_scripts .= 'jQuery(\'#'.$prefix.'hour\').val(\''.dol_print_date($nowgmt, '%H', 'tzuserrel').'\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'hour\').val(\'' . dol_print_date($nowgmt, '%H', 'tzuserrel') . '\');'; if ($fullday) { $reset_scripts .= ' } '; } @@ -6940,14 +6992,14 @@ class Form if ($fullday) { $reset_scripts .= " if (jQuery('#fullday:checked').val() == null) {"; } - $reset_scripts .= 'jQuery(\'#'.$prefix.'min\').val(\''.dol_print_date($nowgmt, '%M', 'tzuserrel').'\');'; + $reset_scripts .= 'jQuery(\'#' . $prefix . 'min\').val(\'' . dol_print_date($nowgmt, '%M', 'tzuserrel') . '\');'; if ($fullday) { $reset_scripts .= ' } '; } } // If reset_scripts is not empty, print the link with the reset_scripts in the onClick if ($reset_scripts && empty($conf->dol_optimize_smallscreen)) { - $retstring .= ' '; } @@ -6959,7 +7011,7 @@ class Form if (empty($labeladddateof)) { $labeladddateof = $langs->trans("DateInvoice"); } - $retstring .= ' -
'; + } else { + $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + } + } + + if ($withpicto != 2) { + $result .= $this->ref; + } + + $result .= $linkend; + //if ($withpicto != 2) $result.=(($addlabel && $this->label) ? $sep . dol_trunc($this->label, ($addlabel > 1 ? $addlabel : 0)) : ''); + + global $action, $hookmanager; + $hookmanager->initHooks(array($this->element.'dao')); + $parameters = array('id'=>$this->id, 'getnomurl' => &$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) { + $result = $hookmanager->resPrint; + } else { + $result .= $hookmanager->resPrint; + } + + return $result; + } + + /** + * Return a thumb for kanban views + * + * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link) + * @param array $arraydata Array of data + * @return string HTML Code for Kanban thumb. + */ + public function getKanbanView($option = '', $arraydata = null) + { + global $conf, $langs; + $return = '
'; + $return .= '
'; + $return .= ''; + $return .= img_picto('', $this->picto); + $return .= ''; + $return .= '
'; + $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + if (property_exists($this, 'label')) { + $return .= '
'.$this->label.'
'; + } + if (property_exists($this, 'amount')) { + $return .= '
'; + $return .= ''.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency).''; + } + if (method_exists($this, 'getLibStatut')) { + $return .= '
'.$this->getLibStatut(5).'
'; + } + $return .= '
'; + $return .= '
'; + $return .= '
'; + + return $return; + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLabelStatus($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + /** + * Return the label of the status + * + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function getLibStatut($mode = 0) + { + return $this->LibStatut($this->status, $mode); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return the status + * + * @param int $status Id status + * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto + * @return string Label of status + */ + public function LibStatut($status, $mode = 0) + { + // phpcs:enable + if (empty($this->labelStatus) || empty($this->labelStatusShort)) { + global $langs; + //$langs->load("timespent@timespent"); + $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); + $this->labelStatus[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled'); + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Enabled'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->transnoentitiesnoconv('Disabled'); + } + + $statusType = 'status'.$status; + //if ($status == self::STATUS_VALIDATED) $statusType = 'status1'; + if ($status == self::STATUS_CANCELED) { + $statusType = 'status6'; + } + + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); + } + + /** + * Load the info information in the object + * + * @param int $id Id of object + * @return void + */ + public function info($id) + { + $sql = "SELECT rowid,"; + $sql .= " date_creation as datec, tms as datem,"; + $sql .= " fk_user_creat, fk_user_modif"; + $sql .= " FROM ".MAIN_DB_PREFIX.$this->table_element." as t"; + $sql .= " WHERE t.rowid = ".((int) $id); + + $result = $this->db->query($sql); + if ($result) { + if ($this->db->num_rows($result)) { + $obj = $this->db->fetch_object($result); + + $this->id = $obj->rowid; + + $this->user_creation_id = $obj->fk_user_creat; + $this->user_modification_id = $obj->fk_user_modif; + if (!empty($obj->fk_user_valid)) { + $this->user_validation_id = $obj->fk_user_valid; + } + $this->date_creation = $this->db->jdate($obj->datec); + $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem); + if (!empty($obj->datev)) { + $this->date_validation = empty($obj->datev) ? '' : $this->db->jdate($obj->datev); + } + } + + $this->db->free($result); + } else { + dol_print_error($this->db); + } + } + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + public function initAsSpecimen() + { + // Set here init that are not commonf fields + // $this->property1 = ... + // $this->property2 = ... + + $this->initAsSpecimenCommon(); + } + + /** + * Create an array of lines + * + * @return array|int array of lines if OK, <0 if KO + */ + public function getLinesArray() + { + $this->lines = array(); + + $objectline = new TimeSpentLine($this->db); + $result = $objectline->fetchAll('ASC', 'position', 0, 0, array('customsql'=>'fk_timespent = '.((int) $this->id))); + + if (is_numeric($result)) { + $this->error = $objectline->error; + $this->errors = $objectline->errors; + return $result; + } else { + $this->lines = $result; + return $this->lines; + } + } + + /** + * Returns the reference to the following non used object depending on the active numbering module. + * + * @return string Object free reference + */ + public function getNextNumRef() + { + global $langs, $conf; + $langs->load("timespent@timespent"); + + if (empty($conf->global->TIMESPENT_timespent_ADDON)) { + $conf->global->TIMESPENT_timespent_ADDON = 'mod_timespent_standard'; + } + + if (!empty($conf->global->TIMESPENT_timespent_ADDON)) { + $mybool = false; + + $file = $conf->global->TIMESPENT_timespent_ADDON.".php"; + $classname = $conf->global->TIMESPENT_timespent_ADDON; + + // Include file with class + $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']); + foreach ($dirmodels as $reldir) { + $dir = dol_buildpath($reldir."core/modules/timespent/"); + + // Load file with numbering class (if found) + $mybool |= @include_once $dir.$file; + } + + if ($mybool === false) { + dol_print_error('', "Failed to include file ".$file); + return ''; + } + + if (class_exists($classname)) { + $obj = new $classname(); + $numref = $obj->getNextValue($this); + + if ($numref != '' && $numref != '-1') { + return $numref; + } else { + $this->error = $obj->error; + //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); + return ""; + } + } else { + print $langs->trans("Error")." ".$langs->trans("ClassNotFound").' '.$classname; + return ""; + } + } else { + print $langs->trans("ErrorNumberingModuleNotSetup", $this->element); + return ""; + } + } + + /** + * Create a document onto disk according to template module. + * + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @param null|array $moreparams Array to provide more information + * @return int 0 if KO, 1 if OK + */ + public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) + { + global $conf, $langs; + + $result = 0; + $includedocgeneration = 0; + + $langs->load("timespent@timespent"); + + if (!dol_strlen($modele)) { + $modele = 'standard_timespent'; + + if (!empty($this->model_pdf)) { + $modele = $this->model_pdf; + } elseif (!empty($conf->global->timespent_ADDON_PDF)) { + $modele = $conf->global->timespent_ADDON_PDF; + } + } + + $modelpath = "core/modules/timespent/doc/"; + + if ($includedocgeneration && !empty($modele)) { + $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams); + } + + return $result; + } + + /** + * Action executed by scheduler + * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' + * Use public function doScheduledJob($param1, $param2, ...) to get parameters + * + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function doScheduledJob() + { + //global $conf, $langs; + + //$conf->global->SYSLOG_FILE = 'DOL_DATA_ROOT/dolibarr_mydedicatedlofile.log'; + + $error = 0; + $this->output = ''; + $this->error = ''; + + dol_syslog(__METHOD__, LOG_DEBUG); + + $now = dol_now(); + + $this->db->begin(); + + // ... + + $this->db->commit(); + + return $error; + } +} diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index e54019a56b4..5273a37bc24 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -431,7 +431,7 @@ foreach ($newarrayoftype as $tmpkey => $tmpval) { $newarrayoftype[$tmpkey]['label'] = img_picto('', $tmpval['picto'], 'class="pictofixedwidth"').$langs->trans($tmpval['label']); } -print '
'; +print '
'; // Select object print '
'; @@ -863,7 +863,7 @@ if ($sql) { $xlabel = $object->fields[$xvalwithoutprefix]['arrayofkeyval'][$obj->$fieldforxkey]; } - $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->trans("Empty") : $langs->trans("NotDefined"))); + $labeltouse = (($xlabel || $xlabel == '0') ? dol_trunc($xlabel, 20, 'middle') : ($xlabel === '' ? $langs->transnoentitiesnoconv("Empty") : $langs->transnoentitiesnoconv("NotDefined"))); $xarrayforallseries = array('label' => $labeltouse); foreach ($search_measures as $key => $val) { $fieldfory = 'y_'.$key; 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 887d14fd36a..74947d9dd71 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1788,7 +1788,9 @@ function dolButtonToOpenUrlInDialogPopup($name, $label, $buttonstring, $url, $di if (empty($conf->use_javascript_ajax)) { $out .= ' href="'.DOL_URL_ROOT.$url.'" target="_blank"'; } elseif ($jsonopen) { - $out .= ' onclick="javascript:'.$jsonopen.'"'; + $out .= ' href="#" onclick="javascript:'.$jsonopen.'"'; + } else { + $out .= ' href="#"'; } $out .= '>'.$buttonstring.''; @@ -5433,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 { @@ -5473,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); @@ -5533,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 @@ -11585,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 */ @@ -11603,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).")"; 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 a4279d27a95..badeb47d6f4 100644 --- a/htdocs/core/lib/report.lib.php +++ b/htdocs/core/lib/report.lib.php @@ -48,17 +48,14 @@ function report_header($reportname, $notused, $period, $periodlink, $description $varlink = '?'.$varlink; } - $head = array(); + $title = $langs->trans("Report"); - $h = 0; - $head[$h][0] = $_SERVER["PHP_SELF"].$varlink; - $head[$h][1] = $langs->trans("Report"); - $head[$h][2] = 'report'; + print_barre_liste($title, 0, '', '', '', '', '', -1, '', 'generic', 0, '', '', -1, 1, 1); - print '
'."\n"; + print ''."\n"; print ''."\n"; - print dol_get_fiche_head($head, 'report'); + print dol_get_fiche_head(); foreach ($moreparam as $key => $value) { print ''."\n"; diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 0b9a52cdf0e..6f3ac2cdf0f 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -444,7 +444,7 @@ function dolWebsiteIncrementCounter($websiteid, $websitepagetype, $websitepageid $sql .= " pageviews_total = pageviews_total + 1,"; $sql .= " pageviews_month = pageviews_month + 1,"; // if last access was done during previous month, we save pageview_month into pageviews_previous_month - $sql .= " pageviews_previous_month = ".$db->ifsql("lastaccess < '".$db->idate(dol_mktime(0, 0, 0, $tmpnow['month'], 1, $tmpnow['year'], 'gmt', 0), 'gmt')."'", 'pageviews_month', 'pageviews_previous_month').","; + $sql .= " pageviews_previous_month = ".$db->ifsql("lastaccess < '".$db->idate(dol_mktime(0, 0, 0, $tmpnow['mon'], 1, $tmpnow['year'], 'gmt', 0), 'gmt')."'", 'pageviews_month', 'pageviews_previous_month').","; $sql .= " lastaccess = '".$db->idate(dol_now('gmt'), 'gmt')."'"; $sql .= " WHERE rowid = ".((int) $websiteid); $resql = $db->query($sql); diff --git a/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php b/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php index 00d57161e10..37bdd72fde0 100644 --- a/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php +++ b/htdocs/core/modules/bank/doc/pdf_sepamandate.modules.php @@ -504,7 +504,6 @@ class pdf_sepamandate extends ModeleBankAccountDoc } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** 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_invoice/doc/doc_generic_supplier_invoice_odt.modules.php b/htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php index c37eef06360..41ce5795ae6 100644 --- a/htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php +++ b/htdocs/core/modules/supplier_invoice/doc/doc_generic_supplier_invoice_odt.modules.php @@ -49,9 +49,9 @@ class doc_generic_supplier_invoice_odt extends ModelePDFSuppliersInvoices /** * @var array Minimum version of PHP required by module. - * e.g.: PHP ≥ 5.6 = array(5, 6) + * e.g.: PHP ≥ 7.0 = array(7, 0) */ - public $phpmin = array(5, 6); + public $phpmin = array(7, 0); /** * @var string Dolibarr version of the loaded document @@ -122,9 +122,10 @@ class doc_generic_supplier_invoice_odt extends ModelePDFSuppliersInvoices $texte = $this->description.".
\n"; $texte .= ''; $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= ''; - $texte .= ''; + $texte .= '
'; // List of directories area $texte .= ''; - $texte .= ''; $texte .= ''; diff --git a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php index 8a747775b3f..8e40a21a1e4 100644 --- a/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php +++ b/htdocs/core/modules/supplier_order/doc/doc_generic_supplier_order_odt.modules.php @@ -119,7 +119,7 @@ class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders $form = new Form($this->db); $texte = $this->description.".
\n"; - $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= ''; $texte .= ''; @@ -181,7 +181,11 @@ class doc_generic_supplier_order_odt extends ModelePDFSuppliersOrders } $texte .= ''; } - + // Add input to upload a new template file. + $texte .= '
'.$langs->trans("UploadNewTemplate").' '; + $texte .= ''; + $texte .= ''; + $texte .= '
'; $texte .= ''; $texte .= ''; diff --git a/htdocs/core/website.inc.php b/htdocs/core/website.inc.php index d9fe10c8868..769f8edd8a4 100644 --- a/htdocs/core/website.inc.php +++ b/htdocs/core/website.inc.php @@ -51,7 +51,7 @@ if (!is_object($website)) { $website->fetch(0, $websitekey); } // Define $websitepage if we have $websitepagefile defined -if (!$pageid && !empty($websitepagefile)) { +if (empty($pageid) && !empty($websitepagefile)) { $pageid = str_replace(array('.tpl.php', 'page'), array('', ''), basename($websitepagefile)); if ($pageid == 'index.php') { $pageid = $website->fk_default_home; diff --git a/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php b/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php index 4ddcac9af7c..a74669e5238 100644 --- a/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php +++ b/htdocs/debugbar/class/DataCollector/DolRequestDataCollector.php @@ -62,7 +62,7 @@ class DolRequestDataCollector extends RequestDataCollector /** * Return widget settings * - * @return void + * @return array */ public function getWidgets() { diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php index 01b1e1bf6cc..76ddd7e67de 100644 --- a/htdocs/don/class/don.class.php +++ b/htdocs/don/class/don.class.php @@ -1154,6 +1154,8 @@ class Don extends CommonObject { global $langs; + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -1161,6 +1163,7 @@ class Don extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; + $return .= ''; if (property_exists($this, 'date')) { $return .= ' | '.$langs->trans("Date").' : '.dol_print_date($this->date).''; } diff --git a/htdocs/eventorganization/class/conferenceorbooth.class.php b/htdocs/eventorganization/class/conferenceorbooth.class.php index 658aa8d5bb5..8bbf0fdd1b9 100644 --- a/htdocs/eventorganization/class/conferenceorbooth.class.php +++ b/htdocs/eventorganization/class/conferenceorbooth.class.php @@ -106,7 +106,7 @@ class ConferenceOrBooth extends ActionComm 'id' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), 'ref' => array('type'=>'integer', 'label'=>'Ref', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>2, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'csslist'=>'left', 'comment'=>"Id"), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'csslist'=>'tdoverflowmax125', 'help'=>"OrganizationEvenLabelName", 'showoncombobox'=>'1', 'autofocusoncreate'=>1), - 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1:(t.usage_organize_event:=:1)', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'position'=>52, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'project', 'css'=>'tdoverflowmax150 maxwidth500', 'csslist'=>'width100'), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1:(t.usage_organize_event:=:1)', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'position'=>52, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'project', 'css'=>'tdoverflowmax150 maxwidth500', 'csslist'=>'nowraponall'), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'help'=>"OrganizationEventLinkToThirdParty", 'picto'=>'company', 'csslist'=>'tdoverflowmax125', 'css'=>'maxwidth500'), 'note' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3), 'fk_action' => array('type'=>'sellist:c_actioncomm:libelle:id::module LIKE (\'%@eventorganization\')', 'label'=>'Format', 'enabled'=>'1', 'position'=>60, 'notnull'=>1, 'visible'=>1, 'css'=>'width100', 'csslist'=>'tdoverflowmax100'), diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index 3ad6e2702c0..4a67003180f 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -921,9 +921,9 @@ while ($i < $imaxinloop) { } if (in_array($val['type'], array('timestamp'))) { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall'; } elseif ($key == 'ref') { - $cssforfield .= ($cssforfield ? ' ' : '').'nowrap'; + $cssforfield .= ($cssforfield ? ' ' : '').'nowraponall'; } if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && !in_array($key, array('rowid', 'ref', 'status')) && empty($val['arrayofkeyval'])) { 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.class.php b/htdocs/expensereport/class/expensereport.class.php index 4bac14b34f1..ebbc83302d5 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -2375,7 +2375,7 @@ class ExpenseReport extends CommonObject * Return list of people with permission to validate expense reports. * Search for permission "approve expense report" * - * @return array Array of user ids + * @return array|int Array of user ids, <0 if KO */ public function fetch_users_approver_expensereport() { @@ -2772,7 +2772,10 @@ class ExpenseReport extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { - global $langs, $selected,$arrayofselected; + global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -2780,9 +2783,6 @@ class ExpenseReport extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; - if (in_array($this->id, $arrayofselected)) { - $selected = 1; - } $return .= ''; if (property_exists($this, 'fk_user_author') && !empty($this->id)) { $return .= '
'.$this->fk_user_author.''; 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/expensereport/class/paymentexpensereport.class.php b/htdocs/expensereport/class/paymentexpensereport.class.php index 955181cf632..0d056a1f9e4 100644 --- a/htdocs/expensereport/class/paymentexpensereport.class.php +++ b/htdocs/expensereport/class/paymentexpensereport.class.php @@ -724,6 +724,9 @@ class PaymentExpenseReport extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -731,6 +734,7 @@ class PaymentExpenseReport extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; + $return .= ''; if (property_exists($this, 'datep')) { $return .= '
'.$langs->trans("Date").' : '.dol_print_date($this->db->jdate($this->datep), 'dayhour').''; } 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 e739ee0806e..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'; @@ -1488,6 +1488,9 @@ class Fichinter extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -1496,6 +1499,7 @@ class Fichinter extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'socid')) { $return .= '
'.$this->socid.''; } 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 '
'; @@ -161,7 +162,7 @@ class doc_generic_supplier_invoice_odt extends ModelePDFSuppliersInvoices $texte .= $conf->global->SUPPLIER_INVOICE_ADDON_PDF_ODT_PATH; $texte .= ''; $texte .= '
'; - $texte .= ''; + $texte .= ''; $texte .= '
'; // Scan directories @@ -178,7 +179,9 @@ class doc_generic_supplier_invoice_odt extends ModelePDFSuppliersInvoices $texte .= '
'; // Show list of found files foreach ($listoffiles as $file) { - $texte .= '- '.$file['name'].' '.img_picto('', 'listlight').'
'; + $texte .= '- '.$file['name'].' '.img_picto('', 'listlight').''; + $texte .= '   '.img_picto('', 'delete').''; + $texte .= '
'; } $texte .= '
'; } @@ -189,9 +192,10 @@ class doc_generic_supplier_invoice_odt extends ModelePDFSuppliersInvoices $texte .= ''; $texte .= '
'; + $texte .= ''; $texte .= $langs->trans("ExampleOfDirectoriesForModelGen"); + $texte .= ''; $texte .= '
'; 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/modules/supplier_proposal/mod_supplier_proposal_saphir.php b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php index 063591e5486..e4eecb4fa7b 100644 --- a/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php +++ b/htdocs/core/modules/supplier_proposal/mod_supplier_proposal_saphir.php @@ -83,7 +83,7 @@ class mod_supplier_proposal_saphir extends ModeleNumRefSupplierProposal $tooltip .= $langs->trans("GenericMaskCodes4a", $langs->transnoentities("CommRequest"), $langs->transnoentities("CommRequest")); $tooltip .= $langs->trans("GenericMaskCodes5"); - $mask = dolGetGlobalString('SUPPLIER_PROPOSAL_SAPHIR_MASK'); + $mask = getDolGlobalString('SUPPLIER_PROPOSAL_SAPHIR_MASK'); // Parametrage du prefix $texte .= '
'.$langs->trans("Mask").':
'; -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.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 17033086e69..bcccc5b9aa3 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -529,7 +529,7 @@ class CommandeFournisseur extends CommonOrder $this->lines = array(); - $sql = "SELECT l.rowid, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description, l.qty,"; + $sql = "SELECT l.rowid, l.fk_commande, l.ref as ref_supplier, l.fk_product, l.product_type, l.label, l.description, l.qty,"; $sql .= " l.vat_src_code, l.tva_tx, l.remise_percent, l.subprice,"; $sql .= " l.localtax1_tx, l. localtax2_tx, l.localtax1_type, l. localtax2_type, l.total_localtax1, l.total_localtax2,"; $sql .= " l.total_ht, l.total_tva, l.total_ttc, l.special_code, l.fk_parent_line, l.rang,"; @@ -559,6 +559,7 @@ class CommandeFournisseur extends CommonOrder $line = new CommandeFournisseurLigne($this->db); $line->id = $objp->rowid; + $line->fk_commande = $objp->fk_commande; $line->desc = $objp->description; $line->description = $objp->description; $line->qty = $objp->qty; @@ -3633,6 +3634,9 @@ class CommandeFournisseur extends CommonOrder public function getKanbanView($option = '', $arraydata = null) { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -3641,6 +3645,7 @@ class CommandeFournisseur extends CommonOrder $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'socid') || property_exists($this, 'total_tva')) { $return .='
'.$this->socid.''; } diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index f635dcab2c5..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; } @@ -3286,6 +3284,9 @@ class FactureFournisseur extends CommonInvoice public function getKanbanView($option = '', $arraydata = null) { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -3293,6 +3294,7 @@ class FactureFournisseur extends CommonInvoice $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; + $return .= ''; if (property_exists($this, 'socid')) { $return .= ' | '.$this->socid.''; } diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 1e99141c95c..f79c9fe49b4 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1704,7 +1704,8 @@ if ($action == 'create') { $("input[name=action]").val("create"); $("form[name=add]").submit(); }); - '; + }); + '; } print ' '; } @@ -1731,13 +1732,13 @@ if ($action == 'create') { // Payment term print ''.$langs->trans('PaymentConditionsShort').''; print img_picto('', 'payment', 'class="pictofixedwidth"'); - print $form->getSelectConditionsPaiements(GETPOSTISSET('cond_reglement_id') ? GETPOST('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id'); + print $form->getSelectConditionsPaiements((GETPOSTISSET('cond_reglement_id') && GETPOST('cond_reglement_id') != 0) ? GETPOST('cond_reglement_id') : $cond_reglement_id, 'cond_reglement_id', -1, 1); print ''; // Payment mode print ''.$langs->trans('PaymentMode').''; print img_picto('', 'bank', 'class="pictofixedwidth"'); - $form->select_types_paiements(GETPOSTISSET('mode_reglement_id') ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id'); + $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') && GETPOST('mode_reglement_id') != 0) ? GETPOST('mode_reglement_id') : $mode_reglement_id, 'mode_reglement_id'); print ''; // Planned delivery date @@ -2086,7 +2087,7 @@ if ($action == 'create') { } print ''.$langs->trans("Date").''; print $object->date_commande ? dol_print_date($object->date_commande, $usehourmin ? 'dayhour' : 'day') : ''; - if ($object->hasDelay() && !empty($object->date_delivery) && !empty($object->date_commande)) { + if ($object->hasDelay() && !empty($object->delivery_date) && !empty($object->date_commande)) { print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning"); } print ""; @@ -2256,7 +2257,7 @@ if ($action == 'create') { $usehourmin = 1; } print $form->selectDate($object->delivery_date ? $object->delivery_date : -1, 'liv_', $usehourmin, $usehourmin, '', "setdate_livraison"); - print ''; + print ''; print ''; } else { $usehourmin = 'day'; @@ -2264,7 +2265,7 @@ if ($action == 'create') { $usehourmin = 'dayhour'; } print $object->delivery_date ? dol_print_date($object->delivery_date, $usehourmin) : ' '; - if ($object->hasDelay() && !empty($object->delivery_date)) { + if ($object->hasDelay() && !empty($object->delivery_date) && ($object->statut == $object::STATUS_ORDERSENT || $object->statut == $object::STATUS_RECEIVED_PARTIALLY)) { print ' '.img_picto($langs->trans("Late").' : '.$object->showDelay(), "warning"); } } diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index 8fe15381a96..2baa2cade8c 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -1771,7 +1771,7 @@ while ($i < $imaxinloop) { if (!empty($arrayfields['u.login']['checked'])) { print ''; if ($userstatic->id) { - print $userstatic->getLoginUrl(-1); + print $userstatic->getNomUrl(-1); } else { print ' '; } diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 619d8a3fc85..341b0c700e1 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -2476,6 +2476,8 @@ class Holiday extends CommonObject { global $langs; + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -2483,6 +2485,7 @@ class Holiday extends CommonObject $return .= ''; $return .= '
'; $return .= ''.$arraydata['user']->getNomUrl(-1).''; + $return .= ''; if (property_exists($this, 'fk_type')) { $return .= '
'.$langs->trans("Type").' : '; $return .= ''.arraydata['labeltype'].''; diff --git a/htdocs/hrm/class/evaluation.class.php b/htdocs/hrm/class/evaluation.class.php index ab87aaeeef5..803963a27e2 100644 --- a/htdocs/hrm/class/evaluation.class.php +++ b/htdocs/hrm/class/evaluation.class.php @@ -1066,6 +1066,9 @@ class Evaluation extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $selected, $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; diff --git a/htdocs/hrm/class/job.class.php b/htdocs/hrm/class/job.class.php index b0a1d263b65..bbcdcf4c1df 100644 --- a/htdocs/hrm/class/job.class.php +++ b/htdocs/hrm/class/job.class.php @@ -1066,6 +1066,8 @@ class Job extends CommonObject { global $selected, $langs; + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; diff --git a/htdocs/hrm/class/position.class.php b/htdocs/hrm/class/position.class.php index 4cb0eb670f8..d2e98a7f28b 100644 --- a/htdocs/hrm/class/position.class.php +++ b/htdocs/hrm/class/position.class.php @@ -1129,6 +1129,9 @@ class Position extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $selected, $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; diff --git a/htdocs/hrm/class/skill.class.php b/htdocs/hrm/class/skill.class.php index 44cea026320..42be9146978 100644 --- a/htdocs/hrm/class/skill.class.php +++ b/htdocs/hrm/class/skill.class.php @@ -1125,6 +1125,8 @@ class Skill extends CommonObject { global $selected, $langs; + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; diff --git a/htdocs/hrm/evaluation_list.php b/htdocs/hrm/evaluation_list.php index b4c0ebe9f02..a9749c46d7e 100644 --- a/htdocs/hrm/evaluation_list.php +++ b/htdocs/hrm/evaluation_list.php @@ -134,10 +134,10 @@ $object->fields = dol_sort_array($object->fields, 'position'); $arrayfields = dol_sort_array($arrayfields, 'position'); // Permissions -$permissiontoread = $user->hasRight('hrm', 'evaluation', 'read'); +$permissiontoread = $user->hasRight('hrm', 'evaluation', 'read'); $permissiontoreadall = $user->hasRight('hrm', 'evaluation', 'readall'); -$permissiontoadd = $user->hasRight('hrm', 'evaluation', 'write'); -$permissiontodelete = $user->hasRight('hrm', 'evaluation', 'delete'); +$permissiontoadd = $user->hasRight('hrm', 'evaluation', 'write'); +$permissiontodelete = $user->hasRight('hrm', 'evaluation', 'delete'); // Security check if (!isModEnabled('hrm')) { 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_bordereau_cheque.sql b/htdocs/install/mysql/tables/llx_bordereau_cheque.sql index 9b1d6e24ad4..65100ccaae1 100644 --- a/htdocs/install/mysql/tables/llx_bordereau_cheque.sql +++ b/htdocs/install/mysql/tables/llx_bordereau_cheque.sql @@ -26,6 +26,7 @@ create table llx_bordereau_cheque rowid integer AUTO_INCREMENT PRIMARY KEY, ref varchar(30) NOT NULL, -- ref ref_ext varchar(255), -- ref_ext + type varchar(6) DEFAULT 'CHQ', -- 'CHQ', 'TRA', ... datec datetime NOT NULL, date_bordereau date, amount double(24,8) NOT NULL, 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 7f76261bcea..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; } } @@ -4222,12 +4223,12 @@ function migrate_delete_old_dir($db, $langs, $conf) * @param Conf $conf Object conf * @param array $listofmodule List of modules, like array('MODULE_KEY_NAME'=>', $reloadmode) * @param int $force 1=Reload module even if not already loaded - * @return int <0 if KO, >0 if OK + * @return int <0 if KO, >0 if OK */ function migrate_reload_modules($db, $langs, $conf, $listofmodule = array(), $force = 0) { if (count($listofmodule) == 0) { - return; + return 0; } dolibarr_install_syslog("upgrade2::migrate_reload_modules force=".$force.", listofmodule=".join(',', array_keys($listofmodule))); diff --git a/htdocs/knowledgemanagement/class/knowledgerecord.class.php b/htdocs/knowledgemanagement/class/knowledgerecord.class.php index 15682d00fc9..4af7cd2bd27 100644 --- a/htdocs/knowledgemanagement/class/knowledgerecord.class.php +++ b/htdocs/knowledgemanagement/class/knowledgerecord.class.php @@ -1125,7 +1125,10 @@ class KnowledgeRecord extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { - global $langs, $selected,$arrayofselected; + global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -1133,9 +1136,6 @@ class KnowledgeRecord extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; - if (in_array($this->id, $arrayofselected)) { - $selected = 1; - } $return .= ''; if (property_exists($this, 'lang') && !empty($this->lang)) { //$return .= '
'.$langs->trans("Language").' : lang).'">'.$langs->trans("Language_".$this->lang, '', '', '', '', 12).''; 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/banks.lang b/htdocs/langs/en_US/banks.lang index 7be02da2c27..2c895b48034 100644 --- a/htdocs/langs/en_US/banks.lang +++ b/htdocs/langs/en_US/banks.lang @@ -120,6 +120,7 @@ ValidateCheckReceipt=Validate this check receipt? ConfirmValidateCheckReceipt=Are you sure that you want to submit this check receipt for validation? No changes will be possible once validated. DeleteCheckReceipt=Delete this check receipt? ConfirmDeleteCheckReceipt=Are you sure you want to delete this check receipt? +DocumentsForDeposit=Documents to deposit at the bank BankChecks=Bank checks BankChecksToReceipt=Checks awaiting deposit BankChecksToReceiptShort=Checks awaiting deposit @@ -145,6 +146,7 @@ BackToAccount=Back to account ShowAllAccounts=Show for all accounts FutureTransaction=Future transaction. Unable to reconcile. SelectChequeTransactionAndGenerate=Select/filter the checks which are to be included in the check deposit receipt. Then, click on "Create". +SelectPaymentTransactionAndGenerate=Select/filter the documents which are to be included in the %s deposit receipt. Then, click on "Create". InputReceiptNumber=Choose the bank statement related with the conciliation. Use a sortable numeric value: YYYYMM or YYYYMMDD EventualyAddCategory=Eventually, specify a category in which to classify the records ToConciliate=To reconcile? diff --git a/htdocs/langs/en_US/bills.lang b/htdocs/langs/en_US/bills.lang index 7ad897ab0e2..798ba129288 100644 --- a/htdocs/langs/en_US/bills.lang +++ b/htdocs/langs/en_US/bills.lang @@ -509,13 +509,14 @@ UseLine=Apply UseDiscount=Use discount UseCredit=Use credit UseCreditNoteInInvoicePayment=Reduce amount to pay with this credit -MenuChequeDeposits=Check Deposits +MenuChequeDeposits=Deposits slips MenuCheques=Checks -MenuChequesReceipts=Check receipts -NewChequeDeposit=New deposit -ChequesReceipts=Check receipts -ChequesArea=Check deposits area -ChequeDeposits=Check deposits +MenuChequesReceipts=Deposit slips +NewChequeDeposit=New deposit slip +ChequesReceipts=Cheque deposit slips +DocumentsDepositArea=Deposit slip area +ChequesArea=Deposit slips area +ChequeDeposits=Deposit slips Cheques=Checks DepositId=Id deposit NbCheque=Number of checks diff --git a/htdocs/langs/en_US/compta.lang b/htdocs/langs/en_US/compta.lang index b3d5f675830..1112d4647bb 100644 --- a/htdocs/langs/en_US/compta.lang +++ b/htdocs/langs/en_US/compta.lang @@ -130,14 +130,17 @@ SalesTurnoverMinimum=Minimum turnover ByExpenseIncome=By expenses & incomes ByThirdParties=By third parties ByUserAuthorOfInvoice=By invoice author -CheckReceipt=Check deposit -CheckReceiptShort=Check deposit -LastCheckReceiptShort=Latest %s check receipts +CheckReceipt=Deposit slip +CheckReceiptShort=Deposit slip +LastCheckReceiptShort=Latest %s deposit slips +LastPaymentForDepositShort=Latest %s %s deposit slips NewCheckReceipt=New discount -NewCheckDeposit=New check deposit +NewCheckDeposit=New deposit slip NewCheckDepositOn=Create receipt for deposit on account: %s NoWaitingChecks=No checks awaiting deposit. +NoWaitingPaymentForDeposit=No %s payment awaiting deposit. DateChequeReceived=Check receiving date +DatePaymentReceived=Date of document reception NbOfCheques=No. of checks PaySocialContribution=Pay a social/fiscal tax PayVAT=Pay a VAT declaration @@ -156,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/en_US/contracts.lang b/htdocs/langs/en_US/contracts.lang index ab94a63bcc3..6b83094fabe 100644 --- a/htdocs/langs/en_US/contracts.lang +++ b/htdocs/langs/en_US/contracts.lang @@ -2,7 +2,7 @@ ContractsArea=Contracts area ListOfContracts=List of contracts AllContracts=All contracts -ContractCard=Contract card +ContractCard=Contract ContractStatusNotRunning=Not running ContractStatusDraft=Draft ContractStatusValidated=Validated diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang index e94b6bbafe4..1e924d96448 100644 --- a/htdocs/langs/en_US/languages.lang +++ b/htdocs/langs/en_US/languages.lang @@ -32,6 +32,7 @@ Language_en_AU=English (Australia) Language_en_CA=English (Canada) Language_en_GB=English (United Kingdom) Language_en_IN=English (India) +Language_en_MY=English (Myanmar) Language_en_NZ=English (New Zealand) Language_en_SA=English (Saudi Arabia) Language_en_SG=English (Singapore) diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index dbb4e53f94b..edcb5923af0 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -174,3 +174,6 @@ MenuDeletedSuccessfuly=Menu has been successfully deleted MenuAddedSuccessfuly=Menu has been successfully added MenuUpdatedSuccessfuly=Menu has been successfully updated ApiObjectDeleted=API for object %s has been successfully deleted +CRUDRead=Read +CRUDCreateWrite=Create or Update +FailedToAddCodeIntoDescriptor=Failed to add code into descriptor. Check that the string comment "%s" is still present into the file. \ No newline at end of file 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/loan/class/loan.class.php b/htdocs/loan/class/loan.class.php index ef44b2fb196..5b807779634 100644 --- a/htdocs/loan/class/loan.class.php +++ b/htdocs/loan/class/loan.class.php @@ -733,6 +733,9 @@ class Loan extends CommonObject public function getKanbanView($option = '') { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -740,6 +743,7 @@ class Loan extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; + $return .= ''; if (property_exists($this, 'capital')) { $return .= ' | '.$langs->trans("Amount").' : '.price($this->capital).''; } diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index 16464caa03a..04d0f290732 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -401,27 +401,29 @@ if ($dirins && in_array($action, array('initapi', 'initphpunit', 'initpagecontac $modulename = ucfirst($module); // Force first letter in uppercase $objectname = $tabobj; $varnametoupdate = ''; + $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; + $destdir = $dirins.'/'.strtolower($module); + + // Get list of existing objects + $objects = array(); + $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); + foreach ($listofobject as $fileobj) { + if (preg_match('/^api_/', $fileobj['name'])) { + continue; + } + if (preg_match('/^actions_/', $fileobj['name'])) { + continue; + } + + $tmpcontent = file_get_contents($fileobj['fullname']); + $reg = array(); + if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { + $objectnameloop = $reg[1]; + $objects[$fileobj['fullname']] = $objectnameloop; + } + } if ($action == 'initapi') { - $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; - $destdir = $dirins.'/'.strtolower($module); - $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); - $objects = array(); - foreach ($listofobject as $fileobj) { - if (preg_match('/^api_/', $fileobj['name'])) { - continue; - } - if (preg_match('/^actions_/', $fileobj['name'])) { - continue; - } - - $tmpcontent = file_get_contents($fileobj['fullname']); - $reg = array(); - if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { - $objectnameloop = $reg[1]; - $objects[] = $objectnameloop; - } - } if (file_exists($dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php')) { $result = dol_copy(DOL_DOCUMENT_ROOT.'/modulebuilder/template/class/api_mymodule.class.php', $dirins.'/'.strtolower($module).'/class/api_'.strtolower($module).'.class.php', 0, 1); } @@ -482,6 +484,7 @@ if ($dirins && in_array($action, array('initapi', 'initphpunit', 'initpagecontac 'MYOBJECT'=>strtoupper($objectname), '---Put here your own copyright and developer email---'=>dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '') ); + if (count($objects) > 1) { $file = $destfile; $content = file($file); @@ -913,10 +916,16 @@ if ($dirins && $action == 'addlanguage' && !empty($module)) { setEventMessages($langs->trans("ErrorFailToCopyFile", $srcfile, $destfile), null, 'errors'); } } else { - $srcfile = $diroflang.'/langs/en_US'; - $destfile = $diroflang.'/langs/'.$newlangcode; + $srcdir = $diroflang.'/langs/en_US'; + $srcfile = $diroflang.'/langs/en_US/'.$modulelowercase.'.lang'; + $destdir = $diroflang.'/langs/'.$newlangcode; - $result = dolCopyDir($srcfile, $destfile, 0, 0); + $arrayofreplacement = array(); + if (!dol_is_dir($srcfile) || !dol_is_file($srcfile)) { + $srcdir = DOL_DOCUMENT_ROOT.'/modulebuilder/template/langs/en_US'; + $arrayofreplacement = array('mymodule'=>$modulelowercase); + } + $result = dolCopyDir($srcdir, $destdir, 0, 0, $arrayofreplacement); } } else { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Language")), null, 'errors'); @@ -924,19 +933,18 @@ if ($dirins && $action == 'addlanguage' && !empty($module)) { } -// remove/delete File +// Remove/delete File if ($dirins && $action == 'confirm_removefile' && !empty($module)) { $objectname = $tabobj; - - $relativefilename = dol_sanitizePathName(GETPOST('file', 'restricthtml')); - $file_api = $dirins."/".$relativefilename; - - //check if have more than one object $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; $destdir = $dirins.'/'.strtolower($module); - $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); - $objects = array(); + $relativefilename = dol_sanitizePathName(GETPOST('file', 'restricthtml')); + + // Get list of existing objects + // TODO ALI This part of code is common at several places and is autonomous. So replace it with $objects = dolGetListOfObjectclasses($destdir); + $objects = array(); + $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); foreach ($listofobject as $fileobj) { if (preg_match('/^api_/', $fileobj['name'])) { continue; @@ -944,123 +952,66 @@ if ($dirins && $action == 'confirm_removefile' && !empty($module)) { if (preg_match('/^actions_/', $fileobj['name'])) { continue; } + $tmpcontent = file_get_contents($fileobj['fullname']); $reg = array(); if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { $objectnameloop = $reg[1]; - $objects[] = $objectnameloop; + $objects[$fileobj['fullname']] = $objectnameloop; } } - $existObj = 0; - $file = file_get_contents($file_api); - $objs = array(); - if (str_contains($file, $objectname)) { - $existObj++; - } - if ($existObj && count($objects) > 1) { - $begin = '/*CRUD FOR '.strtoupper($objectname).'*/'; - $end = '/*END CRUD FOR '.strtoupper($objectname).'*/'; - $varcomentedDel = "\t * @var ".$objectname." \$".strtolower($objectname)." {@type ".$objectname."}"; - $propsDel .= "\tpublic \$".strtolower($objectname).";"; - $constructObjDel .= "\t\t\$this->".strtolower($objectname)."= new ".$objectname."(\$this->db);"; - $content = file($file_api); - // for delete property and the initialization from the construct - foreach ($content as $lineNumber => &$lineContent) { - if (strpos($lineContent, $varcomentedDel) !== false) { - $lineContent = ''; + // Now we delete the file + if ($relativefilename) { + $dirnametodelete = dirname($relativefilename); + $filetodelete = $dirins.'/'.$relativefilename; + $dirtodelete = $dirins.'/'.$dirnametodelete; + + $result = dol_delete_file($filetodelete); + if (!$result) { + setEventMessages($langs->trans("ErrorFailToDeleteFile", basename($filetodelete)), null, 'errors'); + } else { + // If we delete a .sql file, we delete also the other .sql file + if (preg_match('/\.sql$/', $relativefilename)) { + if (preg_match('/\.key\.sql$/', $relativefilename)) { + $relativefilename = preg_replace('/\.key\.sql$/', '.sql', $relativefilename); + $filetodelete = $dirins.'/'.$relativefilename; + $result = dol_delete_file($filetodelete); + } elseif (preg_match('/\.sql$/', $relativefilename)) { + $relativefilename = preg_replace('/\.sql$/', '.key.sql', $relativefilename); + $filetodelete = $dirins.'/'.$relativefilename; + $result = dol_delete_file($filetodelete); + } } - if (strpos($lineContent, $propsDel) !== false) { - $lineContent = ''; + + if (dol_is_dir_empty($dirtodelete)) { + dol_delete_dir($dirtodelete); } - if (strpos($lineContent, $constructObjDel) !== false) { - $lineContent = ''; + + // Update descriptor file to comment file + if (in_array($tab, array('css', 'js'))) { + $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; + $arrayreplacement = array('/^\s*\''.preg_quote('/'.$relativefilename, '/').'\',*/m'=>' // \'/'.$relativefilename.'\','); + dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1); } - } - $allContent = implode("", $content); - file_put_contents($file_api, $allContent); - // for delete methods of object - $handle = fopen($file_api, "r"); - $i = 1; - $lines = array(); - while (($line = fgets($handle)) !== false) { - //search line begin - if (strpos($line, $begin) !== false) { - $start_line = $i; - // Copy lines until the end on array - while (($line = fgets($handle)) !== false) { - if (strpos($line, $end) !== false) { - $end_line = $i; - break; - } - $lines[] = $line; - $i++; - } - break; + + if (preg_match('/_extrafields/', $relativefilename)) { + // Now we update the object file to set $isextrafieldmanaged to 0 + $srcfile = $dirins.'/'.strtolower($module).'/class/'.strtolower($objectname).'.class.php'; + $arrayreplacement = array('/\$isextrafieldmanaged = 1;/' => '$isextrafieldmanaged = 0;'); + dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1); } - $i++; - } - $allContent = implode("", $lines); - //var_dump($allContent);exit; - $check = dolReplaceInFile($file_api, array($allContent => '')); - if ($check) { - dolReplaceInFile($file_api, array($begin => '', $end => '')); - setEventMessages($langs->trans("ApiObjectDeleted", $langs->transnoentities($objectname)), null); - } - fclose($handle); - } - if (count($objects) == 1 && $existObj) { - if ($relativefilename) { - $dirnametodelete = dirname($relativefilename); - $filetodelete = $dirins.'/'.$relativefilename; - $dirtodelete = $dirins.'/'.$dirnametodelete; - $result = dol_delete_file($filetodelete); - if (!$result) { - setEventMessages($langs->trans("ErrorFailToDeleteFile", basename($filetodelete)), null, 'errors'); - } else { - // If we delete a .sql file, we delete also the other .sql file - if (preg_match('/\.sql$/', $relativefilename)) { - if (preg_match('/\.key\.sql$/', $relativefilename)) { - $relativefilename = preg_replace('/\.key\.sql$/', '.sql', $relativefilename); - $filetodelete = $dirins.'/'.$relativefilename; - $result = dol_delete_file($filetodelete); - } elseif (preg_match('/\.sql$/', $relativefilename)) { - $relativefilename = preg_replace('/\.sql$/', '.key.sql', $relativefilename); - $filetodelete = $dirins.'/'.$relativefilename; - $result = dol_delete_file($filetodelete); - } - } - - if (dol_is_dir_empty($dirtodelete)) { - dol_delete_dir($dirtodelete); - } - - // Update descriptor file to comment file - if (in_array($tab, array('css', 'js'))) { - $srcfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; - $arrayreplacement = array('/^\s*\''.preg_quote('/'.$relativefilename, '/').'\',*/m'=>' // \'/'.$relativefilename.'\','); - dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1); - } - - if (preg_match('/_extrafields/', $relativefilename)) { - // Now we update the object file to set $isextrafieldmanaged to 0 - $srcfile = $dirins.'/'.strtolower($module).'/class/'.strtolower($objectname).'.class.php'; - $arrayreplacement = array('/\$isextrafieldmanaged = 1;/' => '$isextrafieldmanaged = 0;'); - dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1); - } - - // Now we update the lib file to set $showtabofpagexxx to 0 - $varnametoupdate = ''; - $reg = array(); - if (preg_match('/_([a-z]+)\.php$/', $relativefilename, $reg)) { - $varnametoupdate = 'showtabofpage'.$reg[1]; - } - if ($varnametoupdate) { - $srcfile = $dirins.'/'.strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php'; - $arrayreplacement = array('/\$'.$varnametoupdate.' = 1;/' => '$'.$varnametoupdate.' = 0;'); - dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1); - } + // Now we update the lib file to set $showtabofpagexxx to 0 + $varnametoupdate = ''; + $reg = array(); + if (preg_match('/_([a-z]+)\.php$/', $relativefilename, $reg)) { + $varnametoupdate = 'showtabofpage'.$reg[1]; + } + if ($varnametoupdate) { + $srcfile = $dirins.'/'.strtolower($module).'/lib/'.strtolower($module).'_'.strtolower($objectname).'.lib.php'; + $arrayreplacement = array('/\$'.$varnametoupdate.' = 1;/' => '$'.$varnametoupdate.' = 0;'); + dolReplaceInFile($srcfile, $arrayreplacement, '', 0, 0, 1); } } } @@ -1074,9 +1025,12 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); if ($result) { setEventMessages($result, null, 'errors'); + } else { + /* FIX ALI header must be after action. Always add an exit after a header. + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); + */ + setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); } - header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); - setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); } $objectname = ucfirst($objectname); @@ -1539,31 +1493,43 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { // Regenerate left menu entry in descriptor for $objectname $stringtoadd = " \$this->menu[\$r++]=array( + // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'fk_menu'=>'fk_mainmenu=mymodule', + // This is a Left menu entry 'type'=>'left', 'titre'=>'List MyObject', 'mainmenu'=>'mymodule', - 'leftmenu'=>'myobject', + 'leftmenu'=>'mymodule_myobject', 'url'=>'/mymodule/myobject_list.php', + // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'langs'=>'mymodule@mymodule', 'position'=>1100+\$r, + // Define condition to show or hide menu entry. Use '\$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected. 'enabled'=>'\$conf->mymodule->enabled', + // Use 'perms'=>'\$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'perms'=>'1', 'target'=>'', + // 0=Menu for internal users, 1=external users, 2=both 'user'=>2, ); \$this->menu[\$r++]=array( - 'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=myobject', + // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'fk_menu'=>'fk_mainmenu=mymodule,fk_leftmenu=mymodule_myobject', + // This is a Left menu entry 'type'=>'left', 'titre'=>'New MyObject', 'mainmenu'=>'mymodule', - 'leftmenu'=>'myobject', + 'leftmenu'=>'mymodule_myobject', 'url'=>'/mymodule/myobject_card.php?action=create', + // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'langs'=>'mymodule@mymodule', 'position'=>1100+\$r, + // Define condition to show or hide menu entry. Use '\$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '\$leftmenu==\'system\'' to show if leftmenu system is selected. 'enabled'=>'\$conf->mymodule->enabled', + // Use 'perms'=>'\$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'perms'=>'1', 'target'=>'', + // 0=Menu for internal users, 1=external users, 2=both 'user'=>2 );\n"; $stringtoadd = preg_replace('/MyObject/', $objectname, $stringtoadd); @@ -1572,13 +1538,14 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { $moduledescriptorfile = $destdir.'/core/modules/mod'.$module.'.class.php'; } - // TODO Allow a replace with regex using dolReplaceInFile with param arryreplacementisregex to 1 - // TODO Avoid duplicate addition - // load class and check if menu exist with same object name - $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; - dol_include_once($pathtofile); - $class = 'mod'.$module; + // TODO Allow a replace with regex using dolReplaceInFile with param arryreplacementisregex to 1 + // TODO Avoid duplicate addition + + // load class and check if menu exist with same object name + $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; + dol_include_once($pathtofile); + $class = 'mod'.$module; if (class_exists($class)) { try { $moduleobj = new $class($db); @@ -1587,8 +1554,8 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { dol_print_error($db, $e->getMessage()); } } - $menus = $moduleobj->menu; - $counter = 0 ; + $menus = $moduleobj->menu; + $counter = 0 ; foreach ($menus as $menu) { if ($menu['leftmenu'] == strtolower($objectname)) { $counter++; @@ -1597,8 +1564,9 @@ if ($dirins && $action == 'initobject' && $module && $objectname) { if (!$counter) { dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER LEFTMENU MYOBJECT */' => '/*LEFTMENU '.strtoupper($objectname).'*/'.$stringtoadd."\n\t\t".'/*END LEFTMENU '.strtoupper($objectname).'*/'."\n\t\t".'/* END MODULEBUILDER LEFTMENU MYOBJECT */')); } - // Add module descriptor to list of files to replace "MyObject' string with real name of object. - $filetogenerate[] = 'core/modules/mod'.$module.'.class.php'; + + // Add module descriptor to list of files to replace "MyObject' string with real name of object. + $filetogenerate[] = 'core/modules/mod'.$module.'.class.php'; } if (!$error) { @@ -1940,9 +1908,13 @@ if ($dirins && $action == 'confirm_deleteobject' && $objectname) { dolibarr_set_const($db, "MAIN_IHM_PARAMS_REV", (int) $conf->global->MAIN_IHM_PARAMS_REV + 1, 'chaine', 0, '', $conf->entity); if ($result) { setEventMessages($result, null, 'errors'); + $error++; + } else { + /* TODO ALI Header redirect must be at end after actions. Also tab=pemrissions looks strange + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); + */ + setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); } - header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); - setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); } if (preg_match('/[^a-z0-9_]/i', $objectname)) { $error++; @@ -2244,15 +2216,32 @@ if ($dirins && $action == 'addright' && !empty($module) && empty($cancel)) { \$r++; "; $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; + + //var_dump($existRight.' '.$firstRight);exit; if (!$existRight) { dolReplaceInFile($moduledescriptorfile, array('/*END '.strtoupper($objectForPerms).'*/' => $rightToAdd.'/*END '.strtoupper($objectForPerms).'*/')); setEventMessages($langs->trans('PermissionAddedSuccesfuly'), null); } - if ($firstRight>0) { - dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER PERMISSIONS */' => '/*'.strtoupper($objectForPerms).'*/'.$rightToAdd."/*END ".strtoupper($objectForPerms).'*/'."\n\t\t".'/* END MODULEBUILDER PERMISSIONS */')); - setEventMessages($langs->trans('PermissionAddedSuccesfuly'), null); + if ($firstRight > 0) { + $filecontentbefore = file_get_contents($moduledescriptorfile); + + $result = dolReplaceInFile($moduledescriptorfile, array('/* END MODULEBUILDER PERMISSIONS */' => '/*'.strtoupper($objectForPerms).'*/'.$rightToAdd."/*END ".strtoupper($objectForPerms).'*/'."\n\t\t".'/* END MODULEBUILDER PERMISSIONS */')); + + $filecontentafter = file_get_contents($moduledescriptorfile); + + if ($filecontentbefore != $filecontentafter) { + setEventMessages($langs->trans('PermissionAddedSuccesfuly'), null); + } else { + setEventMessages($langs->trans('FailedToAddCodeIntoDescriptor', 'END MODULEBUILDER PERMISSIONS'), null, 'warnings'); + } } } + + clearstatcache(true); + if (function_exists('opcache_invalidate')) { + opcache_reset(); // remove the include cache hell ! + } + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); exit; } @@ -2336,6 +2325,7 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e } } + // TODO ALI Update of permission must be done by rewriting completely the permission section //prepare right want to delete $right = " \$this->rights[\$r][0] = \$this->numero . sprintf('%02d', \$r + 1); @@ -2352,6 +2342,7 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e \$this->rights[\$r][5] = '$crud'; \$r++; "; + if (!$error) { if (isModEnabled(strtolower($module))) { $result = unActivateModule(strtolower($module)); @@ -2366,8 +2357,14 @@ if ($dirins && GETPOST('action') == 'update_right' && GETPOST('modifyright')&& e $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; $check = dolReplaceInFile($moduledescriptorfile, array($right => $rightUpdated)); - header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); setEventMessages($langs->trans('PermissionUpdatedSuccesfuly'), null); + + clearstatcache(true); + if (function_exists('opcache_invalidate')) { + opcache_reset(); // remove the include cache hell ! + } + + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); exit; } } @@ -2377,7 +2374,7 @@ if ($dirins && $action == 'confirm_deleteright' && !empty($module) && GETPOST('p // load class and check if right exist $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; dol_include_once($pathtofile); - $class = 'mod'.$module; + $class = 'mod'.$module; if (class_exists($class)) { try { $moduleobj = new $class($db); @@ -2387,14 +2384,14 @@ if ($dirins && $action == 'confirm_deleteright' && !empty($module) && GETPOST('p } } - $permissions = $moduleobj->rights; - $key = (int) GETPOST('permskey', 'int')-1; - //get permission want to delete from permissions array - $x1 = $permissions[$key][1]; - $x2 = $permissions[$key][4]; - $x3 = $permissions[$key][5]; - //prepare right want to delete - $rightTodelete = " + $permissions = $moduleobj->rights; + $key = (int) GETPOST('permskey', 'int')-1; + //get permission want to delete from permissions array + $x1 = $permissions[$key][1]; + $x2 = $permissions[$key][4]; + $x3 = $permissions[$key][5]; + //prepare right want to delete + $rightTodelete = " \$this->rights[\$r][0] = \$this->numero . sprintf('%02d', \$r + 1); \$this->rights[\$r][1] = '$x1'; \$this->rights[\$r][4] = '$x2'; @@ -2402,9 +2399,11 @@ if ($dirins && $action == 'confirm_deleteright' && !empty($module) && GETPOST('p \$r++; "; + $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; + + // TODO ALI The delete must be done by rewriting all content between /* BEGIN MODULEBUILDER PERMISSIONS */ and /* END MODULEBUILDER PERMISSIONS */ + $check = dolReplaceInFile($moduledescriptorfile, array($rightTodelete => "\n\t\t")); - $moduledescriptorfile = $dirins.'/'.strtolower($module).'/core/modules/mod'.$module.'.class.php'; - $check = dolReplaceInFile($moduledescriptorfile, array($rightTodelete => "\n\t\t")); if ($check > 0) { //check if all permissions of object was deleted $permsForObj = array(); @@ -2424,13 +2423,20 @@ if ($dirins && $action == 'confirm_deleteright' && !empty($module) && GETPOST('p if ($result) { setEventMessages($result, null, 'errors'); } - header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); setEventMessages($langs->trans('PermissionDeletedSuccesfuly'), null); setEventMessages($langs->trans('WarningModuleNeedRefrech', $langs->transnoentities($module)), null, 'warnings'); + + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); exit; } else { - header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); setEventMessages($langs->trans('PermissionDeletedSuccesfuly'), null); + + clearstatcache(true); + if (function_exists('opcache_invalidate')) { + opcache_reset(); // remove the include cache hell ! + } + + header("Location: ".DOL_URL_ROOT.'/modulebuilder/index.php?tab=permissions&module='.$module); exit; } } @@ -2647,6 +2653,8 @@ if ($dirins && $action == 'addmenu' && empty($cancel)) { $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; $destdir = $dirins.'/'.strtolower($module); $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); + + // Get list of existing objets $objects = array(); foreach ($listofobject as $fileobj) { if (preg_match('/^api_/', $fileobj['name'])) { @@ -2660,7 +2668,7 @@ if ($dirins && $action == 'addmenu' && empty($cancel)) { $reg = array(); if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { $objectnameloop = $reg[1]; - $objects[] = $objectnameloop; + $objects[$fileobj['fullname']] = $objectnameloop; } } @@ -3355,15 +3363,15 @@ if ($module == 'initmodule') { $pathtochangelog = $modulelowercase.'/ChangeLog.md'; if ($action != 'editfile' || empty($file)) { - print dol_get_fiche_head($head2, $tab, '', -1, '', 0, '', '', $MAXTABFOROBJECT, 'formodulesuffix'); // Description - level 2 + $morehtmlright = ''; + if (realpath($dirread.'/'.$modulelowercase) != $dirread.'/'.$modulelowercase) { + $morehtmlright = '
'.$form->textwithpicto('', ''.$langs->trans("RealPathOfModule").' : '.realpath($dirread.'/'.$modulelowercase).'').'
'; + } + + print dol_get_fiche_head($head2, $tab, '', -1, '', 0, $morehtmlright, '', $MAXTABFOROBJECT, 'formodulesuffix'); // Description - level 2 print ''.$langs->trans("ModuleBuilderDesc".$tab).''; - $infoonmodulepath = ''; - if (realpath($dirread.'/'.$modulelowercase) != $dirread.'/'.$modulelowercase) { - $infoonmodulepath = ''.$langs->trans("RealPathOfModule").' : '.realpath($dirread.'/'.$modulelowercase).'
'; - print ' '.$infoonmodulepath; - } - print '
'; + print '

'; print ''; @@ -3401,7 +3409,8 @@ if ($module == 'initmodule') { print ''; @@ -3838,7 +3847,6 @@ if ($module == 'initmodule') { $urloflist = dol_buildpath('/'.$pathtolist, 1); $urlofcard = dol_buildpath('/'.$pathtocard, 1); - $file = file_get_contents($realpathtoapi); $objs = array(); print ''; @@ -3860,15 +3868,20 @@ if ($module == 'initmodule') { // API file print '
'; print ' '.$langs->trans("ApiClassFile").' : '.(dol_is_file($realpathtoapi) ? '' : '').preg_replace('/^'.strtolower($module).'\//', '', $pathtoapi).(dol_is_file($realpathtoapi)?'':'').''; - if (dol_is_file($realpathtoapi) && preg_match('/var '.$tabobj.'\s+([^\s]*)\s/ims', $file, $objs)) { - print ' '.img_picto($langs->trans("Edit"), 'edit').''; - print ' '; - print ''.img_picto($langs->trans("Delete"), 'delete').''; - print '   '; - if (empty($conf->global->$const_name)) { // If module is not activated - print ''.$langs->trans("ApiExplorer").''; + if (dol_is_file($realpathtoapi)) { + $file = file_get_contents($realpathtoapi); + if (preg_match('/var '.$tabobj.'\s+([^\s]*)\s/ims', $file, $objs)) { + print ' '.img_picto($langs->trans("Edit"), 'edit').''; + print ' '; + print ''.img_picto($langs->trans("Delete"), 'delete').''; + print '   '; + if (empty($conf->global->$const_name)) { // If module is not activated + print ''.$langs->trans("ApiExplorer").''; + } else { + print ''.$langs->trans("ApiExplorer").''; + } } else { - print ''.$langs->trans("ApiExplorer").''; + print ''.img_picto('AddAPIsForThisObject', 'generate', 'class="paddingleft"').''; } } else { print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; @@ -4602,6 +4615,8 @@ if ($module == 'initmodule') { $dirins = $listofmodules[strtolower($module)]['moduledescriptorrootpath']; $destdir = $dirins.'/'.strtolower($module); $listofobject = dol_dir_list($destdir.'/class', 'files', 0, '\.class\.php$'); + + // Get list of existing objects $objects = array(); foreach ($listofobject as $fileobj) { if (preg_match('/^api_/', $fileobj['name'])) { @@ -4615,7 +4630,7 @@ if ($module == 'initmodule') { $reg = array(); if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { $objectnameloop = $reg[1]; - $objects[] = $objectnameloop; + $objects[$fileobj['fullname']] = $objectnameloop; } } $menus = $moduleobj->menu; @@ -4861,7 +4876,7 @@ if ($module == 'initmodule') { $perms = $moduleobj->rights; - // Scan for object class files + // Get list of existing objects $dir = $dirread.'/'.$modulelowercase.'/class'; $listofobject = dol_dir_list($dir, 'files', 0, '\.class\.php$'); $objects = array('myobject'); @@ -4869,12 +4884,13 @@ if ($module == 'initmodule') { foreach ($listofobject as $fileobj) { $tmpcontent = file_get_contents($fileobj['fullname']); if (preg_match('/class\s+([^\s]*)\s+extends\s+CommonObject/ims', $tmpcontent, $reg)) { - $objects[] = $reg[1]; + $objects[$fileobj['fullname']] = $reg[1]; } } + // declared select list for actions and labels permissions - $crud = array('Read','Write','Delete'); - $labels = array("Read objects of $module","Create/Update objects of $module","Delete objects of $module"); + $crud = array('read'=>'CRUDRead', 'write'=>'CRUDCreateWrite', 'delete'=>'Delete'); + $labels = array("Read objects of ".$module, "Create/Update objects of ".$module, "Delete objects of ".$module); $action = GETPOST('action', 'alpha'); @@ -4919,18 +4935,18 @@ if ($module == 'initmodule') { print ''; print_liste_field_titre("ID", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center"); print_liste_field_titre("Label", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center"); - print_liste_field_titre("Permission", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center"); + print_liste_field_titre("Object", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center"); print_liste_field_titre("CRUD", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center"); print_liste_field_titre("", $_SERVER["PHP_SELF"], '', "", $param, '', $sortfield, $sortorder, "center"); print "\n"; //form for add new right - print ''; - print ''; + print ''; + print ''; print ''; @@ -4946,8 +4962,8 @@ if ($module == 'initmodule') { print ''; @@ -5016,7 +5032,7 @@ if ($module == 'initmodule') { print ''; print ''; print ''; print ''; print ''; + print ''; } print '
'; print $moduleobj->numero; print ''; - print '   ('.$langs->trans("SeeIDsInUse").''; + print '   ('; + print dolButtonToOpenUrlInDialogPopup('popup_modules_id', $langs->transnoentitiesnoconv("SeeIDsInUse"), $langs->transnoentitiesnoconv("SeeIDsInUse"), '/admin/system/modules.php?mainmenu=home&leftmenu=admintools_info', '', ''); print ' - '.$langs->trans("SeeReservedIDsRangeHere").')'; print ''; print '
'; print '
'; - print $perm[0]; + print dol_escape_htmltag($perm[0]); print ''; @@ -5024,7 +5040,7 @@ if ($module == 'initmodule') { print ''; - print $perm[4]; + print dol_escape_htmltag($perm[4]); print ''; @@ -5042,7 +5058,7 @@ if ($module == 'initmodule') { } } } else { - print '
'.$langs->trans("None").'
'.$langs->trans("None").'
'; diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 19d99557569..2a9b583b9e9 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -906,6 +906,9 @@ class MyObject extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $conf, $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -913,6 +916,7 @@ class MyObject extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'label')) { $return .= '
'.$this->label.'
'; } diff --git a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php index 66d0ae14d58..21397085729 100644 --- a/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php +++ b/htdocs/modulebuilder/template/core/modules/mymodule/doc/pdf_standard_myobject.modules.php @@ -882,7 +882,7 @@ class pdf_standard_myobject extends ModelePDFMyObject * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output * @param Translate $outputlangsbis Object lang for output bis - * @return void + * @return float|int */ protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null) { diff --git a/htdocs/modulebuilder/template/doc/Documentation.asciidoc b/htdocs/modulebuilder/template/doc/Documentation.asciidoc index 5a05c7011a6..a6dc59eea14 100644 --- a/htdocs/modulebuilder/template/doc/Documentation.asciidoc +++ b/htdocs/modulebuilder/template/doc/Documentation.asciidoc @@ -49,6 +49,16 @@ __README__ __DATA_SPECIFICATION__ +== MATRIX OF PERMISSIONS + +__DATA_PERMISSIONS__ + + +== OTHER + +__API_DOC__ + + == CHANGELOG //include::ChangeLog.md[] diff --git a/htdocs/modulebuilder/template/myobject_list.php b/htdocs/modulebuilder/template/myobject_list.php index 270ffbbf16f..ec5d8c979ed 100644 --- a/htdocs/modulebuilder/template/myobject_list.php +++ b/htdocs/modulebuilder/template/myobject_list.php @@ -269,9 +269,9 @@ $form = new Form($db); $now = dol_now(); +$title = $langs->trans("MyObjects"); //$help_url = "EN:Module_MyObject|FR:Module_MyObject_FR|ES:Módulo_MyObject"; $help_url = ''; -$title = $langs->trans("MyObjects"); $morejs = array(); $morecss = array(); diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index e5af1f2bddf..ee30c468358 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -1646,6 +1646,9 @@ class Mo extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -1654,6 +1657,7 @@ class Mo extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'fk_bom')) { $return .= '
'.$this->fk_bom.''; } diff --git a/htdocs/partnership/class/partnership.class.php b/htdocs/partnership/class/partnership.class.php index fcec2935103..63f0374f77f 100644 --- a/htdocs/partnership/class/partnership.class.php +++ b/htdocs/partnership/class/partnership.class.php @@ -1334,7 +1334,8 @@ class Partnership extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { - global $conf, $langs; + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -1342,6 +1343,7 @@ class Partnership extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'label')) { $return .= '
'.$this->label.'
'; } 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/class/product.class.php b/htdocs/product/class/product.class.php index d4a30517068..28fa20a0083 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -6370,6 +6370,8 @@ class Product extends CommonObject { global $langs,$conf; + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= '
'; @@ -6388,6 +6390,7 @@ class Product extends CommonObject $return .= '
'; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'label')) { $return .= '
'.$this->label.''; } diff --git a/htdocs/product/class/productbatch.class.php b/htdocs/product/class/productbatch.class.php index 52a39205b14..750e5d5bd7c 100644 --- a/htdocs/product/class/productbatch.class.php +++ b/htdocs/product/class/productbatch.class.php @@ -431,7 +431,7 @@ class Productbatch extends CommonObject * @param int $fk_product_stock id product_stock for objet * @param int $with_qty 1 = doesn't return line with 0 quantity * @param int $fk_product If set to a product id, get eatby and sellby from table llx_product_lot - * @return array <0 if KO, array of batch + * @return array|int <0 if KO, array of batch */ public static function findAll($dbs, $fk_product_stock, $with_qty = 0, $fk_product = 0) { diff --git a/htdocs/product/dynamic_price/class/price_expression.class.php b/htdocs/product/dynamic_price/class/price_expression.class.php index b9010f60f18..d38851e0eaa 100644 --- a/htdocs/product/dynamic_price/class/price_expression.class.php +++ b/htdocs/product/dynamic_price/class/price_expression.class.php @@ -162,7 +162,7 @@ class PriceExpression /** * List all price expressions * - * @return array Array of price expressions + * @return array|int Array of price expressions, <0 if ko */ public function list_price_expression() { diff --git a/htdocs/product/dynamic_price/class/price_global_variable.class.php b/htdocs/product/dynamic_price/class/price_global_variable.class.php index 336fb024470..99407851174 100644 --- a/htdocs/product/dynamic_price/class/price_global_variable.class.php +++ b/htdocs/product/dynamic_price/class/price_global_variable.class.php @@ -311,7 +311,7 @@ class PriceGlobalVariable /** * List all price global variables * - * @return array Array of price global variables + * @return array|int Array of price global variables, <0 if ko */ public function listGlobalVariables() { diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 416d96ad55b..8ecbce06cde 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -127,7 +127,7 @@ class Entrepot extends CommonObject 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'showoncombobox'=>1, 'position'=>25, 'searchall'=>1), 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-2, 'position'=>35, 'searchall'=>1), 'lieu' =>array('type'=>'varchar(64)', 'label'=>'LocationSummary', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'showoncombobox'=>2, 'searchall'=>1), - 'fk_parent' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ParentWarehouse', 'enabled'=>1, 'visible'=>-2, 'position'=>41), + 'fk_parent' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:1:((statut:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ParentWarehouse', 'enabled'=>1, 'visible'=>-2, 'position'=>41), 'fk_project' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>25), 'address' =>array('type'=>'varchar(255)', 'label'=>'Address', 'enabled'=>1, 'visible'=>-2, 'position'=>45, 'searchall'=>1), 'zip' =>array('type'=>'varchar(10)', 'label'=>'Zip', 'enabled'=>1, 'visible'=>-2, 'position'=>50, 'searchall'=>1), @@ -962,6 +962,7 @@ class Entrepot extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); $return = '
'; $return .= '
'; @@ -970,6 +971,7 @@ class Entrepot extends CommonObject $return .= '
'; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'lieu') && (!empty($this->lieu))) { $return .= '
'.$this->lieu.''; } 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/product/stock/class/productstockentrepot.class.php b/htdocs/product/stock/class/productstockentrepot.class.php index a0310a16359..1151890a4b1 100644 --- a/htdocs/product/stock/class/productstockentrepot.class.php +++ b/htdocs/product/stock/class/productstockentrepot.class.php @@ -242,7 +242,7 @@ class ProductStockEntrepot extends CommonObject * @param array $filter filter array * @param string $filtermode filter mode (AND or OR) * - * @return int <0 if KO, >0 if OK + * @return int|array <0 if KO, array if OK */ public function fetchAll($fk_product = '', $fk_entrepot = '', $sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') { diff --git a/htdocs/product/stock/stockatdate.php b/htdocs/product/stock/stockatdate.php index 718e3043a23..46c902238de 100644 --- a/htdocs/product/stock/stockatdate.php +++ b/htdocs/product/stock/stockatdate.php @@ -375,7 +375,7 @@ if ($mode != 'future') { print img_picto('', 'stock', 'class="pictofixedwidth"').$langs->trans("Warehouse").' :'; print ' '; $selected = ((GETPOSTISSET('search_fk_warehouse') || GETPOSTISSET('fk_warehouse')) ? $search_fk_warehouse : 'ifonenodefault'); - print $formproduct->selectWarehouses($selected, 'search_fk_warehouse', '', 1, 0, 0, $langs->trans('Warehouse'), 0, 0, null, '', null, 1, false, 'e.ref', 1); + print $formproduct->selectWarehouses($selected, 'search_fk_warehouse', '', 1, 0, 0, $langs->trans('Warehouse'), 0, 0, null, 'minwidth200', null, 1, false, 'e.ref', 1); } print '
'; 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/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index 1c8105ea931..7c68b8bdeab 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -271,6 +271,7 @@ class Tasks extends DolibarrApi * @return array Array of roles * * @url GET {id}/roles + * */ public function getRoles($id, $userid = 0) { diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index fc4f6acb426..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++; @@ -2384,7 +2387,10 @@ class Project extends CommonObject */ public function getKanbanView($option = '') { - global $langs,$user; + global $langs, $user; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -2397,6 +2403,7 @@ class Project extends CommonObject $return .= img_warning($langs->trans('Late')); } $return .= ''; + $return .= ''; if (property_exists($this, 'date_start') && $this->date_start) { $return .= '
'.dol_print_date($this->date_start, 'day').''; } diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 596d828ff97..eb2f0f35069 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') ); /** @@ -128,6 +130,8 @@ class Task extends CommonObjectLine public $timespent_thm; public $timespent_note; public $timespent_fk_product; + public $timespent_invoiceid; + public $timespent_invoicelineid; public $comments = array(); @@ -556,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) { @@ -673,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); @@ -877,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"; @@ -891,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"; @@ -908,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)"; @@ -1261,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; @@ -1305,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 } @@ -1318,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; } @@ -1354,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,"; @@ -1369,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) { @@ -1452,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); @@ -1512,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; @@ -1556,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; } /** @@ -1613,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,"; @@ -1628,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) { @@ -1729,18 +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 .= " 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); @@ -1764,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 } @@ -1779,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; } @@ -1835,12 +1821,13 @@ class Task extends CommonObjectLine } if (!$error) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."projet_task_time"; - $sql .= " WHERE rowid = ".((int) $this->timespent_id); - dol_syslog(get_class($this)."::delTimeSpent", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) { + $timespent = new TimeSpent($this->db); + $timespent->fetch($this->timespent_id); + + $res_del = $timespent->delete($user); + + if ($res_del < 0) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } } @@ -2371,6 +2358,9 @@ class Task extends CommonObjectLine public function getKanbanView($option = '', $arraydata = null) { global $langs, $conf; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -2379,6 +2369,7 @@ class Task extends CommonObjectLine $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; + $return .= ''; if (property_exists($this, 'fk_project') ) { $return .= '
'.$this->fk_project.''; } 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/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 85d83031ccd..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'; @@ -309,6 +310,8 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us } $object->timespent_fk_user = GETPOST("userid_line", 'int'); $object->timespent_fk_product = GETPOST("fk_product", 'int'); + $object->timespent_invoiceid = GETPOST("invoiceid", 'int'); + $object->timespent_invoicelineid = GETPOST("invoicelineid", 'int'); $result = 0; if (in_array($object->timespent_fk_user, $childids) || $user->rights->projet->all->creer) { @@ -336,8 +339,10 @@ if (($action == 'updateline' || $action == 'updatesplitline') && !$cancel && $us } $object->timespent_fk_user = GETPOST("userid_line", 'int'); $object->timespent_fk_product = GETPOST("fk_product", 'int'); - + $object->timespent_invoiceid = GETPOST("invoiceid", 'int'); + $object->timespent_invoicelineid = GETPOST("invoicelineid", 'int'); $result = 0; + if (in_array($object->timespent_fk_user, $childids) || $user->rights->projet->all->creer) { $result = $object->updateTimeSpent($user); @@ -561,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) { @@ -665,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) { @@ -764,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) { @@ -1262,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 @@ -1270,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 @@ -1468,7 +1473,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser print $langs->trans('InvoiceToUse'); print ''; print ''; - $form->selectInvoice($projectstatic->thirdparty->id, '', 'invoiceid', 24, 0, $langs->trans('NewInvoice'), 1, 0, 0, 'maxwidth500', '', 'all'); + print $form->selectInvoice($projectstatic->thirdparty->id, '', 'invoiceid', 24, 0, $langs->trans('NewInvoice'), 1, 0, 0, 'maxwidth500', '', 'all'); print ''; print ''; /*print ''; @@ -1547,22 +1552,23 @@ 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,"; $sql .= " il.fk_facture as invoice_id, inv.fk_statut,"; $sql .= " p.fk_soc,s.name_alias,"; + $sql .= " t.invoice_line_id"; // Add fields from hooks $parameters = array(); $reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook $sql .= preg_replace('/^,/', '', $hookmanager->resPrint); $sql = preg_replace('/,\s*$/', '', $sql); - $sql .= " FROM ".MAIN_DB_PREFIX."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"; @@ -1571,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).")"; @@ -1625,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(); @@ -1873,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')); @@ -1903,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 ''; } } @@ -1919,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 ''; @@ -1975,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); @@ -1994,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'])) { @@ -2007,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); @@ -2046,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 ''; @@ -2068,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 ''; @@ -2088,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) { @@ -2178,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'); @@ -2199,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); @@ -2258,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; } } @@ -2308,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).'">'; @@ -2344,7 +2350,19 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0 || $allprojectforuser if ($task_time->invoice_id) { $result = $tmpinvoice->fetch($task_time->invoice_id); if ($result > 0) { - print $tmpinvoice->getNomUrl(1); + if ($action=='editline' && $_GET['lineid'] == $task_time->rowid) { + print $formproject->selectInvoiceAndLine($task_time->invoice_id, $task_time->invoice_line_id, 'invoiceid', 'invoicelineid', 'maxwidth500', array('p.rowid'=>$projectstatic->id)); + } else { + print $tmpinvoice->getNomUrl(1); + if (!empty($task_time->invoice_line_id)) { + $invoiceLine = new FactureLigne($db); + $invoiceLine->fetch($task_time->invoice_line_id); + if (!empty($invoiceLine->id)) { + print '
'.$langs->trans('Qty').':'.$invoiceLine->qty; + print ' '.$langs->trans('TotalHT').':'.price($invoiceLine->total_ht); + } + } + } } } else { print $langs->trans("No"); @@ -2386,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 ''; @@ -2419,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 ''; } @@ -2442,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'); @@ -2454,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); @@ -2504,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 ''; } @@ -2519,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 ''; @@ -2557,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 ''; } @@ -2580,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'); @@ -2592,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; @@ -2642,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/members/new.php b/htdocs/public/members/new.php index ed3f256f71f..ce6eb58d02e 100644 --- a/htdocs/public/members/new.php +++ b/htdocs/public/members/new.php @@ -604,7 +604,7 @@ if (!empty($conf->global->MEMBER_SKIP_TABLE) || !empty($conf->global->MEMBER_NEW print $form->selectarray("morphy", $morphys, GETPOST('morphy'), 1); print ''."\n"; } else { - print $morphys[$conf->global->MEMBER_NEWFORM_FORCEMORPHY]; + //print $morphys[$conf->global->MEMBER_NEWFORM_FORCEMORPHY]; print ''; } diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 2777e48c7f5..4ee7a4a77ca 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -354,7 +354,7 @@ if (empty($ipaddress)) { $ipaddress = $_SESSION['ipaddress']; } if (empty($TRANSACTIONID)) { - $TRANSACTIONID = $_SESSION['TRANSACTIONID']; + $TRANSACTIONID = $_SESSION['TRANSACTIONID']; // pi_... or ch_... if (empty($TRANSACTIONID) && GETPOST('payment_intent', 'alphanohtml')) { // For the case we use STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION = 2 $TRANSACTIONID = GETPOST('payment_intent', 'alphanohtml'); @@ -856,7 +856,8 @@ if ($ispaymentok) { $paiement->paiementid = $paymentTypeId; $paiement->num_payment = ''; $paiement->note_public = 'Online payment '.dol_print_date($now, 'standard').' from '.$ipaddress; - $paiement->ext_payment_id = $TRANSACTIONID; + $paiement->ext_payment_id = $TRANSACTIONID; // TODO LDR May be we should store py_... instead of pi_... but we started with pi_... so we continue. + //$paiement->ext_payment_id = $TRANSACTIONID.':'.$customer->id.'@'.$stripearrayofkeysbyenv[$servicestatus]['publishable_key']; // TODO LDR It would be better if we could store this. Do we have customer->id and publishable_key ? $paiement->ext_payment_site = $service; if (!$error) { @@ -973,8 +974,8 @@ if ($ispaymentok) { $paiement->paiementid = $paymentTypeId; $paiement->num_payment = ''; $paiement->note_public = 'Online payment ' . dol_print_date($now, 'standard') . ' from ' . $ipaddress; - $paiement->ext_payment_id = $TRANSACTIONID; - $paiement->ext_payment_site = ''; + $paiement->ext_payment_id = $TRANSACTIONID; // pi_... for Stripe, ... + $paiement->ext_payment_site = $service; // 'StripeLive' or 'Stripe', or ... if (!$error) { $paiement_id = $paiement->create($user, 1); // This include closing invoices and regenerating documents diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 9c10041a64e..5d0944e9738 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -34,6 +34,11 @@ if (is_numeric($entity)) { define("DOLENTITY", $entity); } +// So log file will have a suffix +if (!defined('USESUFFIXINLOG')) { + define('USESUFFIXINLOG', '_stripeipn'); +} + // Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; @@ -311,9 +316,7 @@ if ($event->type == 'payout.created') { } elseif ($event->type == 'payment_intent.succeeded') { // Called when making payment with PaymentIntent method ($conf->global->STRIPE_USE_NEW_CHECKOUT is on). dol_syslog("object = ".var_export($event->data, true)); - // TODO: create fees - - /* TODO LMR Enable this only if this is a payment of a Dolibarr bon_prelevement only + /* TODO LMR We must retreive the invoice and payment amount from the id = ext_payment_id into llx_prelevement_demande include_once DOL_DOCUMENT_ROOT . '/compta/paiement/class/paiement.class.php'; $object = $event->data->object; $invoice_id = $object->metadata->dol_id; @@ -330,20 +333,23 @@ if ($event->type == 'payout.created') { global $stripearrayofkeysbyenv; $stripeacc = $stripearrayofkeysbyenv[$servicestatus]['secret_key']; - dol_syslog("Try to create sepa_debit with data = ".json_encode($dataforcard)); + dol_syslog("Try to create payment with data = ".json_encode($dataforcard)); $s = new \Stripe\StripeClient($stripeacc); $paymentmethodstripe = $s->paymentMethods->retrieve($paymentmethodstripeid); - //$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; $paymentTypeId = $paymentmethodstripe->type; - if ($paymentTypeId == "sepa_debit") { + if ($paymentTypeId == "ban") { + $paymentTypeId = "PRE" + } elseif ($paymentTypeId == "sepa_debit") { // is this used ? how ? $paymentTypeId = "BANCON"; } elseif ($paymentTypeId == "card") { $paymentTypeId = "CB"; } + // TODO LMR Enable this only if this is a payment of a Dolibarr llx_prelevement_demande only + $paiement = new Paiement($db); $paiement->datepaye = $now; $paiement->date = $now; @@ -359,13 +365,16 @@ if ($event->type == 'payout.created') { $errorforinvoice++; } $paiement->paiementid = $paymentTypeId; - $paiement->num_paiement = ''; $paiement->num_payment = ''; - // Add a comment with keyword 'SellYourSaas' in text. Used by trigger. - $paiement->note_public = 'StripeSepa payment ' . dol_print_date($now, 'standard') . ' using ' . $paymentmethod . ($ipaddress ? ' from ip ' . $ipaddress : '') . ' - Transaction ID = ' . $TRANSACTIONID; + $paiement->note_public = ''; $paiement->note_private = 'StripeSepa payment ' . dol_print_date($now, 'standard') . ' using ' . $paymentmethod . ($ipaddress ? ' from ip ' . $ipaddress : '') . ' - Transaction ID = ' . $TRANSACTIONID; - $paiement->ext_payment_id = $TRANSACTIONID . ':' . $customer_id . '@' . $stripearrayofkeysbyenv[$servicestatus]['publishable_key']; - $paiement->ext_payment_site = 'stripe'; + // TODO LMR Fill the $paiement->ext_payment_id with an ID of payment intent (so 'pi_....'). Like this: + $paiement->ext_payment_id = $TRANSACTIONID.':'.$customer_id.'@'.$stripearrayofkeysbyenv[$servicestatus]['publishable_key']; // May be we should store py_... instead of pi_... but we started with pi_... so we continue. + $paiement->ext_payment_site = $service; // 'StripeLive' or 'Stripe' if test + + + $db->begin(); + if (!$errorforinvoice) { dol_syslog('* Record payment for invoice id ' . $invoice_id . '. It includes closing of invoice and regenerating document'); diff --git a/htdocs/public/ticket/view.php b/htdocs/public/ticket/view.php index 1bfc235ff65..67b582c0afd 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(); @@ -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 '
'; diff --git a/htdocs/recruitment/class/recruitmentcandidature.class.php b/htdocs/recruitment/class/recruitmentcandidature.class.php index 6dae3e08388..9d75781056a 100644 --- a/htdocs/recruitment/class/recruitmentcandidature.class.php +++ b/htdocs/recruitment/class/recruitmentcandidature.class.php @@ -1036,7 +1036,10 @@ class RecruitmentCandidature extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { - global $langs, $selected,$arrayofselected; + global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -1044,9 +1047,6 @@ class RecruitmentCandidature extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; - if (in_array($this->id, $arrayofselected)) { - $selected = 1; - } $return .= ''; if (property_exists($this, 'fk_recruitmentjobposition')) { $return .= '
'.$langs->trans('Job').' : '.$this->fk_recruitmentjobposition.''; diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index b0ca58d6b8f..d44294ac9bd 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -1116,7 +1116,10 @@ class RecruitmentJobPosition extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { - global $langs, $selected,$arrayofselected,$obj; + global $langs, $obj; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -1124,9 +1127,6 @@ class RecruitmentJobPosition extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; - if (in_array($this->id, $arrayofselected)) { - $selected = 1; - } $return .= ''; if (property_exists($this, 'date_planned')) { $return .= '
'.$langs->trans("Date").' : '.dol_print_date($this->db->jdate($this->date_planned), 'day').''; diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index a0747f13f45..8ee6043f870 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -801,7 +801,7 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio * @param int $showaddress 0=no, 1=yes * @param Translate $outputlangs Object lang for output * @param Translate $outputlangsbis Object lang for output bis - * @return void + * @return float|int */ protected function _pagehead(&$pdf, $object, $showaddress, $outputlangs, $outputlangsbis = null) { diff --git a/htdocs/resource/class/html.formresource.class.php b/htdocs/resource/class/html.formresource.class.php index 8b4e32c05d2..5f8c27dab4f 100644 --- a/htdocs/resource/class/html.formresource.class.php +++ b/htdocs/resource/class/html.formresource.class.php @@ -77,7 +77,7 @@ class FormResource * @param int $limit Limit number of answers * @param string $morecss More css * @param bool $multiple add [] in the name of element and add 'multiple' attribut - * @return string HTML string with + * @return string|array HTML string with */ public function select_resource_list($selected = '', $htmlname = 'fk_resource', $filter = '', $showempty = 0, $showtype = 0, $forcecombo = 0, $event = array(), $filterkey = '', $outputmode = 0, $limit = 20, $morecss = '', $multiple = false) { 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/salaries/class/paymentsalary.class.php b/htdocs/salaries/class/paymentsalary.class.php index 0f141bc3023..4294dd47478 100644 --- a/htdocs/salaries/class/paymentsalary.class.php +++ b/htdocs/salaries/class/paymentsalary.class.php @@ -772,7 +772,10 @@ class PaymentSalary extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { - global $langs, $db; + global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -780,6 +783,7 @@ class PaymentSalary extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; + $return .= ''; if (property_exists($this, 'fk_bank')) { $return .= ' | '.$this->fk_bank.''; } diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index 7192a14e9d3..d45e2bf00d5 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -753,6 +753,9 @@ class Salary extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -760,6 +763,7 @@ class Salary extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; + $return .= ''; if (property_exists($this, 'fk_user')) { $return .= ' | '.$this->fk_user.''; } diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 6ae3cad817a..1912bd74521 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -5212,6 +5212,7 @@ class Societe extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); $return = '
'; $return .= '
'; @@ -5220,6 +5221,7 @@ class Societe extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'code_client')) { $return .= '
'.$this->code_client.''; } diff --git a/htdocs/societe/paymentmodes.php b/htdocs/societe/paymentmodes.php index 54b8b1e22f1..2cc9094176a 100644 --- a/htdocs/societe/paymentmodes.php +++ b/htdocs/societe/paymentmodes.php @@ -1577,7 +1577,7 @@ if ($socid && $action != 'edit' && $action != 'create' && $action != 'editcard' $modelselected = $conf->global->BANKADDON_PDF; } - $out .= $form->selectarray('modelrib'.$rib->id, $modellist, $modelselected, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100'); + $out .= $form->selectarray('modelrib'.$rib->id, $modellist, $modelselected, 1, 0, 0, '', 0, 0, 0, '', 'minwidth100 maxwidth125'); $out .= ajax_combobox('modelrib'.$rib->id); $allowgenifempty = 0; diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index fbcf04aacd2..aa82aaecb9c 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2771,6 +2771,9 @@ class SupplierProposal extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -2779,6 +2782,7 @@ class SupplierProposal extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'socid')) { $return .= ' | '.$this->socid.''; } 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/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 889ab003b9d..99724fddc63 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -2883,7 +2883,7 @@ class Ticket extends CommonObject * * @param User $user Object user * @param int $mode "opened" for askprice to close, "signed" for proposal to invoice - * @return int <0 if KO, >0 if OK + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK */ public function load_board($user, $mode) { @@ -3010,7 +3010,10 @@ class Ticket extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { - global $langs, $selected,$arrayofselected; + global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -3018,9 +3021,6 @@ class Ticket extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl(1) : $this->ref).''; - if (in_array($this->id, $arrayofselected)) { - $selected = 1; - } $return .= ''; if (!empty($arraydata['user_assignment'])) { $return .= '
'.$arraydata['user_assignment'].''; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 3fc11f9eadd..c4c0b4e2b92 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -3063,6 +3063,8 @@ class User extends CommonObject */ public function getKanbanView($option = '', $arraydata = null) { + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -3082,6 +3084,7 @@ class User extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'label')) { $return .= '
'.$this->label.''; } diff --git a/htdocs/user/class/usergroup.class.php b/htdocs/user/class/usergroup.class.php index 60f92f0d40c..9bf322b49b6 100644 --- a/htdocs/user/class/usergroup.class.php +++ b/htdocs/user/class/usergroup.class.php @@ -980,6 +980,9 @@ class UserGroup extends CommonObject public function getKanbanView($option = '', $arraydata = null) { global $langs; + + $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']); + $return = '
'; $return .= '
'; $return .= ''; @@ -987,6 +990,7 @@ class UserGroup extends CommonObject $return .= ''; $return .= '
'; $return .= ''.(method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref).''; + $return .= ''; if (property_exists($this, 'members')) { $return .= '
'.(empty($this->nb_users) ? 0 : $this->nb_users).' '.$langs->trans('Users').''; } diff --git a/htdocs/user/group/perms.php b/htdocs/user/group/perms.php index 8fa614bf1e5..75ab7884ea4 100644 --- a/htdocs/user/group/perms.php +++ b/htdocs/user/group/perms.php @@ -255,12 +255,18 @@ if ($object->id > 0) { print '/'; print ''.$langs->trans("None").""; print ''; + } else { + print ''; } - print ' '; - print ''.$langs->trans("Permissions").''; - if ($user->admin) { - print ''; - } + print ''; + //print ''.$langs->trans("Permissions").''; + print ''; + + print ''; + print ''.img_picto('', 'folder-open', 'class="paddingright"').''.$langs->trans("ExpandAll").''; + print ' | '; + print ''.img_picto('', 'folder', 'class="paddingright"').''.$langs->trans("UndoExpandAll").''; + print ''; print ''."\n"; $sql = "SELECT r.id, r.libelle as label, r.module, r.perms, r.subperms, r.module_position, r.bydefault"; @@ -275,9 +281,12 @@ if ($object->id > 0) { $result = $db->query($sql); if ($result) { $num = $db->num_rows($result); - $i = 0; + $i = 0;$j = 0; $oldmod = ''; + $cookietohidegroup = (empty($_COOKIE["DOLUSER_PERMS_HIDE_GRP"]) ? '' : preg_replace('/^,/', '', $_COOKIE["DOLUSER_PERMS_HIDE_GRP"])); + $cookietohidegrouparray = explode(',', $cookietohidegroup); + while ($i < $num) { $obj = $db->fetch_object($result); @@ -289,48 +298,78 @@ if ($object->id > 0) { $objMod = $modules[$obj->module]; + if (GETPOSTISSET('forbreakperms_'.$obj->module)) { + $ishidden = GETPOST('forbreakperms_'.$obj->module, 'int'); + } elseif (in_array($j, $cookietohidegrouparray)) { // If j is among list of hidden group + $ishidden = 1; + } else { + $ishidden = 0; + } + $isexpanded = ! $ishidden; + // Break found, it's a new module to catch if (isset($obj->module) && ($oldmod <> $obj->module)) { $oldmod = $obj->module; + $j++; + if (GETPOSTISSET('forbreakperms_'.$obj->module)) { + $ishidden = GETPOST('forbreakperms_'.$obj->module, 'int'); + } elseif (in_array($j, $cookietohidegrouparray)) { // If j is among list of hidden group + $ishidden = 1; + } else { + $ishidden = 0; + } + $isexpanded = ! $ishidden; // Break detected, we get objMod $objMod = $modules[$obj->module]; $picto = ($objMod->picto ? $objMod->picto : 'generic'); // Show break line - print ''; - print ''; + print ''; + // Picto and label of module + print ''; print img_object('', $picto, 'class="pictoobjectwidth paddingright"').' '.$objMod->getName(); print ''; print ''; + // Permission and tick (2 columns) if ($caneditperms) { - print ''; - print 'module.'&token='.newToken().'">'.$langs->trans("All").""; - print '/'; - print 'module.'&token='.newToken().'">'.$langs->trans("None").""; + print ''; + print ''; + print ''; + print ''; print ''; } else { - print ' '; + print ''; + print ''; } - print ' '; - print ' '; - - // Permission id - if ($user->admin) { - print ''; - } - + // Description of permission (2 columns) + print ''; + print ''; + print ''; + print ''; + print ''; //Add picto + / - when open en closed print ''."\n"; } print ''."\n"; - print ''; + print ''; + // Picto and label of module print ''; + print ''; //print img_object('', $picto, 'class="inline-block pictoobjectwidth"').' '.$objMod->getName(); print ''; + // Permission and tick (2 columns) if (!empty($permsgroupbyentity[$entity]) && is_array($permsgroupbyentity[$entity])) { if (in_array($obj->id, $permsgroupbyentity[$entity])) { // Own permission by group @@ -360,11 +399,13 @@ if ($object->id > 0) { //print img_edit_add($langs->trans("Add")); print img_picto($langs->trans("Add"), 'switch_off'); print ''; + } else { + print ' '; } print ' '; } - // Description of permission + // Description of permission (2 columns) $permlabel = (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ($langs->trans("PermissionAdvanced".$obj->id) != ("PermissionAdvanced".$obj->id)) ? $langs->trans("PermissionAdvanced".$obj->id) : (($langs->trans("Permission".$obj->id) != ("Permission".$obj->id)) ? $langs->trans("Permission".$obj->id) : $langs->trans($obj->label))); print ''; print $permlabel; @@ -383,6 +424,8 @@ if ($object->id > 0) { print $form->textwithpicto('', $htmltext); //print ''.$obj->id.''; print ''; + } else { + print ' '; } print ''."\n"; @@ -393,6 +436,82 @@ if ($object->id > 0) { print ''; print '
'; + print ''; + + print ''; print '
'; $parameters = array(); diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 4c2b77ce766..7424f7474c0 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -377,7 +377,7 @@ llxHeader("", $title); if (!empty($id) || !empty($ref)) { - $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/webservices/server_order.php b/htdocs/webservices/server_order.php index 0f0eb79d10e..bed089abea1 100644 --- a/htdocs/webservices/server_order.php +++ b/htdocs/webservices/server_order.php @@ -654,7 +654,7 @@ function getOrdersForThirdParty($authentication, $idthirdparty) * * @param array $authentication Array of authentication information * @param array $order Order info - * @return int Id of new order + * @return array array of new order */ function createOrder($authentication, $order) { diff --git a/htdocs/webservices/server_other.php b/htdocs/webservices/server_other.php index ae1a480710f..c51ca01639e 100644 --- a/htdocs/webservices/server_other.php +++ b/htdocs/webservices/server_other.php @@ -185,7 +185,7 @@ function getVersions($authentication) * @param string $modulepart Properties of document * @param string $file Relative path * @param string $refname Ref of object to check permission for external users (autodetect if not provided) - * @return void + * @return array */ function getDocument($authentication, $modulepart, $file, $refname = '') { diff --git a/htdocs/webservices/server_project.php b/htdocs/webservices/server_project.php index b64ccc94d59..16aef76c699 100644 --- a/htdocs/webservices/server_project.php +++ b/htdocs/webservices/server_project.php @@ -235,7 +235,7 @@ $server->register( * * @param array $authentication Array of authentication information * @param array $project Project info - * @return int Id of new order + * @return array array of new order */ function createProject($authentication, $project) { diff --git a/htdocs/zapier/class/api_zapier.class.php b/htdocs/zapier/class/api_zapier.class.php index e6edefcc616..c98f3bab6c7 100644 --- a/htdocs/zapier/class/api_zapier.class.php +++ b/htdocs/zapier/class/api_zapier.class.php @@ -239,7 +239,7 @@ class Zapier extends DolibarrApi * Create hook object * * @param array $request_data Request datas - * @return int ID of hook + * @return array ID of hook * * @url POST /hook/ */