html.formactions.class.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. <?php
  2. /* Copyright (c) 2008-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
  4. * Copyright (C) 2010-2018 Juanjo Menent <jmenent@2byte.es>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * \file htdocs/core/class/html.formactions.class.php
  21. * \ingroup core
  22. * \brief File of class with predefined functions and HTML components
  23. */
  24. /**
  25. * Class to manage building of HTML components
  26. */
  27. class FormActions
  28. {
  29. /**
  30. * @var DoliDB Database handler.
  31. */
  32. public $db;
  33. /**
  34. * @var string Error code (or message)
  35. */
  36. public $error = '';
  37. /**
  38. * Constructor
  39. *
  40. * @param DoliDB $db Database handler
  41. */
  42. public function __construct($db)
  43. {
  44. $this->db = $db;
  45. }
  46. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  47. /**
  48. * Show list of action status
  49. *
  50. * @param string $formname Name of form where select is included
  51. * @param string $selected Preselected value (-1..100)
  52. * @param int $canedit 1=can edit, 0=read only
  53. * @param string $htmlname Name of html prefix for html fields (selectX and valX)
  54. * @param integer $showempty Show an empty line if select is used
  55. * @param integer $onlyselect 0=Standard, 1=Hide percent of completion and force usage of a select list, 2=Same than 1 and add "Incomplete (Todo+Running)
  56. * @param string $morecss More css on select field
  57. * @return void
  58. */
  59. public function form_select_status_action($formname, $selected, $canedit = 1, $htmlname = 'complete', $showempty = 0, $onlyselect = 0, $morecss = 'maxwidth100')
  60. {
  61. // phpcs:enable
  62. global $langs, $conf;
  63. $listofstatus = array(
  64. 'na' => $langs->trans("ActionNotApplicable"),
  65. '0' => $langs->trans("ActionsToDoShort"),
  66. '50' => $langs->trans("ActionRunningShort"),
  67. '100' => $langs->trans("ActionDoneShort")
  68. );
  69. // +ActionUncomplete
  70. if (!empty($conf->use_javascript_ajax)) {
  71. print "\n";
  72. print "<script type=\"text/javascript\">
  73. var htmlname = '".$htmlname."';
  74. $(document).ready(function () {
  75. select_status();
  76. $('#select' + htmlname).change(function() {
  77. console.log('We change field select '+htmlname);
  78. select_status();
  79. });
  80. });
  81. function select_status() {
  82. var defaultvalue = $('#select' + htmlname).val();
  83. console.log('val='+defaultvalue);
  84. var percentage = $('input[name=percentage]');
  85. var selected = '".(isset($selected) ? dol_escape_js($selected) : '')."';
  86. var value = (selected>0?selected:(defaultvalue>=0?defaultvalue:''));
  87. percentage.val(value);
  88. if (defaultvalue == 'na' || defaultvalue == -1) {
  89. percentage.prop('disabled', true);
  90. $('.hideifna').hide();
  91. }
  92. else if (defaultvalue == 0) {
  93. percentage.val(0);
  94. percentage.removeAttr('disabled'); /* Not disabled, we want to change it to higher value */
  95. $('.hideifna').show();
  96. }
  97. else if (defaultvalue == 100) {
  98. percentage.val(100);
  99. percentage.prop('disabled', true);
  100. $('.hideifna').show();
  101. }
  102. else {
  103. if (defaultvalue == 50 && (percentage.val() == 0 || percentage.val() == 100)) { percentage.val(50) };
  104. percentage.removeAttr('disabled');
  105. $('.hideifna').show();
  106. }
  107. }
  108. </script>\n";
  109. }
  110. if (!empty($conf->use_javascript_ajax) || $onlyselect) {
  111. //var_dump($selected);
  112. if ($selected == 'done') {
  113. $selected = '100';
  114. }
  115. print '<select '.($canedit ? '' : 'disabled ').'name="'.$htmlname.'" id="select'.$htmlname.'" class="flat'.($morecss ? ' '.$morecss : '').'">';
  116. if ($showempty) {
  117. print '<option value="-1"'.($selected == '' ? ' selected' : '').'>&nbsp;</option>';
  118. }
  119. foreach ($listofstatus as $key => $val) {
  120. print '<option value="'.$key.'"'.(($selected == $key && strlen($selected) == strlen($key)) || (($selected > 0 && $selected < 100) && $key == '50') ? ' selected' : '').'>'.$val.'</option>';
  121. if ($key == '50' && $onlyselect == 2) {
  122. print '<option value="todo"'.($selected == 'todo' ? ' selected' : '').'>'.$langs->trans("ActionUncomplete").' ('.$langs->trans("ActionsToDoShort")."+".$langs->trans("ActionRunningShort").')</option>';
  123. }
  124. }
  125. print '</select>';
  126. if ($selected == 0 || $selected == 100) {
  127. $canedit = 0;
  128. }
  129. print ajax_combobox('select'.$htmlname, array(), 0, 0, 'resolve', '-1', $morecss);
  130. if (empty($onlyselect)) {
  131. print ' <input type="text" id="val'.$htmlname.'" name="percentage" class="flat hideifna" value="'.($selected >= 0 ? $selected : '').'" size="2"'.($canedit && ($selected >= 0) ? '' : ' disabled').'>';
  132. print '<span class="hideonsmartphone hideifna">%</span>';
  133. }
  134. } else {
  135. print ' <input type="text" id="val'.$htmlname.'" name="percentage" class="flat" value="'.($selected >= 0 ? $selected : '').'" size="2"'.($canedit ? '' : ' disabled').'>%';
  136. }
  137. }
  138. /**
  139. * Show list of actions for element
  140. *
  141. * @param Object $object Object
  142. * @param string $typeelement 'invoice', 'propal', 'order', 'invoice_supplier', 'order_supplier', 'fichinter'
  143. * @param int $socid Socid of user
  144. * @param int $forceshowtitle Show title even if there is no actions to show
  145. * @param string $morecss More css on table
  146. * @param int $max Max number of record
  147. * @param string $moreparambacktopage More param for the backtopage
  148. * @param string $morehtmlcenter More html text on center of title line
  149. * @param int $assignedtouser Assign event by default to this user id (will be ignored if not enough permissions)
  150. * @return int <0 if KO, >=0 if OK
  151. */
  152. public function showactions($object, $typeelement, $socid = 0, $forceshowtitle = 0, $morecss = 'listactions', $max = 0, $moreparambacktopage = '', $morehtmlcenter = '', $assignedtouser = 0)
  153. {
  154. global $langs, $conf, $user;
  155. require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
  156. $sortfield = 'a.datep,a.id';
  157. $sortorder = 'DESC,DESC';
  158. $actioncomm = new ActionComm($this->db);
  159. $listofactions = $actioncomm->getActions($socid, $object->id, $typeelement, '', $sortfield, $sortorder, ($max ? ($max + 1) : 0));
  160. if (!is_array($listofactions)) {
  161. dol_print_error($this->db, 'FailedToGetActions');
  162. }
  163. require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
  164. $caction = new CActionComm($this->db);
  165. $arraylist = $caction->liste_array(1, 'code', '', (empty($conf->global->AGENDA_USE_EVENT_TYPE) ? 1 : 0), '', 1);
  166. $num = count($listofactions);
  167. if ($num || $forceshowtitle) {
  168. if ($typeelement == 'invoice') {
  169. $title = $langs->trans('ActionsOnBill');
  170. } elseif ($typeelement == 'invoice_supplier' || $typeelement == 'supplier_invoice') {
  171. $title = $langs->trans('ActionsOnBill');
  172. } elseif ($typeelement == 'propal') {
  173. $title = $langs->trans('ActionsOnPropal');
  174. } elseif ($typeelement == 'supplier_proposal') {
  175. $title = $langs->trans('ActionsOnSupplierProposal');
  176. } elseif ($typeelement == 'order') {
  177. $title = $langs->trans('ActionsOnOrder');
  178. } elseif ($typeelement == 'order_supplier' || $typeelement == 'supplier_order') {
  179. $title = $langs->trans('ActionsOnOrder');
  180. } elseif ($typeelement == 'shipping') {
  181. $title = $langs->trans('ActionsOnShipping');
  182. } elseif ($typeelement == 'fichinter') {
  183. $title = $langs->trans('ActionsOnFicheInter');
  184. } elseif ($typeelement == 'project') {
  185. $title = $langs->trans('LatestLinkedEvents', $max ? $max : '');
  186. } elseif ($typeelement == 'task') {
  187. $title = $langs->trans('LatestLinkedEvents', $max ? $max : '');
  188. } elseif ($typeelement == 'member') {
  189. $title = $langs->trans('LatestLinkedEvents', $max ? $max : '');
  190. } else {
  191. $title = $langs->trans("LatestLinkedEvents", $max ? $max : '');
  192. }
  193. $urlbacktopage = $_SERVER['PHP_SELF'].'?id='.$object->id.($moreparambacktopage ? '&'.$moreparambacktopage : '');
  194. $projectid = $object->fk_project;
  195. if ($typeelement == 'project') {
  196. $projectid = $object->id;
  197. }
  198. $taskid = 0;
  199. if ($typeelement == 'task') {
  200. $taskid = $object->id;
  201. }
  202. $usercanaddaction = 0;
  203. if (empty($assignedtouser) || $assignedtouser == $user->id) {
  204. $usercanaddaction = $user->hasRight('agenda', 'myactions', 'create');
  205. $assignedtouser = 0;
  206. } else {
  207. $usercanaddaction = $user->hasRight('agenda', 'allactions', 'create');
  208. }
  209. $newcardbutton = '';
  210. if (isModEnabled('agenda') && $usercanaddaction) {
  211. $url = DOL_URL_ROOT.'/comm/action/card.php?action=create&token='.newToken().'&datep='.urlencode(dol_print_date(dol_now(), 'dayhourlog', 'tzuser'));
  212. $url .= '&origin='.urlencode($typeelement).'&originid='.((int) $object->id).((!empty($object->socid) && $object->socid > 0) ? '&socid='.((int) $object->socid) : ((!empty($socid) && $socid > 0) ? '&socid='.((int) $socid) : ''));
  213. $url .= ($projectid > 0 ? '&projectid='.((int) $projectid) : '').($taskid > 0 ? '&taskid='.((int) $taskid) : '');
  214. $url .= ($assignedtouser > 0 ? '&assignedtouser='.$assignedtouser : '');
  215. $url .= '&backtopage='.urlencode($urlbacktopage);
  216. $newcardbutton .= dolGetButtonTitle($langs->trans("AddEvent"), '', 'fa fa-plus-circle', $url);
  217. }
  218. print '<!-- formactions->showactions -->'."\n";
  219. print load_fiche_titre($title, $newcardbutton, '', 0, 0, '', $morehtmlcenter);
  220. $page = 0;
  221. $param = '';
  222. print '<div class="div-table-responsive-no-min">';
  223. print '<table class="centpercent noborder'.($morecss ? ' '.$morecss : '').'">';
  224. print '<tr class="liste_titre">';
  225. print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1);
  226. print getTitleFieldOfList('By', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1);
  227. print getTitleFieldOfList('Type', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1);
  228. print getTitleFieldOfList('Title', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1);
  229. print getTitleFieldOfList('Date', 0, $_SERVER["PHP_SELF"], 'a.datep', $page, $param, '', $sortfield, $sortorder, 'center ', 1);
  230. print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, 'right ', 1);
  231. print '</tr>';
  232. print "\n";
  233. if (is_array($listofactions) && count($listofactions)) {
  234. $cacheusers = array();
  235. $cursorevent = 0;
  236. foreach ($listofactions as $actioncomm) {
  237. if ($max && $cursorevent >= $max) {
  238. break;
  239. }
  240. print '<tr class="oddeven">';
  241. // Ref
  242. print '<td class="nowraponall">'.$actioncomm->getNomUrl(1, -1).'</td>';
  243. // Onwer
  244. print '<td class="nowraponall tdoverflowmax125">';
  245. if (!empty($actioncomm->userownerid)) {
  246. if (isset($cacheusers[$actioncomm->userownerid]) && is_object($cacheusers[$actioncomm->userownerid])) {
  247. $tmpuser = $cacheusers[$actioncomm->userownerid];
  248. } else {
  249. $tmpuser = new User($this->db);
  250. $tmpuser->fetch($actioncomm->userownerid);
  251. $cacheusers[$actioncomm->userownerid] = $tmpuser;
  252. }
  253. if ($tmpuser->id > 0) {
  254. print $tmpuser->getNomUrl(-1, '', 0, 0, 16, 0, 'firstelselast', '');
  255. }
  256. }
  257. print '</td>';
  258. $actionstatic = $actioncomm;
  259. // Example: Email sent from invoice card
  260. //$actionstatic->code = 'AC_BILL_SENTBYMAIL
  261. //$actionstatic->type_code = 'AC_OTHER_AUTO'
  262. // Type
  263. $labeltype = $actionstatic->type_code;
  264. if (empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($arraylist[$labeltype])) {
  265. $labeltype = 'AC_OTH';
  266. }
  267. if (preg_match('/^TICKET_MSG/', $actionstatic->code)) {
  268. $labeltype = $langs->trans("Message");
  269. } else {
  270. if (!empty($arraylist[$labeltype])) {
  271. $labeltype = $arraylist[$labeltype];
  272. }
  273. if ($actionstatic->type_code == 'AC_OTH_AUTO' && ($actionstatic->type_code != $actionstatic->code) && $labeltype && !empty($arraylist[$actionstatic->code])) {
  274. $labeltype .= ' - '.$arraylist[$actionstatic->code]; // Use code in priority on type_code
  275. }
  276. }
  277. print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($labeltype).'">';
  278. print $actioncomm->getTypePicto();
  279. print $labeltype;
  280. print '</td>';
  281. // Label
  282. print '<td class="tdoverflowmax200" title="'.dol_escape_htmltag($actioncomm->label).'">'.$actioncomm->getNomUrl(0, 36).'</td>';
  283. // Date
  284. print '<td class="center nowraponall">'.dol_print_date($actioncomm->datep, 'dayhour', 'tzuserrel');
  285. if ($actioncomm->datef) {
  286. $tmpa = dol_getdate($actioncomm->datep);
  287. $tmpb = dol_getdate($actioncomm->datef);
  288. if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
  289. if ($tmpa['hours'] != $tmpb['hours'] || $tmpa['minutes'] != $tmpb['minutes']) {
  290. print '-'.dol_print_date($actioncomm->datef, 'hour', 'tzuserrel');
  291. }
  292. } else {
  293. print '-'.dol_print_date($actioncomm->datef, 'dayhour', 'tzuserrel');
  294. }
  295. }
  296. print '</td>';
  297. print '<td class="right">';
  298. print $actioncomm->getLibStatut(3);
  299. print '</td>';
  300. print '</tr>';
  301. $cursorevent++;
  302. }
  303. } else {
  304. print '<tr class="oddeven"><td colspan="6"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
  305. }
  306. if ($max && $num > $max) {
  307. print '<tr class="oddeven"><td colspan="6"><span class="opacitymedium">'.$langs->trans("More").'...</span></td></tr>';
  308. }
  309. print '</table>';
  310. print '</div>';
  311. }
  312. return $num;
  313. }
  314. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  315. /**
  316. * Output html select list of type of event
  317. *
  318. * @param array|string $selected Type pre-selected (can be 'manual', 'auto' or 'AC_xxx'). Can be an array too.
  319. * @param string $htmlname Name of select field
  320. * @param string $excludetype A type to exclude ('systemauto', 'system', '')
  321. * @param integer $onlyautoornot 1=Group all type AC_XXX into 1 line AC_MANUAL. 0=Keep details of type, -1=Keep details and add a combined line "All manual", -2=Combined line is disabled (not implemented yet)
  322. * @param int $hideinfohelp 1=Do not show info help, 0=Show, -1=Show+Add info to tell how to set default value
  323. * @param int $multiselect 1=Allow multiselect of action type
  324. * @param int $nooutput 1=No output
  325. * @param string $morecss More css to add to SELECT component.
  326. * @return string
  327. */
  328. public function select_type_actions($selected = '', $htmlname = 'actioncode', $excludetype = '', $onlyautoornot = 0, $hideinfohelp = 0, $multiselect = 0, $nooutput = 0, $morecss = 'minwidth300')
  329. {
  330. // phpcs:enable
  331. global $langs, $user, $form, $conf;
  332. if (!is_object($form)) {
  333. $form = new Form($this->db);
  334. }
  335. require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
  336. require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
  337. $caction = new CActionComm($this->db);
  338. // Suggest a list with manual events or all auto events
  339. $arraylist = $caction->liste_array(1, 'code', $excludetype, $onlyautoornot, '', 0); // If we use param 'all' instead of 'code', there is no group by include in answer but the key 'type' of answer array contains the key for the group by.
  340. if (empty($multiselect)) {
  341. // Add empty line at start only if no multiselect
  342. array_unshift($arraylist, '&nbsp;');
  343. }
  344. //asort($arraylist);
  345. if ($selected == 'manual') {
  346. $selected = 'AC_OTH';
  347. }
  348. if ($selected == 'auto') {
  349. $selected = 'AC_OTH_AUTO';
  350. }
  351. if (!empty($conf->global->AGENDA_ALWAYS_HIDE_AUTO)) {
  352. unset($arraylist['AC_OTH_AUTO']);
  353. }
  354. $out = '';
  355. if (!empty($multiselect)) {
  356. if (!is_array($selected) && !empty($selected)) {
  357. $selected = explode(',', $selected);
  358. }
  359. $out .= $form->multiselectarray($htmlname, $arraylist, $selected, 0, 0, 'centpercent', 0, 0);
  360. } else {
  361. $out .= $form->selectarray($htmlname, $arraylist, $selected, 0, 0, 0, '', 0, 0, 0, '', $morecss, 1);
  362. }
  363. if ($user->admin && empty($onlyautoornot) && $hideinfohelp <= 0) {
  364. $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup").($hideinfohelp == -1 ? ". ".$langs->trans("YouCanSetDefaultValueInModuleSetup") : ''), 1);
  365. }
  366. if ($nooutput) {
  367. return $out;
  368. } else {
  369. print $out;
  370. }
  371. return '';
  372. }
  373. }