html.formaccounting.class.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. <?php
  2. /* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
  3. * Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
  4. * Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
  5. * Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
  6. * Copyright (C) 2016-2020 Alexandre Spangaro <aspangaro@open-dsi.fr>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * \file htdocs/core/class/html.formaccounting.class.php
  23. * \ingroup Accountancy (Double entries)
  24. * \brief File of class with all html predefined components
  25. */
  26. require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
  27. /**
  28. * Class to manage generation of HTML components for accounting management
  29. */
  30. class FormAccounting extends Form
  31. {
  32. private $options_cache = array();
  33. /**
  34. * @var DoliDB Database handler.
  35. */
  36. public $db;
  37. /**
  38. * @var string Error code (or message)
  39. */
  40. public $error = '';
  41. /**
  42. * Constructor
  43. *
  44. * @param DoliDB $db Database handler
  45. */
  46. public function __construct($db)
  47. {
  48. $this->db = $db;
  49. }
  50. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  51. /**
  52. * Return list of journals with label by nature
  53. *
  54. * @param string $selectid Preselected journal code
  55. * @param string $htmlname Name of field in html form
  56. * @param int $nature Limit the list to a particular type of journals (1:various operations / 2:sale / 3:purchase / 4:bank / 9: has-new)
  57. * @param int $showempty Add an empty field
  58. * @param int $select_in 0=selectid value is the journal rowid (default) or 1=selectid is journal code
  59. * @param int $select_out Set value returned by select. 0=rowid (default), 1=code
  60. * @param string $morecss More css non HTML object
  61. * @param string $usecache Key to use to store result into a cache. Next call with same key will reuse the cache.
  62. * @param int $disabledajaxcombo Disable ajax combo box.
  63. * @return string String with HTML select
  64. */
  65. public function select_journal($selectid, $htmlname = 'journal', $nature = 0, $showempty = 0, $select_in = 0, $select_out = 0, $morecss = 'maxwidth300 maxwidthonsmartphone', $usecache = '', $disabledajaxcombo = 0)
  66. {
  67. // phpcs:enable
  68. global $conf, $langs;
  69. $out = '';
  70. $options = array();
  71. if ($usecache && !empty($this->options_cache[$usecache])) {
  72. $options = $this->options_cache[$usecache];
  73. $selected = $selectid;
  74. } else {
  75. $sql = "SELECT rowid, code, label, nature, entity, active";
  76. $sql .= " FROM ".$this->db->prefix()."accounting_journal";
  77. $sql .= " WHERE active = 1";
  78. $sql .= " AND entity = ".$conf->entity;
  79. if ($nature && is_numeric($nature)) {
  80. $sql .= " AND nature = ".((int) $nature);
  81. }
  82. $sql .= " ORDER BY code";
  83. dol_syslog(get_class($this)."::select_journal", LOG_DEBUG);
  84. $resql = $this->db->query($sql);
  85. if (!$resql) {
  86. $this->error = "Error ".$this->db->lasterror();
  87. dol_syslog(get_class($this)."::select_journal ".$this->error, LOG_ERR);
  88. return -1;
  89. }
  90. $selected = 0;
  91. $langs->load('accountancy');
  92. while ($obj = $this->db->fetch_object($resql)) {
  93. $label = $obj->code.' - '.$langs->trans($obj->label);
  94. $select_value_in = $obj->rowid;
  95. $select_value_out = $obj->rowid;
  96. // Try to guess if we have found default value
  97. if ($select_in == 1) {
  98. $select_value_in = $obj->code;
  99. }
  100. if ($select_out == 1) {
  101. $select_value_out = $obj->code;
  102. }
  103. // Remember guy's we store in database llx_accounting_bookkeeping the code of accounting_journal and not the rowid
  104. if ($selectid != '' && $selectid == $select_value_in) {
  105. //var_dump("Found ".$selectid." ".$select_value_in);
  106. $selected = $select_value_out;
  107. }
  108. $options[$select_value_out] = $label;
  109. }
  110. $this->db->free($resql);
  111. if ($usecache) {
  112. $this->options_cache[$usecache] = $options;
  113. }
  114. }
  115. $out .= Form::selectarray($htmlname, $options, $selected, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, ($disabledajaxcombo ? 0 : 1));
  116. return $out;
  117. }
  118. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  119. /**
  120. * Return list of journals with label by nature
  121. *
  122. * @param array $selectedIds Preselected journal code array
  123. * @param string $htmlname Name of field in html form
  124. * @param int $nature Limit the list to a particular type of journals (1:various operations / 2:sale / 3:purchase / 4:bank / 9: has-new)
  125. * @param int $showempty Add an empty field
  126. * @param int $select_in 0=selectid value is the journal rowid (default) or 1=selectid is journal code
  127. * @param int $select_out Set value returned by select. 0=rowid (default), 1=code
  128. * @param string $morecss More css non HTML object
  129. * @param string $usecache Key to use to store result into a cache. Next call with same key will reuse the cache.
  130. * @param int $disabledajaxcombo Disable ajax combo box.
  131. * @return string String with HTML select
  132. */
  133. public function multi_select_journal($selectedIds = array(), $htmlname = 'journal', $nature = 0, $showempty = 0, $select_in = 0, $select_out = 0, $morecss = '', $usecache = '', $disabledajaxcombo = 0)
  134. {
  135. // phpcs:enable
  136. global $conf, $langs;
  137. $out = '';
  138. $options = array();
  139. if ($usecache && !empty($this->options_cache[$usecache])) {
  140. $options = $this->options_cache[$usecache];
  141. $selected = $selectedIds;
  142. } else {
  143. $sql = "SELECT rowid, code, label, nature, entity, active";
  144. $sql .= " FROM ".$this->db->prefix()."accounting_journal";
  145. $sql .= " WHERE active = 1";
  146. $sql .= " AND entity = ".$conf->entity;
  147. if ($nature && is_numeric($nature)) {
  148. $sql .= " AND nature = ".((int) $nature);
  149. }
  150. $sql .= " ORDER BY code";
  151. dol_syslog(get_class($this)."::multi_select_journal", LOG_DEBUG);
  152. $resql = $this->db->query($sql);
  153. if (!$resql) {
  154. $this->error = "Error ".$this->db->lasterror();
  155. dol_syslog(get_class($this)."::multi_select_journal ".$this->error, LOG_ERR);
  156. return -1;
  157. }
  158. $selected = array();
  159. $langs->load('accountancy');
  160. while ($obj = $this->db->fetch_object($resql)) {
  161. $label = $langs->trans($obj->label);
  162. $select_value_in = $obj->rowid;
  163. $select_value_out = $obj->rowid;
  164. // Try to guess if we have found default value
  165. if ($select_in == 1) {
  166. $select_value_in = $obj->code;
  167. }
  168. if ($select_out == 1) {
  169. $select_value_out = $obj->code;
  170. }
  171. // Remember guy's we store in database llx_accounting_bookkeeping the code of accounting_journal and not the rowid
  172. if (!empty($selectedIds) && in_array($select_value_in, $selectedIds)) {
  173. //var_dump("Found ".$selectid." ".$select_value_in);
  174. $selected[] = $select_value_out;
  175. }
  176. $options[$select_value_out] = $label;
  177. }
  178. $this->db->free($resql);
  179. if ($usecache) {
  180. $this->options_cache[$usecache] = $options;
  181. }
  182. }
  183. $out .= Form::multiselectarray($htmlname, $options, $selected, $showempty, 0, $morecss, 0, 0, 0, 'code_journal', '', ($disabledajaxcombo ? 0 : 1));
  184. return $out;
  185. }
  186. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  187. /**
  188. * Return list of accounting category.
  189. * Use mysoc->country_id or mysoc->country_code so they must be defined.
  190. *
  191. * @param string $selected Preselected type
  192. * @param string $htmlname Name of field in form
  193. * @param int $useempty Set to 1 if we want an empty value
  194. * @param int $maxlen Max length of text in combo box
  195. * @param int $help Add or not the admin help picto
  196. * @param int $allcountries All countries
  197. * @return void
  198. */
  199. public function select_accounting_category($selected = '', $htmlname = 'account_category', $useempty = 0, $maxlen = 0, $help = 1, $allcountries = 0)
  200. {
  201. // phpcs:enable
  202. global $db, $langs, $user, $mysoc;
  203. if (empty($mysoc->country_id) && empty($mysoc->country_code) && empty($allcountries)) {
  204. dol_print_error('', 'Call to select_accounting_account with mysoc country not yet defined');
  205. exit;
  206. }
  207. if (!empty($mysoc->country_id)) {
  208. $sql = "SELECT c.rowid, c.label as type, c.range_account";
  209. $sql .= " FROM ".$this->db->prefix()."c_accounting_category as c";
  210. $sql .= " WHERE c.active = 1";
  211. $sql .= " AND c.category_type = 0";
  212. if (empty($allcountries)) {
  213. $sql .= " AND c.fk_country = ".((int) $mysoc->country_id);
  214. }
  215. $sql .= " ORDER BY c.label ASC";
  216. } else {
  217. $sql = "SELECT c.rowid, c.label as type, c.range_account";
  218. $sql .= " FROM ".$this->db->prefix()."c_accounting_category as c, ".$this->db->prefix()."c_country as co";
  219. $sql .= " WHERE c.active = 1";
  220. $sql .= " AND c.category_type = 0";
  221. $sql .= " AND c.fk_country = co.rowid";
  222. if (empty($allcountries)) {
  223. $sql .= " AND co.code = '".$this->db->escape($mysoc->country_code)."'";
  224. }
  225. $sql .= " ORDER BY c.label ASC";
  226. }
  227. dol_syslog(get_class($this).'::'.__METHOD__, LOG_DEBUG);
  228. $resql = $this->db->query($sql);
  229. if ($resql) {
  230. $num = $this->db->num_rows($resql);
  231. if ($num) {
  232. $out = '<select class="flat minwidth200" id="'.$htmlname.'" name="'.$htmlname.'">';
  233. $i = 0;
  234. if ($useempty) {
  235. $out .= '<option value="0">&nbsp;</option>';
  236. }
  237. while ($i < $num) {
  238. $obj = $this->db->fetch_object($resql);
  239. $titletoshowhtml = ($maxlen ? dol_trunc($obj->type, $maxlen) : $obj->type).($obj->range_account ? ' <span class="opacitymedium">('.$obj->range_account.')</span>' : '');
  240. $titletoshow = ($maxlen ? dol_trunc($obj->type, $maxlen) : $obj->type).($obj->range_account ? ' ('.$obj->range_account.')' : '');
  241. $out .= '<option value="'.$obj->rowid.'"';
  242. if ($obj->rowid == $selected) {
  243. $out .= ' selected';
  244. }
  245. $out .= ' data-html="'.dol_escape_htmltag(dol_string_onlythesehtmltags($titletoshowhtml, 1, 1, 0, 0, array('span'))).'"';
  246. $out .= '>';
  247. $out .= dol_escape_htmltag($titletoshow);
  248. $out .= '</option>';
  249. $i++;
  250. }
  251. $out .= '</select>';
  252. //if ($user->admin && $help) $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
  253. } else {
  254. $out = $langs->trans("ErrorNoAccountingCategoryForThisCountry", $mysoc->country_code);
  255. }
  256. } else {
  257. dol_print_error($this->db);
  258. }
  259. $out .= ajax_combobox($htmlname, array());
  260. print $out;
  261. }
  262. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  263. /**
  264. * Return select filter with date of transaction
  265. *
  266. * @param string $htmlname Name of select field
  267. * @param string $selectedkey Value
  268. * @return string HTML edit field
  269. */
  270. public function select_bookkeeping_importkey($htmlname = 'importkey', $selectedkey = '')
  271. {
  272. // phpcs:enable
  273. $options = array();
  274. $sql = "SELECT DISTINCT import_key FROM ".$this->db->prefix()."accounting_bookkeeping";
  275. $sql .= " WHERE entity IN (".getEntity('accountancy').")";
  276. $sql .= ' ORDER BY import_key DESC';
  277. dol_syslog(get_class($this)."::select_bookkeeping_importkey", LOG_DEBUG);
  278. $resql = $this->db->query($sql);
  279. if (!$resql) {
  280. $this->error = "Error ".$this->db->lasterror();
  281. dol_syslog(get_class($this)."::select_bookkeeping_importkey ".$this->error, LOG_ERR);
  282. return -1;
  283. }
  284. while ($obj = $this->db->fetch_object($resql)) {
  285. $options[$obj->import_key] = $obj->import_key;
  286. }
  287. return Form::selectarray($htmlname, $options, $selectedkey);
  288. }
  289. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  290. /**
  291. * Return list of accounts with label by chart of accounts
  292. *
  293. * @param string $selectid Preselected id of accounting accounts (depends on $select_in)
  294. * @param string $htmlname Name of HTML field id. If name start with '.', it is name of HTML css class, so several component with same name in different forms can be used.
  295. * @param int|string $showempty 1=Add an empty field, 2=Add an empty field+'None' field
  296. * @param array $event Event options
  297. * @param int $select_in 0=selectid value is a aa.rowid (default) or 1=selectid is aa.account_number
  298. * @param int $select_out Set value returned by select. 0=rowid (default), 1=account_number
  299. * @param string $morecss More css non HTML object
  300. * @param string $usecache Key to use to store result into a cache. Next call with same key will reuse the cache.
  301. * @param string $active Filter on status active or not: '0', '1' or '' for no filter
  302. * @return string String with HTML select
  303. */
  304. public function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $morecss = 'minwidth100 maxwidth300 maxwidthonsmartphone', $usecache = '', $active = '1')
  305. {
  306. // phpcs:enable
  307. global $conf, $langs;
  308. require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
  309. $out = '';
  310. $options = array();
  311. if ($showempty == 2) {
  312. $options['0'] = '--- '.$langs->trans("None").' ---';
  313. }
  314. if ($usecache && !empty($this->options_cache[$usecache])) {
  315. $options = $options + $this->options_cache[$usecache]; // We use + instead of array_merge because we don't want to reindex key from 0
  316. $selected = $selectid;
  317. } else {
  318. $trunclength = getDolGlobalInt('ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT', 50);
  319. $sql = "SELECT DISTINCT aa.account_number, aa.label, aa.labelshort, aa.rowid, aa.fk_pcg_version";
  320. $sql .= " FROM ".$this->db->prefix()."accounting_account as aa";
  321. $sql .= " INNER JOIN ".$this->db->prefix()."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
  322. $sql .= " AND asy.rowid = ".((int) $conf->global->CHARTOFACCOUNTS);
  323. if ($active === '1') {
  324. $sql .= " AND aa.active = 1";
  325. } elseif ($active === '0') {
  326. $sql .= " AND aa.active = 0";
  327. }
  328. $sql .= " AND aa.entity=".((int) $conf->entity);
  329. $sql .= " ORDER BY aa.account_number";
  330. dol_syslog(get_class($this)."::select_account", LOG_DEBUG);
  331. $resql = $this->db->query($sql);
  332. if (!$resql) {
  333. $this->error = "Error ".$this->db->lasterror();
  334. dol_syslog(get_class($this)."::select_account ".$this->error, LOG_ERR);
  335. return -1;
  336. }
  337. $num_rows = $this->db->num_rows($resql);
  338. if ($num_rows == 0 && (empty($conf->global->CHARTOFACCOUNTS) || $conf->global->CHARTOFACCOUNTS < 0)) {
  339. $langs->load("errors");
  340. $showempty = $langs->trans("ErrorYouMustFirstSetupYourChartOfAccount");
  341. } else {
  342. $selected = $selectid; // selectid can be -1, 0, 123
  343. while ($obj = $this->db->fetch_object($resql)) {
  344. if (empty($obj->labelshort)) {
  345. $labeltoshow = $obj->label;
  346. } else {
  347. $labeltoshow = $obj->labelshort;
  348. }
  349. $label = length_accountg($obj->account_number).' - '.$labeltoshow;
  350. $label = dol_trunc($label, $trunclength);
  351. $select_value_in = $obj->rowid;
  352. $select_value_out = $obj->rowid;
  353. // Try to guess if we have found default value
  354. if ($select_in == 1) {
  355. $select_value_in = $obj->account_number;
  356. }
  357. if ($select_out == 1) {
  358. $select_value_out = $obj->account_number;
  359. }
  360. // Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number
  361. // Because same account_number can be share between different accounting_system and do have the same meaning
  362. if ($selectid != '' && $selectid == $select_value_in) {
  363. //var_dump("Found ".$selectid." ".$select_value_in);
  364. $selected = $select_value_out;
  365. }
  366. $options[$select_value_out] = $label;
  367. }
  368. }
  369. $this->db->free($resql);
  370. if ($usecache) {
  371. $this->options_cache[$usecache] = $options;
  372. unset($this->options_cache[$usecache]['0']);
  373. }
  374. }
  375. $out .= Form::selectarray($htmlname, $options, $selected, ($showempty ? (is_numeric($showempty) ? 1 : $showempty): 0), 0, 0, '', 0, 0, 0, '', $morecss, 1);
  376. return $out;
  377. }
  378. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  379. /**
  380. * Return list of auxilary accounts. Cumulate list from customers, suppliers and users.
  381. *
  382. * @param string $selectid Preselected pcg_type
  383. * @param string $htmlname Name of field in html form
  384. * @param int|string $showempty Add an empty field
  385. * @param string $morecss More css
  386. * @param string $usecache Key to use to store result into a cache. Next call with same key will reuse the cache.
  387. * @param string $labelhtmlname HTML name of label for autofill of account from name.
  388. * @return string String with HTML select
  389. */
  390. public function select_auxaccount($selectid, $htmlname = 'account_num_aux', $showempty = 0, $morecss = 'maxwidth250', $usecache = '', $labelhtmlname = '')
  391. {
  392. // phpcs:enable
  393. $aux_account = array();
  394. if ($usecache && !empty($this->options_cache[$usecache])) {
  395. $aux_account = $aux_account + $this->options_cache[$usecache]; // We use + instead of array_merge because we don't want to reindex key from 0
  396. } else {
  397. dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
  398. // Auxiliary thirdparties account
  399. $sql = "SELECT code_compta, code_compta_fournisseur, nom as name";
  400. $sql .= " FROM ".$this->db->prefix()."societe";
  401. $sql .= " WHERE entity IN (".getEntity('societe').")";
  402. $sql .= " AND (client IN (1,3) OR fournisseur = 1)";
  403. $resql = $this->db->query($sql);
  404. if ($resql) {
  405. while ($obj = $this->db->fetch_object($resql)) {
  406. if (!empty($obj->code_compta)) {
  407. $aux_account[$obj->code_compta] = $obj->code_compta.' <span class="opacitymedium">('.$obj->name.')</span>';
  408. }
  409. if (!empty($obj->code_compta_fournisseur)) {
  410. $aux_account[$obj->code_compta_fournisseur] = $obj->code_compta_fournisseur.' <span class="opacitymedium">('.$obj->name.')</span>';
  411. }
  412. }
  413. } else {
  414. $this->error = "Error ".$this->db->lasterror();
  415. dol_syslog(get_class($this)."::select_auxaccount ".$this->error, LOG_ERR);
  416. return -1;
  417. }
  418. ksort($aux_account);
  419. $this->db->free($resql);
  420. // Auxiliary user account
  421. $sql = "SELECT DISTINCT accountancy_code, lastname, firstname ";
  422. $sql .= " FROM ".$this->db->prefix()."user";
  423. $sql .= " WHERE entity IN (".getEntity('user').")";
  424. $sql .= " ORDER BY accountancy_code";
  425. $resql = $this->db->query($sql);
  426. if ($resql) {
  427. while ($obj = $this->db->fetch_object($resql)) {
  428. if (!empty($obj->accountancy_code)) {
  429. $aux_account[$obj->accountancy_code] = $obj->accountancy_code.' <span class="opacitymedium">('.dolGetFirstLastname($obj->firstname, $obj->lastname).')</span>';
  430. }
  431. }
  432. } else {
  433. $this->error = "Error ".$this->db->lasterror();
  434. dol_syslog(get_class($this)."::select_auxaccount ".$this->error, LOG_ERR);
  435. return -1;
  436. }
  437. $this->db->free($resql);
  438. if ($usecache) {
  439. $this->options_cache[$usecache] = $aux_account;
  440. }
  441. }
  442. // Build select
  443. $out = '';
  444. $out .= Form::selectarray($htmlname, $aux_account, $selectid, ($showempty ? (is_numeric($showempty) ? 1 : $showempty): 0), 0, 0, '', 0, 0, 0, '', $morecss, 1);
  445. //automatic filling if we give the name of the subledger_label input
  446. if (!empty($conf->use_javascript_ajax) && !empty($labelhtmlname)) {
  447. $out .= '<script>
  448. jQuery(document).ready(() => {
  449. $("#'.$htmlname.'").on("select2:select", function(e) {
  450. var regExp = /\(([^)]+)\)/;
  451. const match = regExp.exec(e.params.data.text);
  452. $(\'input[name="'.dol_escape_js($labelhtmlname).'"]\').val(match[1]);
  453. });
  454. });
  455. </script>';
  456. }
  457. return $out;
  458. }
  459. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  460. /**
  461. * Return HTML combo list of years existing into book keepping
  462. *
  463. * @param string $selected Preselected value
  464. * @param string $htmlname Name of HTML select object
  465. * @param int $useempty Affiche valeur vide dans liste
  466. * @param string $output_format (html/opton (for option html only)/array (to return options arrays
  467. * @return string|array HTML select component or array of select options
  468. */
  469. public function selectyear_accountancy_bookkepping($selected = '', $htmlname = 'yearid', $useempty = 0, $output_format = 'html')
  470. {
  471. // phpcs:enable
  472. global $conf;
  473. $out_array = array();
  474. $sql = "SELECT DISTINCT date_format(doc_date, '%Y') as dtyear";
  475. $sql .= " FROM ".$this->db->prefix()."accounting_bookkeeping";
  476. $sql .= " WHERE entity IN (".getEntity('accountancy').")";
  477. $sql .= " ORDER BY date_format(doc_date, '%Y')";
  478. dol_syslog(__METHOD__, LOG_DEBUG);
  479. $resql = $this->db->query($sql);
  480. if (!$resql) {
  481. $this->error = "Error ".$this->db->lasterror();
  482. dol_syslog(__METHOD__.$this->error, LOG_ERR);
  483. return -1;
  484. }
  485. while ($obj = $this->db->fetch_object($resql)) {
  486. $out_array[$obj->dtyear] = $obj->dtyear;
  487. }
  488. $this->db->free($resql);
  489. if ($output_format == 'html') {
  490. return Form::selectarray($htmlname, $out_array, $selected, $useempty, 0, 0, 'placeholder="aa"');
  491. } else {
  492. return $out_array;
  493. }
  494. }
  495. }