diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 7e7a62c1e84..d7dc3d584e3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -69,12 +69,3 @@ body: attributes: label: Attached files description: Screenshots, screencasts, dolibarr.log, debugging informations - - - type: checkboxes - id: terms - attributes: - label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CODE_OF_CONDUCT.md) - options: - - label: I agree to follow this project's Code of Conduct - required: true diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index f4975622a8f..885f3472d18 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -33,12 +33,3 @@ body: attributes: label: Suggested steps description: List of tasks to achieve goal - - - type: checkboxes - id: terms - attributes: - label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/Dolibarr/dolibarr/blob/develop/.github/CODE_OF_CONDUCT.md) - options: - - label: I agree to follow this project's Code of Conduct - required: true diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 5245e60ad67..954b3e632ca 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2018 Laurent Destailleur * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2017 Regis Houssin - * Copyright (C) 2010-2016 Juanjo Menent + * Copyright (C) 2010-2022 Juanjo Menent * Copyright (C) 2011-2021 Philippe Grand * Copyright (C) 2011 Remy Younes * Copyright (C) 2012-2015 Marcos García @@ -2408,6 +2408,31 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') $fieldValue = '0'; } } + + // Labels Length + $maxlength = ''; + if (in_array($fieldlist[$field], array('libelle', 'label'))) { + switch ($tabname) { + case MAIN_DB_PREFIX . 'c_accounting_category': + case MAIN_DB_PREFIX . 'c_ecotaxe': + case MAIN_DB_PREFIX . 'c_email_senderprofile': + case MAIN_DB_PREFIX . 'c_forme_juridique': + case MAIN_DB_PREFIX . 'c_holiday_types': + case MAIN_DB_PREFIX . 'c_payment_term': + case MAIN_DB_PREFIX . 'c_transport_mode': + $maxlength = ' maxlength="255"'; + break; + case MAIN_DB_PREFIX . 'c_email_templates': + $maxlength = ' maxlength="180"'; + break; + case MAIN_DB_PREFIX . 'c_socialnetworks': + $maxlength = ' maxlength="150"'; + break; + default: + $maxlength = ' maxlength="128"'; + } + } + print ''; $transfound = 0; $transkey = ''; @@ -2426,7 +2451,7 @@ function fieldList($fieldlist, $obj = '', $tabname = '', $context = '') } } if (!$transfound) { - print ''; + print ''; } else { print ''; } diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 697f8fa2130..ea675ed9001 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -5,6 +5,7 @@ * Copyright (C) 2016 Juanjo Menent * Copyright (C) 2018 Ferran Marcet * Copyright (C) 2021 Alexandre Spangaro + * Copyright (C) 2021 Anthony Berton * * 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 @@ -199,6 +200,13 @@ if ($action == 'update') { } else { dolibarr_set_const($db, "THEME_ELDY_USE_CHECKED", $val, 'chaine', 0, '', $conf->entity); } + + $val=(implode(',', (colorStringToArray(GETPOST('THEME_ELDY_BTNACTION'), array())))); + if ($val == '') { + dolibarr_del_const($db, 'THEME_ELDY_BTNACTION', $conf->entity); + } else { + dolibarr_set_const($db, 'THEME_ELDY_BTNACTION', $val, 'chaine', 0, '', $conf->entity); + } } if ($mode == 'dashboard') { diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index 41ed388e044..f03d66bae54 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -1,7 +1,9 @@ - * Copyright (C) 2016 Laurent Destailleur - * Copyright (C) 2020 Thibault FOUCART +/* Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2016 Laurent Destailleur + * Copyright (C) 2020 Thibault FOUCART + * Copyright (C) 2022 ATM Consulting + * Copyright (C) 2022 OpenDSI * * 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 @@ -274,14 +276,17 @@ class Proposals extends DolibarrApi /** * Get lines of a commercial proposal * - * @param int $id Id of commercial proposal + * @param int $id Id of commercial proposal + * @param string $sqlfilters Other criteria to filter answers separated by a comma. d is the alias for proposal lines table, p is the alias for product table. "Syntax example "(p.ref:like:'SO-%') and (d.date_start:<:'20220101')" * * @url GET {id}/lines * * @return int */ - public function getLines($id) + public function getLines($id, $sqlfilters = '') { + $filters = ""; + if (!DolibarrApiAccess::$user->rights->propal->lire) { throw new RestException(401); } @@ -294,7 +299,16 @@ class Proposals extends DolibarrApi if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - $this->propal->getLinesArray(); + + if (!empty($sqlfilters)) { + if (!DolibarrApi::_checkFilters($sqlfilters)) { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $filters = " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $this->propal->getLinesArray($filters); $result = array(); foreach ($this->propal->lines as $line) { array_push($result, $this->_cleanObjectDatas($line)); @@ -308,7 +322,7 @@ class Proposals extends DolibarrApi * @param int $id Id of commercial proposal to update * @param array $request_data Commercial proposal line data * - * @url POST {id}/lines + * @url POST {id}/line * * @return int */ @@ -368,6 +382,84 @@ class Proposals extends DolibarrApi } } + /** + * Add lines to given commercial proposal + * + * @param int $id Id of commercial proposal to update + * @param array $request_data Commercial proposal line data + * + * @url POST {id}/lines + * + * @return int + */ + public function postLines($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if (!$result) { + throw new RestException(404, 'Commercial Proposal not found'); + } + + if (!DolibarrApi::_checkAccessToResource('propal', $this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $errors = []; + $this->db->begin(); + + foreach ($request_data as $TData) { + if (empty($TData[0])) $TData = array($TData); + + foreach ($TData as $lineData) { + $line = (object) $lineData; + + $updateRes = $this->propal->addline( + $line->desc, + $line->subprice, + $line->qty, + $line->tva_tx, + $line->localtax1_tx, + $line->localtax2_tx, + $line->fk_product, + $line->remise_percent, + 'HT', + 0, + $line->info_bits, + $line->product_type, + $line->rang, + $line->special_code, + $line->fk_parent_line, + $line->fk_fournprice, + $line->pa_ht, + $line->label, + $line->date_start, + $line->date_end, + $line->array_options, + $line->fk_unit, + $line->origin, + $line->origin_id, + $line->multicurrency_subprice, + $line->fk_remise_except + ); + + if ($updateRes < 0) { + $errors['lineLabel'] = $line->label; + $errors['msg'] = $this->propal->errors; + } + } + } + if (empty($errors)) { + $this->db->commit(); + return count($request_data); + } else { + $this->db->rollback(); + throw new RestException(400, implode(", ", $errors)); + } + } + /** * Update a line of given commercial proposal * diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index fd3bbfe7171..1c532e26147 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1,20 +1,22 @@ - * Copyright (C) 2004 Eric Seigne - * Copyright (C) 2004-2011 Laurent Destailleur - * Copyright (C) 2005 Marc Barilley - * Copyright (C) 2005-2013 Regis Houssin - * Copyright (C) 2006 Andre Cianfarani - * Copyright (C) 2008 Raphael Bertrand - * Copyright (C) 2010-2020 Juanjo Menent - * Copyright (C) 2010-2017 Philippe Grand - * Copyright (C) 2012-2014 Christophe Battarel - * Copyright (C) 2012 Cedric Salvador - * Copyright (C) 2013 Florian Henry - * Copyright (C) 2014-2015 Marcos García - * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2021 Frédéric France - * Copyright (C) 2018 Ferran Marcet +/* Copyright (C) 2002-2004 Rodolphe Quiedeville + * Copyright (C) 2004 Eric Seigne + * Copyright (C) 2004-2011 Laurent Destailleur + * Copyright (C) 2005 Marc Barilley + * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2006 Andre Cianfarani + * Copyright (C) 2008 Raphael Bertrand + * Copyright (C) 2010-2020 Juanjo Menent + * Copyright (C) 2010-2017 Philippe Grand + * Copyright (C) 2012-2014 Christophe Battarel + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2013 Florian Henry + * Copyright (C) 2014-2015 Marcos García + * Copyright (C) 2018 Nicolas ZABOURI + * Copyright (C) 2018-2021 Frédéric France + * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2022 ATM Consulting + * Copyright (C) 2022 OpenDSI * * 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 @@ -1714,12 +1716,13 @@ class Propal extends CommonObject /** * Load array lines * - * @param int $only_product Return only physical products - * @param int $loadalsotranslation Return translation for products + * @param int $only_product Return only physical products + * @param int $loadalsotranslation Return translation for products + * @param string $filters Filter on other fields * - * @return int <0 if KO, >0 if OK + * @return int <0 if KO, >0 if OK */ - public function fetch_lines($only_product = 0, $loadalsotranslation = 0) + public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $filters = '') { global $langs, $conf; // phpcs:enable @@ -1738,6 +1741,9 @@ class Propal extends CommonObject if ($only_product) { $sql .= ' AND p.fk_product_type = 0'; } + if ($filters) { + $sql .= $filters; + } $sql .= ' ORDER by d.rang'; dol_syslog(get_class($this)."::fetch_lines", LOG_DEBUG); @@ -3689,12 +3695,13 @@ class Propal extends CommonObject /** * Retrieve an array of proposal lines + * @param string $filters Filter on other fields * * @return int >0 if OK, <0 if KO */ - public function getLinesArray() + public function getLinesArray($filters = '') { - return $this->fetch_lines(); + return $this->fetch_lines(0, 0, $filters); } /** diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index f43f4e6ddfa..0ea9b1ba30d 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -62,6 +62,9 @@ $label = GETPOST('label', 'alpha'); $actioncode = GETPOST('actioncode'); $fk_user = GETPOST('userid', 'int'); +// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context +$hookmanager->initHooks(array('taxcard', 'globalcard')); + // Initialize technical objects $object = new ChargeSociales($db); $extrafields = new ExtraFields($db); @@ -97,7 +100,7 @@ $result = restrictedArea($user, 'tax', $object->id, 'chargesociales', 'charges') * Actions */ -$parameters = array(); +$parameters = array('socid' => $socid); $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'); @@ -446,6 +449,8 @@ if ($id > 0) { $object = new ChargeSociales($db); $result = $object->fetch($id); + $formconfirm = ''; + if ($result > 0) { $head = tax_prepare_head($object); @@ -464,25 +469,36 @@ if ($id > 0) { $formquestion[] = array('type' => 'text', 'name' => 'amount', 'label' => $langs->trans("Amount"), 'value' => price($object->amount), 'morecss' => 'width100'); } - print $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneTax', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 280); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneTax', $object->ref), 'confirm_clone', $formquestion, 'yes', 1, 280); } if ($action == 'paid') { $text = $langs->trans('ConfirmPaySocialContribution'); - print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans('PaySocialContribution'), $text, "confirm_paid", '', '', 2); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id, $langs->trans('PaySocialContribution'), $text, "confirm_paid", '', '', 2); } // Confirmation of the removal of the Social Contribution if ($action == 'delete') { $text = $langs->trans('ConfirmDeleteSocialContribution'); - print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('DeleteSocialContribution'), $text, 'confirm_delete', '', '', 2); + $formconfirm = $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('DeleteSocialContribution'), $text, 'confirm_delete', '', '', 2); } if ($action == 'edit') { print "
id&action=update\" method=\"post\">"; print ''; } + // Call Hook formConfirm + $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid); + $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook + if (empty($reshook)) { + $formconfirm .= $hookmanager->resPrint; + } elseif ($reshook > 0) { + $formconfirm = $hookmanager->resPrint; + } + + // Print form confirm + print $formconfirm; print dol_get_fiche_head($head, 'card', $langs->trans("SocialContribution"), -1, 'bill'); diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 5f46e9632c7..a59f35a3978 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1666,7 +1666,11 @@ function dol_get_fiche_head($links = array(), $active = '', $title = '', $notab $limittitle = 30; $out .= ''; if ($picto) { - $out .= img_picto($title, ($pictoisfullpath ? '' : 'object_').$picto, '', $pictoisfullpath, 0, 0, '', 'imgTabTitle').' '; + $noprefix = $pictoisfullpath; + if (strpos($picto, 'fontawesome_') !== false) { + $noprefix = 1; + } + $out .= img_picto($title, ($noprefix ? '' : 'object_').$picto, '', $pictoisfullpath, 0, 0, '', 'imgTabTitle').' '; } $out .= ''.dol_escape_htmltag(dol_trunc($title, $limittitle)).''; $out .= ''; @@ -2021,10 +2025,14 @@ function dol_banner_tab($object, $paramid, $morehtml = '', $shownav = 1, $fieldi $width = 14; $cssclass = 'photorefcenter'; $picto = $object->picto; + $prefix = 'object_'; if ($object->element == 'project' && !$object->public) { $picto = 'project'; // instead of projectpub } - $nophoto = img_picto('No photo', 'object_'.$picto); + if (strpos($picto, 'fontawesome_') !== false) { + $prefix = ''; + } + $nophoto = img_picto('No photo', $prefix.$picto); } $morehtmlleft .= ''; $morehtmlleft .= '
'; @@ -3609,6 +3617,7 @@ function dol_trunc($string, $size = 40, $trunc = 'right', $stringencoding = 'UTF * Example: picto.png if picto.png is stored into htdocs/theme/mytheme/img * Example: picto.png@mymodule if picto.png is stored into htdocs/mymodule/img * Example: /mydir/mysubdir/picto.png if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1) + * Example: fontawesome_envelope-open-text_fas_red_1em if you want to use fontaweseome icons: fontawesome__