html.formaccounting.class.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  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-2017 Alexandre Spangaro <aspangaro@zendsi.com>
  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 <http://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * \file htdocs/core/class/html.formaccounting.class.php
  23. * \ingroup Advanced accountancy
  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.NotCamelCaps
  51. /**
  52. * Return list of journals with label by nature
  53. *
  54. * @param string $selectid Preselected pcg_type
  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. 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. {
  73. $options = $this->options_cache[$usecache];
  74. $selected=$selectid;
  75. }
  76. else
  77. {
  78. $sql = "SELECT rowid, code, label, nature, entity, active";
  79. $sql.= " FROM " . MAIN_DB_PREFIX . "accounting_journal";
  80. $sql.= " WHERE active = 1";
  81. $sql.= " AND entity = ".$conf->entity;
  82. //if ($nature && is_numeric($nature)) $sql .= " AND nature = ".$nature;
  83. $sql.= " ORDER BY code";
  84. dol_syslog(get_class($this) . "::select_journal", LOG_DEBUG);
  85. $resql = $this->db->query($sql);
  86. if (!$resql) {
  87. $this->error = "Error ".$this->db->lasterror();
  88. dol_syslog(get_class($this)."::select_journal ".$this->error, LOG_ERR);
  89. return -1;
  90. }
  91. $selected = 0;
  92. $langs->load('accountancy');
  93. while ($obj = $this->db->fetch_object($resql))
  94. {
  95. $label = $obj->code . ' - ' . $langs->trans($obj->label);
  96. $select_value_in = $obj->rowid;
  97. $select_value_out = $obj->rowid;
  98. // Try to guess if we have found default value
  99. if ($select_in == 1) {
  100. $select_value_in = $obj->code;
  101. }
  102. if ($select_out == 1) {
  103. $select_value_out = $obj->code;
  104. }
  105. // Remember guy's we store in database llx_accounting_bookkeeping the code of accounting_journal and not the rowid
  106. if ($selectid != '' && $selectid == $select_value_in) {
  107. //var_dump("Found ".$selectid." ".$select_value_in);
  108. $selected = $select_value_out;
  109. }
  110. $options[$select_value_out] = $label;
  111. }
  112. $this->db->free($resql);
  113. if ($usecache)
  114. {
  115. $this->options_cache[$usecache] = $options;
  116. }
  117. }
  118. $out .= Form::selectarray($htmlname, $options, $selected, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, ($disabledajaxcombo?0:1));
  119. return $out;
  120. }
  121. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  122. /**
  123. * Return list of accounting category.
  124. * Use mysoc->country_id or mysoc->country_code so they must be defined.
  125. *
  126. * @param string $selected Preselected type
  127. * @param string $htmlname Name of field in form
  128. * @param int $useempty Set to 1 if we want an empty value
  129. * @param int $maxlen Max length of text in combo box
  130. * @param int $help Add or not the admin help picto
  131. * @param int $allcountries All countries
  132. * @return void
  133. */
  134. function select_accounting_category($selected='',$htmlname='account_category', $useempty=0, $maxlen=0, $help=1, $allcountries=0)
  135. {
  136. // phpcs:enable
  137. global $db,$langs,$user,$mysoc;
  138. if (empty($mysoc->country_id) && empty($mysoc->country_code) && empty($allcountries))
  139. {
  140. dol_print_error('','Call to select_accounting_account with mysoc country not yet defined');
  141. exit;
  142. }
  143. if (! empty($mysoc->country_id))
  144. {
  145. $sql = "SELECT c.rowid, c.label as type, c.range_account";
  146. $sql.= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
  147. $sql.= " WHERE c.active = 1";
  148. $sql.= " AND c.category_type = 0";
  149. if (empty($allcountries)) $sql.= " AND c.fk_country = ".$mysoc->country_id;
  150. $sql.= " ORDER BY c.label ASC";
  151. }
  152. else
  153. {
  154. $sql = "SELECT c.rowid, c.label as type, c.range_account";
  155. $sql.= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c, ".MAIN_DB_PREFIX."c_country as co";
  156. $sql.= " WHERE c.active = 1";
  157. $sql.= " AND c.category_type = 0";
  158. $sql.= " AND c.fk_country = co.rowid";
  159. if (empty($allcountries)) $sql.= " AND co.code = '".$mysoc->country_code."'";
  160. $sql.= " ORDER BY c.label ASC";
  161. }
  162. dol_syslog(get_class($this).'::'.__METHOD__, LOG_DEBUG);
  163. $resql=$db->query($sql);
  164. if ($resql)
  165. {
  166. $num = $db->num_rows($resql);
  167. if ($num)
  168. {
  169. $out = '<select class="flat minwidth200" id="'.$htmlname.'" name="'.$htmlname.'">';
  170. $i = 0;
  171. if ($useempty) $out.= '<option value="0">&nbsp;</option>';
  172. while ($i < $num)
  173. {
  174. $obj = $db->fetch_object($resql);
  175. $out .= '<option value="'.$obj->rowid.'"';
  176. if ($obj->rowid == $selected) $out .= ' selected';
  177. $out .= '>'.($maxlen ? dol_trunc($obj->type,$maxlen) : $obj->type);
  178. $out .= ' ('.$obj->range_account.')';
  179. $i++;
  180. }
  181. $out .= '</select>';
  182. //if ($user->admin && $help) $out .= info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1);
  183. }
  184. else
  185. {
  186. $out .= $langs->trans("ErrorNoAccountingCategoryForThisCountry",$mysoc->country_code);
  187. }
  188. }
  189. else
  190. {
  191. dol_print_error($db,$db->lasterror());
  192. }
  193. $out .= ajax_combobox($htmlname, array());
  194. print $out;
  195. }
  196. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  197. /**
  198. * Return select filter with date of transaction
  199. *
  200. * @param string $htmlname Name of select field
  201. * @param string $selectedkey Value
  202. * @return string HTML edit field
  203. */
  204. function select_bookkeeping_importkey($htmlname = 'importkey', $selectedkey = '')
  205. {
  206. // phpcs:enable
  207. $options = array();
  208. $sql = 'SELECT DISTINCT import_key from ' . MAIN_DB_PREFIX . 'accounting_bookkeeping';
  209. $sql .= " WHERE entity IN (".getEntity('accountancy').")";
  210. $sql .= ' ORDER BY import_key DESC';
  211. dol_syslog(get_class($this) . "::select_bookkeeping_importkey", LOG_DEBUG);
  212. $resql = $this->db->query($sql);
  213. if (!$resql) {
  214. $this->error = "Error " . $this->db->lasterror();
  215. dol_syslog(get_class($this) . "::select_bookkeeping_importkey " . $this->error, LOG_ERR);
  216. return - 1;
  217. }
  218. while ($obj = $this->db->fetch_object($resql)) {
  219. $options[$obj->import_key] = dol_print_date($obj->import_key, 'dayhourtext');
  220. }
  221. return Form::selectarray($htmlname, $options, $selectedkey);
  222. }
  223. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  224. /**
  225. * Return list of accounts with label by chart of accounts
  226. *
  227. * @param string $selectid Preselected id or code of accounting accounts (depends on $select_in)
  228. * @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.
  229. * @param int $showempty 1=Add an empty field, 2=Add an empty field+'None' field
  230. * @param array $event Event options
  231. * @param int $select_in 0=selectid value is a aa.rowid (default) or 1=selectid is aa.account_number
  232. * @param int $select_out Set value returned by select. 0=rowid (default), 1=account_number
  233. * @param string $morecss More css non HTML object
  234. * @param string $usecache Key to use to store result into a cache. Next call with same key will reuse the cache.
  235. * @return string String with HTML select
  236. */
  237. function select_account($selectid, $htmlname = 'account', $showempty = 0, $event = array(), $select_in = 0, $select_out = 0, $morecss='maxwidth300 maxwidthonsmartphone', $usecache='')
  238. {
  239. // phpcs:enable
  240. global $conf, $langs;
  241. require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
  242. $out = '';
  243. $options = array();
  244. if ($usecache && ! empty($this->options_cache[$usecache]))
  245. {
  246. $options = $this->options_cache[$usecache];
  247. $selected=$selectid;
  248. }
  249. else
  250. {
  251. $trunclength = empty($conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT) ? 50 : $conf->global->ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT;
  252. $sql = "SELECT DISTINCT aa.account_number, aa.label, aa.rowid, aa.fk_pcg_version";
  253. $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa";
  254. $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
  255. $sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS;
  256. $sql .= " AND aa.active = 1";
  257. $sql .= " AND aa.entity=".$conf->entity;
  258. $sql .= " ORDER BY aa.account_number";
  259. dol_syslog(get_class($this) . "::select_account", LOG_DEBUG);
  260. $resql = $this->db->query($sql);
  261. if (!$resql) {
  262. $this->error = "Error " . $this->db->lasterror();
  263. dol_syslog(get_class($this) . "::select_account " . $this->error, LOG_ERR);
  264. return -1;
  265. }
  266. $selected = 0;
  267. while ($obj = $this->db->fetch_object($resql))
  268. {
  269. $label = length_accountg($obj->account_number) . ' - ' . $obj->label;
  270. $label = dol_trunc($label, $trunclength);
  271. $select_value_in = $obj->rowid;
  272. $select_value_out = $obj->rowid;
  273. // Try to guess if we have found default value
  274. if ($select_in == 1) {
  275. $select_value_in = $obj->account_number;
  276. }
  277. if ($select_out == 1) {
  278. $select_value_out = $obj->account_number;
  279. }
  280. // Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number
  281. // Because same account_number can be share between different accounting_system and do have the same meaning
  282. if ($selectid != '' && $selectid == $select_value_in) {
  283. //var_dump("Found ".$selectid." ".$select_value_in);
  284. $selected = $select_value_out;
  285. }
  286. $options[$select_value_out] = $label;
  287. }
  288. $this->db->free($resql);
  289. if ($usecache)
  290. {
  291. $this->options_cache[$usecache] = $options;
  292. }
  293. }
  294. if ($showempty == 2)
  295. {
  296. $options['0'] = $langs->trans("None");
  297. }
  298. $out .= Form::selectarray($htmlname, $options, $selected, ($showempty > 0 ? 1 : 0), 0, 0, '', 0, 0, 0, '', $morecss, 1);
  299. return $out;
  300. }
  301. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  302. /**
  303. * Return list of auxilary thirdparty accounts
  304. *
  305. * @param string $selectid Preselected pcg_type
  306. * @param string $htmlname Name of field in html form
  307. * @param int $showempty Add an empty field
  308. * @param string $morecss More css
  309. * @return string String with HTML select
  310. */
  311. function select_auxaccount($selectid, $htmlname='account_num_aux', $showempty=0, $morecss='maxwidth200')
  312. {
  313. // phpcs:enable
  314. $aux_account = array();
  315. // Auxiliary customer account
  316. $sql = "SELECT DISTINCT code_compta, nom ";
  317. $sql .= " FROM ".MAIN_DB_PREFIX."societe";
  318. $sql .= " WHERE entity IN (" . getEntity('societe') . ")";
  319. $sql .= " ORDER BY code_compta";
  320. dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
  321. $resql = $this->db->query($sql);
  322. if ($resql) {
  323. while ($obj = $this->db->fetch_object($resql)) {
  324. if (!empty($obj->code_compta)) {
  325. $aux_account[$obj->code_compta] = $obj->code_compta.' ('.$obj->nom.')';
  326. }
  327. }
  328. } else {
  329. $this->error = "Error ".$this->db->lasterror();
  330. dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
  331. return -1;
  332. }
  333. $this->db->free($resql);
  334. // Auxiliary supplier account
  335. $sql = "SELECT DISTINCT code_compta_fournisseur, nom ";
  336. $sql .= " FROM ".MAIN_DB_PREFIX."societe";
  337. $sql .= " WHERE entity IN (" . getEntity('societe') . ")";
  338. $sql .= " ORDER BY code_compta_fournisseur";
  339. dol_syslog(get_class($this)."::select_auxaccount", LOG_DEBUG);
  340. $resql = $this->db->query($sql);
  341. if ($resql) {
  342. while ($obj = $this->db->fetch_object($resql)) {
  343. if (!empty($obj->code_compta_fournisseur)) {
  344. $aux_account[$obj->code_compta_fournisseur] = $obj->code_compta_fournisseur.' ('.$obj->nom.')';
  345. }
  346. }
  347. } else {
  348. $this->error = "Error ".$this->db->lasterror();
  349. dol_syslog(get_class($this)."::select_pcgsubtype ".$this->error, LOG_ERR);
  350. return -1;
  351. }
  352. $this->db->free($resql);
  353. // Build select
  354. $out .= Form::selectarray($htmlname, $aux_account, $selectid, $showempty, 0, 0, '', 0, 0, 0, '', $morecss, 1);
  355. return $out;
  356. }
  357. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
  358. /**
  359. * Return HTML combo list of years existing into book keepping
  360. *
  361. * @param string $selected Preselected value
  362. * @param string $htmlname Name of HTML select object
  363. * @param int $useempty Affiche valeur vide dans liste
  364. * @param string $output_format (html/opton (for option html only)/array (to return options arrays
  365. * @return string/array
  366. */
  367. function selectyear_accountancy_bookkepping($selected = '', $htmlname = 'yearid', $useempty = 0, $output_format = 'html')
  368. {
  369. // phpcs:enable
  370. global $conf;
  371. $out_array = array();
  372. $sql = "SELECT DISTINCT date_format(doc_date,'%Y') as dtyear";
  373. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping";
  374. $sql .= " WHERE entity IN (" . getEntity('accountancy') . ")";
  375. $sql .= " ORDER BY date_format(doc_date,'%Y')";
  376. dol_syslog(get_class($this)."::".__METHOD__, LOG_DEBUG);
  377. $resql = $this->db->query($sql);
  378. if (!$resql) {
  379. $this->error = "Error ".$this->db->lasterror();
  380. dol_syslog(get_class($this)."::".__METHOD__.$this->error, LOG_ERR);
  381. return -1;
  382. }
  383. while ($obj = $this->db->fetch_object($resql)) {
  384. $out_array[$obj->dtyear] = $obj->dtyear;
  385. }
  386. $this->db->free($resql);
  387. if ($output_format == 'html') {
  388. return Form::selectarray($htmlname, $out_array, $selected, $useempty, 0, 0, 'placeholder="aa"');
  389. } else {
  390. return $out_array;
  391. }
  392. }
  393. }