accountancycategory.class.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. <?php
  2. /* Copyright (C) 2016 Jamal Elbaz <jamelbaz@gmail.pro>
  3. * Copyright (C) 2016-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
  4. * Copyright (C) 2018-2019 Frédéric France <frederic.france@netlogic.fr>
  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/accountancy/class/accountancycategory.class.php
  21. * \ingroup Accountancy (Double entries)
  22. * \brief File of class to manage categories of an accounting category_type
  23. */
  24. // Class
  25. require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
  26. /**
  27. * Class to manage categories of an accounting account
  28. */
  29. class AccountancyCategory // extends CommonObject
  30. {
  31. /**
  32. * @var DoliDB Database handler.
  33. */
  34. public $db;
  35. /**
  36. * @var string Error string
  37. */
  38. public $error;
  39. /**
  40. * @var string[] Error codes (or messages)
  41. */
  42. public $errors = array();
  43. /**
  44. * @var string ID to identify managed object
  45. */
  46. public $element = 'c_accounting_category';
  47. /**
  48. * @var string Name of table without prefix where object is stored
  49. */
  50. public $table_element = 'c_accounting_category';
  51. /**
  52. * @var int ID
  53. * @deprecated
  54. */
  55. public $rowid;
  56. /**
  57. * @var int ID
  58. */
  59. public $id;
  60. /**
  61. * @var string Accountancy code
  62. */
  63. public $code;
  64. /**
  65. * @var string Accountancy Category label
  66. */
  67. public $label;
  68. /**
  69. * @var string Accountancy range account
  70. */
  71. public $range_account;
  72. /**
  73. * @var int Sens of the account: 0: credit - debit, 1: debit - credit
  74. */
  75. public $sens;
  76. /**
  77. * @var int Category type of accountancy
  78. */
  79. public $category_type;
  80. /**
  81. * @var string Formula
  82. */
  83. public $formula;
  84. /**
  85. * @var int Position
  86. */
  87. public $position;
  88. /**
  89. * @var int country id
  90. */
  91. public $fk_country;
  92. /**
  93. * @var int Is active
  94. */
  95. public $active;
  96. /**
  97. * @var array Lines cptbk
  98. */
  99. public $lines_cptbk;
  100. /**
  101. * @var array Lines display
  102. */
  103. public $lines_display;
  104. /**
  105. * @var mixed Sample property 1
  106. */
  107. public $sdc;
  108. /**
  109. * Constructor
  110. *
  111. * @param DoliDb $db Database handler
  112. */
  113. public function __construct($db)
  114. {
  115. $this->db = $db;
  116. }
  117. /**
  118. * Create object into database
  119. *
  120. * @param User $user User that create
  121. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  122. * @return int <0 if KO, Id of created object if OK
  123. */
  124. public function create($user, $notrigger = 0)
  125. {
  126. global $conf, $langs;
  127. $error = 0;
  128. // Clean parameters
  129. if (isset($this->code)) $this->code = trim($this->code);
  130. if (isset($this->label)) $this->label = trim($this->label);
  131. if (isset($this->range_account)) $this->range_account = trim($this->range_account);
  132. if (isset($this->sens)) $this->sens = (int) $this->sens;
  133. if (isset($this->category_type)) $this->category_type = (int) $this->category_type;
  134. if (isset($this->formula)) $this->formula = trim($this->formula);
  135. if (isset($this->position)) $this->position = (int) $this->position;
  136. if (isset($this->fk_country)) $this->fk_country = (int) $this->fk_country;
  137. if (isset($this->active)) $this->active = (int) $this->active;
  138. // Check parameters
  139. // Put here code to add control on parameters values
  140. // Insert request
  141. $sql = "INSERT INTO ".MAIN_DB_PREFIX."c_accounting_category(";
  142. if ($this->rowid > 0) $sql .= "rowid, ";
  143. $sql .= "code, ";
  144. $sql .= "label, ";
  145. $sql .= "range_account, ";
  146. $sql .= "sens, ";
  147. $sql .= "category_type, ";
  148. $sql .= "formula, ";
  149. $sql .= "position, ";
  150. $sql .= "fk_country, ";
  151. $sql .= "active, ";
  152. $sql .= "entity";
  153. $sql .= ") VALUES (";
  154. if ($this->rowid > 0) $sql .= " ".$this->rowid.",";
  155. $sql .= " ".(!isset($this->code) ? 'NULL' : "'".$this->db->escape($this->code)."'").",";
  156. $sql .= " ".(!isset($this->label) ? 'NULL' : "'".$this->db->escape($this->label)."'").",";
  157. $sql .= " ".(!isset($this->range_account) ? 'NULL' : "'".$this->db->escape($this->range_account)."'").",";
  158. $sql .= " ".(!isset($this->sens) ? 'NULL' : "'".$this->db->escape($this->sens)."'").",";
  159. $sql .= " ".(!isset($this->category_type) ? 'NULL' : "'".$this->db->escape($this->category_type)."'").",";
  160. $sql .= " ".(!isset($this->formula) ? 'NULL' : "'".$this->db->escape($this->formula)."'").",";
  161. $sql .= " ".(!isset($this->position) ? 'NULL' : $this->db->escape($this->position)).",";
  162. $sql .= " ".(!isset($this->fk_country) ? 'NULL' : $this->db->escape($this->fk_country)).",";
  163. $sql .= " ".(!isset($this->active) ? 'NULL' : $this->db->escape($this->active));
  164. $sql .= ", ".$conf->entity;
  165. $sql .= ")";
  166. $this->db->begin();
  167. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  168. $resql = $this->db->query($sql);
  169. if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); }
  170. // Commit or rollback
  171. if ($error)
  172. {
  173. foreach ($this->errors as $errmsg)
  174. {
  175. dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
  176. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  177. }
  178. $this->db->rollback();
  179. return -1 * $error;
  180. }
  181. else
  182. {
  183. $this->db->commit();
  184. return $this->id;
  185. }
  186. }
  187. /**
  188. * Load object in memory from database
  189. *
  190. * @param int $id Id object
  191. * @param string $code Code
  192. * @param string $label Label
  193. * @return int <0 if KO, >0 if OK
  194. */
  195. public function fetch($id, $code = '', $label = '')
  196. {
  197. $sql = "SELECT";
  198. $sql .= " t.rowid,";
  199. $sql .= " t.code,";
  200. $sql .= " t.label,";
  201. $sql .= " t.range_account,";
  202. $sql .= " t.sens,";
  203. $sql .= " t.category_type,";
  204. $sql .= " t.formula,";
  205. $sql .= " t.position,";
  206. $sql .= " t.fk_country,";
  207. $sql .= " t.active";
  208. $sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as t";
  209. if ($id) $sql .= " WHERE t.rowid = ".$id;
  210. else
  211. {
  212. $sql .= " WHERE t.entity IN (".getEntity('c_accounting_category').")"; // Dont't use entity if you use rowid
  213. if ($code) $sql .= " AND t.code = '".$this->db->escape($code)."'";
  214. elseif ($label) $sql .= " AND t.label = '".$this->db->escape($label)."'";
  215. }
  216. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  217. $resql = $this->db->query($sql);
  218. if ($resql)
  219. {
  220. if ($this->db->num_rows($resql))
  221. {
  222. $obj = $this->db->fetch_object($resql);
  223. $this->id = $obj->rowid;
  224. $this->code = $obj->code;
  225. $this->label = $obj->label;
  226. $this->range_account = $obj->range_account;
  227. $this->sens = $obj->sens;
  228. $this->category_type = $obj->category_type;
  229. $this->formula = $obj->formula;
  230. $this->position = $obj->position;
  231. $this->fk_country = $obj->fk_country;
  232. $this->active = $obj->active;
  233. }
  234. $this->db->free($resql);
  235. return 1;
  236. }
  237. else
  238. {
  239. $this->error = "Error ".$this->db->lasterror();
  240. return -1;
  241. }
  242. }
  243. /**
  244. * Update object into database
  245. *
  246. * @param User $user User that modify
  247. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  248. * @return int <0 if KO, >0 if OK
  249. */
  250. public function update($user = null, $notrigger = 0)
  251. {
  252. global $conf, $langs;
  253. $error = 0;
  254. // Clean parameters
  255. if (isset($this->code)) $this->code = trim($this->code);
  256. if (isset($this->label)) $this->label = trim($this->label);
  257. if (isset($this->range_account)) $this->range_account = trim($this->range_account);
  258. if (isset($this->sens)) $this->sens = (int) $this->sens;
  259. if (isset($this->category_type)) $this->category_type = (int) $this->category_type;
  260. if (isset($this->formula)) $this->formula = trim($this->formula);
  261. if (isset($this->position)) $this->position = (int) $this->position;
  262. if (isset($this->fk_country)) $this->fk_country = (int) $this->fk_country;
  263. if (isset($this->active)) $this->active = (int) $this->active;
  264. // Check parameters
  265. // Put here code to add control on parameters values
  266. // Update request
  267. $sql = "UPDATE ".MAIN_DB_PREFIX."c_accounting_category SET";
  268. $sql .= " code=".(isset($this->code) ? "'".$this->db->escape($this->code)."'" : "null").",";
  269. $sql .= " label=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").",";
  270. $sql .= " range_account=".(isset($this->range_account) ? "'".$this->db->escape($this->range_account)."'" : "null").",";
  271. $sql .= " sens=".(isset($this->sens) ? $this->sens : "null").",";
  272. $sql .= " category_type=".(isset($this->category_type) ? $this->category_type : "null").",";
  273. $sql .= " formula=".(isset($this->formula) ? "'".$this->db->escape($this->formula)."'" : "null").",";
  274. $sql .= " position=".(isset($this->position) ? $this->position : "null").",";
  275. $sql .= " fk_country=".(isset($this->fk_country) ? $this->fk_country : "null").",";
  276. $sql .= " active=".(isset($this->active) ? $this->active : "null")."";
  277. $sql .= " WHERE rowid=".$this->id;
  278. $this->db->begin();
  279. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  280. $resql = $this->db->query($sql);
  281. if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); }
  282. // Commit or rollback
  283. if ($error)
  284. {
  285. foreach ($this->errors as $errmsg)
  286. {
  287. dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
  288. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  289. }
  290. $this->db->rollback();
  291. return -1 * $error;
  292. }
  293. else
  294. {
  295. $this->db->commit();
  296. return 1;
  297. }
  298. }
  299. /**
  300. * Delete object in database
  301. *
  302. * @param User $user User that delete
  303. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  304. * @return int <0 if KO, >0 if OK
  305. */
  306. public function delete($user, $notrigger = 0)
  307. {
  308. global $conf, $langs;
  309. $error = 0;
  310. $sql = "DELETE FROM ".MAIN_DB_PREFIX."c_accounting_category";
  311. $sql .= " WHERE rowid=".$this->id;
  312. $this->db->begin();
  313. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  314. $resql = $this->db->query($sql);
  315. if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); }
  316. // Commit or rollback
  317. if ($error)
  318. {
  319. foreach ($this->errors as $errmsg)
  320. {
  321. dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
  322. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  323. }
  324. $this->db->rollback();
  325. return -1 * $error;
  326. }
  327. else
  328. {
  329. $this->db->commit();
  330. return 1;
  331. }
  332. }
  333. /**
  334. * Function to select all accounting accounts from an accounting category
  335. *
  336. * @param int $id Id
  337. * @return int <0 if KO, 0 if not found, >0 if OK
  338. */
  339. public function display($id)
  340. {
  341. global $conf;
  342. $sql = "SELECT t.rowid, t.account_number, t.label";
  343. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
  344. $sql .= " WHERE t.fk_accounting_category = ".$id;
  345. $sql .= " AND t.entity = ".$conf->entity;
  346. $this->lines_display = array();
  347. dol_syslog(__METHOD__." sql=".$sql, LOG_DEBUG);
  348. $resql = $this->db->query($sql);
  349. if ($resql) {
  350. $num = $this->db->num_rows($resql);
  351. if ($num) {
  352. while ($obj = $this->db->fetch_object($resql)) {
  353. $this->lines_display[] = $obj;
  354. }
  355. }
  356. return $num;
  357. } else {
  358. $this->error = "Error ".$this->db->lasterror();
  359. $this->errors[] = $this->error;
  360. dol_syslog(__METHOD__." ".implode(','.$this->errors), LOG_ERR);
  361. return -1;
  362. }
  363. }
  364. /**
  365. * Function to select accounting category of an accounting account present in chart of accounts
  366. *
  367. * @param int $id Id category
  368. *
  369. * @return int <0 if KO, 0 if not found, >0 if OK
  370. */
  371. public function getCptBK($id)
  372. {
  373. global $conf;
  374. $sql = "SELECT t.numero_compte, t.label_operation, t.doc_ref";
  375. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t";
  376. $sql .= " WHERE t.numero_compte NOT IN (";
  377. $sql .= " SELECT t.account_number";
  378. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
  379. $sql .= " WHERE t.fk_accounting_category = ".$id." AND t.entity = ".$conf->entity.")";
  380. $sql .= " AND t.numero_compte IN (";
  381. $sql .= " SELECT DISTINCT aa.account_number";
  382. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa";
  383. $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
  384. $sql .= " AND asy.rowid = ".$conf->global->CHARTOFACCOUNTS;
  385. $sql .= " AND aa.active = 1";
  386. $sql .= " AND aa.entity = ".$conf->entity.")";
  387. $sql .= " GROUP BY t.numero_compte, t.label_operation, t.doc_ref";
  388. $sql .= " ORDER BY t.numero_compte";
  389. $this->lines_CptBk = array();
  390. dol_syslog(__METHOD__, LOG_DEBUG);
  391. $resql = $this->db->query($sql);
  392. if ($resql) {
  393. $num = $this->db->num_rows($resql);
  394. if ($num) {
  395. while ($obj = $this->db->fetch_object($resql)) {
  396. $this->lines_cptbk[] = $obj;
  397. }
  398. }
  399. return $num;
  400. } else {
  401. $this->error = "Error ".$this->db->lasterror();
  402. $this->errors[] = $this->error;
  403. dol_syslog(__METHOD__." ".implode(','.$this->errors), LOG_ERR);
  404. return -1;
  405. }
  406. }
  407. /**
  408. * Function to select accounting category of an accounting account present in chart of accounts
  409. *
  410. * @param int $id Id of category to know which account to exclude
  411. *
  412. * @return int <0 if KO, 0 if not found, >0 if OK
  413. */
  414. public function getAccountsWithNoCategory($id)
  415. {
  416. global $conf;
  417. $sql = "SELECT aa.account_number as numero_compte, aa.label as label_compte";
  418. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa";
  419. $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
  420. $sql .= " WHERE (aa.fk_accounting_category != ".$id." OR aa.fk_accounting_category IS NULL)";
  421. $sql .= " AND asy.rowid = ".$conf->global->CHARTOFACCOUNTS;
  422. $sql .= " AND aa.active = 1";
  423. $sql .= " AND aa.entity = ".$conf->entity;
  424. $sql .= " GROUP BY aa.account_number, aa.label";
  425. $sql .= " ORDER BY aa.account_number, aa.label";
  426. $this->lines_CptBk = array();
  427. dol_syslog(__METHOD__, LOG_DEBUG);
  428. $resql = $this->db->query($sql);
  429. if ($resql) {
  430. $num = $this->db->num_rows($resql);
  431. if ($num) {
  432. while ($obj = $this->db->fetch_object($resql)) {
  433. $this->lines_cptbk[] = $obj;
  434. }
  435. }
  436. return $num;
  437. } else {
  438. $this->error = "Error ".$this->db->lasterror();
  439. $this->errors[] = $this->error;
  440. dol_syslog(__METHOD__." ".implode(','.$this->errors), LOG_ERR);
  441. return -1;
  442. }
  443. }
  444. /**
  445. * Function to add an accounting account in an accounting category
  446. *
  447. * @param int $id_cat Id category
  448. * @param array $cpts list of accounts array
  449. *
  450. * @return int <0 if KO, >0 if OK
  451. */
  452. public function updateAccAcc($id_cat, $cpts = array())
  453. {
  454. global $conf;
  455. $error = 0;
  456. require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
  457. $sql = "SELECT aa.rowid, aa.account_number";
  458. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa";
  459. $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
  460. $sql .= " AND asy.rowid = ".$conf->global->CHARTOFACCOUNTS;
  461. $sql .= " AND aa.active = 1";
  462. $sql .= " AND aa.entity = ".$conf->entity;
  463. $sql .= " ORDER BY LENGTH(aa.account_number) DESC;"; // LENGTH is ok with mysql and postgresql
  464. $this->db->begin();
  465. dol_syslog(__METHOD__, LOG_DEBUG);
  466. $resql = $this->db->query($sql);
  467. if (!$resql) {
  468. $error++;
  469. $this->errors[] = "Error ".$this->db->lasterror();
  470. $this->db->rollback();
  471. return -1;
  472. }
  473. $accountincptsadded = array();
  474. while ($obj = $this->db->fetch_object($resql))
  475. {
  476. $account_number_formated = length_accountg($obj->account_number);
  477. if (!empty($accountincptsadded[$account_number_formated])) continue;
  478. if (array_key_exists($account_number_formated, $cpts))
  479. {
  480. $accountincptsadded[$account_number_formated] = 1;
  481. // We found an account number that is in list $cpts of account to add
  482. $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account";
  483. $sql .= " SET fk_accounting_category=".$id_cat;
  484. $sql .= " WHERE rowid=".$obj->rowid;
  485. dol_syslog(__METHOD__, LOG_DEBUG);
  486. $resqlupdate = $this->db->query($sql);
  487. if (!$resqlupdate) {
  488. $error++;
  489. $this->errors[] = "Error ".$this->db->lasterror();
  490. }
  491. }
  492. }
  493. // Commit or rollback
  494. if ($error) {
  495. foreach ($this->errors as $errmsg) {
  496. dol_syslog(__METHOD__." ".$errmsg, LOG_ERR);
  497. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  498. }
  499. $this->db->rollback();
  500. return -1 * $error;
  501. } else {
  502. $this->db->commit();
  503. return 1;
  504. }
  505. }
  506. /**
  507. * Function to delete an accounting account from an accounting category
  508. *
  509. * @param int $cpt_id Id of accounting account
  510. *
  511. * @return int <0 if KO, >0 if OK
  512. */
  513. public function deleteCptCat($cpt_id)
  514. {
  515. $error = 0;
  516. $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account as aa";
  517. $sql .= " SET fk_accounting_category= 0";
  518. $sql .= " WHERE aa.rowid= ".$cpt_id;
  519. $this->db->begin();
  520. dol_syslog(__METHOD__." sql=".$sql, LOG_DEBUG);
  521. $resql = $this->db->query($sql);
  522. if (!$resql) {
  523. $error++;
  524. $this->errors[] = "Error ".$this->db->lasterror();
  525. }
  526. // Commit or rollback
  527. if ($error) {
  528. foreach ($this->errors as $errmsg) {
  529. dol_syslog(__METHOD__." ".$errmsg, LOG_ERR);
  530. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  531. }
  532. $this->db->rollback();
  533. return -1 * $error;
  534. } else {
  535. $this->db->commit();
  536. return 1;
  537. }
  538. }
  539. /**
  540. * Function to know all category from accounting account
  541. *
  542. * @return array|integer Result in table (array), -1 if KO
  543. */
  544. public function getCatsCpts()
  545. {
  546. global $mysoc, $conf;
  547. if (empty($mysoc->country_id)) {
  548. dol_print_error('', 'Call to select_accounting_account with mysoc country not yet defined');
  549. exit();
  550. }
  551. $sql = "SELECT t.rowid, t.account_number, t.label as account_label, cat.code, cat.position, cat.label as name_cat, cat.sens ";
  552. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t, ".MAIN_DB_PREFIX."c_accounting_category as cat";
  553. $sql .= " WHERE t.fk_accounting_category IN ( SELECT c.rowid ";
  554. $sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
  555. $sql .= " WHERE c.active = 1";
  556. $sql .= " AND c.entity = ".$conf->entity;
  557. $sql .= " AND (c.fk_country = ".$mysoc->country_id." OR c.fk_country = 0)";
  558. $sql .= " AND cat.rowid = t.fk_accounting_category";
  559. $sql .= " AND t.entity = ".$conf->entity;
  560. $sql .= " ORDER BY cat.position ASC";
  561. $resql = $this->db->query($sql);
  562. if ($resql) {
  563. $i = 0;
  564. $obj = '';
  565. $num = $this->db->num_rows($resql);
  566. $data = array();
  567. if ($num) {
  568. while ($obj = $this->db->fetch_object($resql)) {
  569. $name_cat = $obj->name_cat;
  570. $data[$name_cat][$i] = array(
  571. 'id' => $obj->rowid,
  572. 'code' => $obj->code,
  573. 'position' => $obj->position,
  574. 'account_number' => $obj->account_number,
  575. 'account_label' => $obj->account_label,
  576. 'sens' => $obj->sens
  577. );
  578. $i++;
  579. }
  580. }
  581. return $data;
  582. } else {
  583. $this->error = "Error ".$this->db->lasterror();
  584. dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
  585. return -1;
  586. }
  587. }
  588. /**
  589. * Function to show result of an accounting account from the ledger with a direction and a period
  590. *
  591. * @param int|array $cpt Accounting account or array of accounting account
  592. * @param string $date_start Date start
  593. * @param string $date_end Date end
  594. * @param int $sens Sens of the account: 0: credit - debit (use this by default), 1: debit - credit
  595. * @param string $thirdparty_code Thirdparty code
  596. * @param int $month Specifig month - Can be empty
  597. * @param int $year Specifig year - Can be empty
  598. * @return integer <0 if KO, >= 0 if OK
  599. */
  600. public function getSumDebitCredit($cpt, $date_start, $date_end, $sens, $thirdparty_code = 'nofilter', $month = 0, $year = 0)
  601. {
  602. global $conf;
  603. $this->sdc = 0;
  604. $this->sdcpermonth = array();
  605. $sql = "SELECT SUM(t.debit) as debit, SUM(t.credit) as credit";
  606. if (is_array($cpt)) $sql .= ", t.numero_compte as accountancy_account";
  607. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t";
  608. //if (in_array($this->db->type, array('mysql', 'mysqli'))) $sql.=' USE INDEX idx_accounting_bookkeeping_doc_date';
  609. $sql .= " WHERE t.entity = ".$conf->entity;
  610. if (is_array($cpt))
  611. {
  612. $listofaccount = '';
  613. foreach ($cpt as $cptcursor)
  614. {
  615. if ($listofaccount) $listofaccount .= ",";
  616. $listofaccount .= "'".$cptcursor."'";
  617. }
  618. $sql .= " AND t.numero_compte IN (".$listofaccount.")";
  619. }
  620. else
  621. {
  622. $sql .= " AND t.numero_compte = '".$this->db->escape($cpt)."'";
  623. }
  624. if (!empty($date_start) && !empty($date_end) && (empty($month) || empty($year))) // If month/year provided, it is stronger than filter date_start/date_end
  625. $sql .= " AND (t.doc_date BETWEEN '".$this->db->idate($date_start)."' AND '".$this->db->idate($date_end)."')";
  626. if (!empty($month) && !empty($year)) {
  627. $sql .= " AND (t.doc_date BETWEEN '".$this->db->idate(dol_get_first_day($year, $month))."' AND '".$this->db->idate(dol_get_last_day($year, $month))."')";
  628. }
  629. if ($thirdparty_code != 'nofilter')
  630. {
  631. $sql .= " AND t.thirdparty_code = '".$this->db->escape($thirdparty_code)."'";
  632. }
  633. if (is_array($cpt)) $sql .= " GROUP BY t.numero_compte";
  634. //print $sql;
  635. $resql = $this->db->query($sql);
  636. if ($resql)
  637. {
  638. $num = $this->db->num_rows($resql);
  639. if ($num)
  640. {
  641. $obj = $this->db->fetch_object($resql);
  642. if ($sens == 1) {
  643. $this->sdc = $obj->debit - $obj->credit;
  644. } else {
  645. $this->sdc = $obj->credit - $obj->debit;
  646. }
  647. if (is_array($cpt))
  648. {
  649. $this->sdcperaccount[$obj->accountancy_account] = $this->sdc;
  650. }
  651. }
  652. return $num;
  653. } else {
  654. $this->error = "Error ".$this->db->lasterror();
  655. $this->errors[] = $this->error;
  656. dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
  657. return -1;
  658. }
  659. }
  660. /**
  661. * Return list of personalized groups that are active
  662. *
  663. * @param int $categorytype -1=All, 0=Only non computed groups, 1=Only computed groups
  664. * @return array|int Array of groups or -1 if error
  665. */
  666. public function getCats($categorytype = -1)
  667. {
  668. global $conf, $mysoc;
  669. if (empty($mysoc->country_id)) {
  670. dol_print_error('', 'Call to select_accounting_account with mysoc country not yet defined');
  671. exit();
  672. }
  673. $sql = "SELECT c.rowid, c.code, c.label, c.formula, c.position, c.category_type, c.sens";
  674. $sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
  675. $sql .= " WHERE c.active = 1";
  676. $sql .= " AND c.entity = ".$conf->entity;
  677. if ($categorytype >= 0) $sql .= " AND c.category_type = 1";
  678. $sql .= " AND (c.fk_country = ".$mysoc->country_id." OR c.fk_country = 0)";
  679. $sql .= " ORDER BY c.position ASC";
  680. $resql = $this->db->query($sql);
  681. if ($resql) {
  682. $i = 0;
  683. $obj = '';
  684. $num = $this->db->num_rows($resql);
  685. $data = array();
  686. if ($num) {
  687. while ($i < $num) {
  688. $obj = $this->db->fetch_object($resql);
  689. $data[] = array(
  690. 'rowid' => $obj->rowid,
  691. 'code' => $obj->code,
  692. 'label' => $obj->label,
  693. 'formula' => $obj->formula,
  694. 'position' => $obj->position,
  695. 'category_type' => $obj->category_type,
  696. 'bc' => $obj->sens
  697. );
  698. $i++;
  699. }
  700. }
  701. return $data;
  702. } else {
  703. $this->error = "Error ".$this->db->lasterror();
  704. $this->errors[] = $this->error;
  705. dol_syslog(__METHOD__." ".implode(',', $this->errors), LOG_ERR);
  706. return -1;
  707. }
  708. }
  709. /**
  710. * Get all accounting account of a group.
  711. * You must choose between first parameter (personalized group) or the second (free criteria filter)
  712. *
  713. * @param int $cat_id Id if personalized accounting group/category
  714. * @param string $predefinedgroupwhere Sql criteria filter to select accounting accounts
  715. * @return array|int Array of accounting accounts or -1 if error
  716. */
  717. public function getCptsCat($cat_id, $predefinedgroupwhere = '')
  718. {
  719. global $conf, $mysoc;
  720. $sql = '';
  721. if (empty($mysoc->country_id) && empty($mysoc->country_code)) {
  722. dol_print_error('', 'Call to select_accounting_account with mysoc country not yet defined');
  723. exit();
  724. }
  725. if (!empty($cat_id))
  726. {
  727. $sql = "SELECT t.rowid, t.account_number, t.label as account_label";
  728. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
  729. $sql .= " WHERE t.fk_accounting_category = ".$cat_id;
  730. $sql .= " AND t.entity = ".$conf->entity;
  731. $sql .= " ORDER BY t.account_number";
  732. }
  733. else
  734. {
  735. $sql = "SELECT t.rowid, t.account_number, t.label as account_label";
  736. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
  737. $sql .= " WHERE ".$predefinedgroupwhere;
  738. $sql .= " AND t.entity = ".$conf->entity;
  739. $sql .= " ORDER BY t.account_number";
  740. }
  741. //echo $sql;
  742. $resql = $this->db->query($sql);
  743. if ($resql) {
  744. $i = 0;
  745. $obj = '';
  746. $num = $this->db->num_rows($resql);
  747. $data = array();
  748. if ($num) {
  749. while ($obj = $this->db->fetch_object($resql))
  750. {
  751. $data[] = array(
  752. 'id' => $obj->rowid,
  753. 'account_number' => $obj->account_number,
  754. 'account_label' => $obj->account_label,
  755. );
  756. $i++;
  757. }
  758. }
  759. return $data;
  760. } else {
  761. $this->error = "Error ".$this->db->lasterror();
  762. dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
  763. return -1;
  764. }
  765. }
  766. }