accountancycategory.class.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  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)) {
  130. $this->code = trim($this->code);
  131. }
  132. if (isset($this->label)) {
  133. $this->label = trim($this->label);
  134. }
  135. if (isset($this->range_account)) {
  136. $this->range_account = trim($this->range_account);
  137. }
  138. if (isset($this->sens)) {
  139. $this->sens = (int) $this->sens;
  140. }
  141. if (isset($this->category_type)) {
  142. $this->category_type = (int) $this->category_type;
  143. }
  144. if (isset($this->formula)) {
  145. $this->formula = trim($this->formula);
  146. }
  147. if (isset($this->position)) {
  148. $this->position = (int) $this->position;
  149. }
  150. if (isset($this->fk_country)) {
  151. $this->fk_country = (int) $this->fk_country;
  152. }
  153. if (isset($this->active)) {
  154. $this->active = (int) $this->active;
  155. }
  156. // Check parameters
  157. // Put here code to add control on parameters values
  158. // Insert request
  159. $sql = "INSERT INTO ".MAIN_DB_PREFIX."c_accounting_category(";
  160. if ($this->rowid > 0) {
  161. $sql .= "rowid, ";
  162. }
  163. $sql .= "code, ";
  164. $sql .= "label, ";
  165. $sql .= "range_account, ";
  166. $sql .= "sens, ";
  167. $sql .= "category_type, ";
  168. $sql .= "formula, ";
  169. $sql .= "position, ";
  170. $sql .= "fk_country, ";
  171. $sql .= "active, ";
  172. $sql .= "entity";
  173. $sql .= ") VALUES (";
  174. if ($this->rowid > 0) {
  175. $sql .= " ".$this->rowid.",";
  176. }
  177. $sql .= " ".(!isset($this->code) ? 'NULL' : "'".$this->db->escape($this->code)."'").",";
  178. $sql .= " ".(!isset($this->label) ? 'NULL' : "'".$this->db->escape($this->label)."'").",";
  179. $sql .= " ".(!isset($this->range_account) ? 'NULL' : "'".$this->db->escape($this->range_account)."'").",";
  180. $sql .= " ".(!isset($this->sens) ? 'NULL' : "'".$this->db->escape($this->sens)."'").",";
  181. $sql .= " ".(!isset($this->category_type) ? 'NULL' : "'".$this->db->escape($this->category_type)."'").",";
  182. $sql .= " ".(!isset($this->formula) ? 'NULL' : "'".$this->db->escape($this->formula)."'").",";
  183. $sql .= " ".(!isset($this->position) ? 'NULL' : $this->db->escape($this->position)).",";
  184. $sql .= " ".(!isset($this->fk_country) ? 'NULL' : $this->db->escape($this->fk_country)).",";
  185. $sql .= " ".(!isset($this->active) ? 'NULL' : $this->db->escape($this->active));
  186. $sql .= ", ".$conf->entity;
  187. $sql .= ")";
  188. $this->db->begin();
  189. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  190. $resql = $this->db->query($sql);
  191. if (!$resql) {
  192. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  193. }
  194. // Commit or rollback
  195. if ($error) {
  196. foreach ($this->errors as $errmsg) {
  197. dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
  198. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  199. }
  200. $this->db->rollback();
  201. return -1 * $error;
  202. } else {
  203. $this->db->commit();
  204. return $this->id;
  205. }
  206. }
  207. /**
  208. * Load object in memory from database
  209. *
  210. * @param int $id Id object
  211. * @param string $code Code
  212. * @param string $label Label
  213. * @return int <0 if KO, >0 if OK
  214. */
  215. public function fetch($id, $code = '', $label = '')
  216. {
  217. $sql = "SELECT";
  218. $sql .= " t.rowid,";
  219. $sql .= " t.code,";
  220. $sql .= " t.label,";
  221. $sql .= " t.range_account,";
  222. $sql .= " t.sens,";
  223. $sql .= " t.category_type,";
  224. $sql .= " t.formula,";
  225. $sql .= " t.position,";
  226. $sql .= " t.fk_country,";
  227. $sql .= " t.active";
  228. $sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as t";
  229. if ($id) {
  230. $sql .= " WHERE t.rowid = ".((int) $id);
  231. } else {
  232. $sql .= " WHERE t.entity IN (".getEntity('c_accounting_category').")"; // Dont't use entity if you use rowid
  233. if ($code) {
  234. $sql .= " AND t.code = '".$this->db->escape($code)."'";
  235. } elseif ($label) {
  236. $sql .= " AND t.label = '".$this->db->escape($label)."'";
  237. }
  238. }
  239. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  240. $resql = $this->db->query($sql);
  241. if ($resql) {
  242. if ($this->db->num_rows($resql)) {
  243. $obj = $this->db->fetch_object($resql);
  244. $this->id = $obj->rowid;
  245. $this->code = $obj->code;
  246. $this->label = $obj->label;
  247. $this->range_account = $obj->range_account;
  248. $this->sens = $obj->sens;
  249. $this->category_type = $obj->category_type;
  250. $this->formula = $obj->formula;
  251. $this->position = $obj->position;
  252. $this->fk_country = $obj->fk_country;
  253. $this->active = $obj->active;
  254. }
  255. $this->db->free($resql);
  256. return 1;
  257. } else {
  258. $this->error = "Error ".$this->db->lasterror();
  259. return -1;
  260. }
  261. }
  262. /**
  263. * Update object into database
  264. *
  265. * @param User $user User that modify
  266. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  267. * @return int <0 if KO, >0 if OK
  268. */
  269. public function update($user = null, $notrigger = 0)
  270. {
  271. global $conf, $langs;
  272. $error = 0;
  273. // Clean parameters
  274. if (isset($this->code)) {
  275. $this->code = trim($this->code);
  276. }
  277. if (isset($this->label)) {
  278. $this->label = trim($this->label);
  279. }
  280. if (isset($this->range_account)) {
  281. $this->range_account = trim($this->range_account);
  282. }
  283. if (isset($this->sens)) {
  284. $this->sens = (int) $this->sens;
  285. }
  286. if (isset($this->category_type)) {
  287. $this->category_type = (int) $this->category_type;
  288. }
  289. if (isset($this->formula)) {
  290. $this->formula = trim($this->formula);
  291. }
  292. if (isset($this->position)) {
  293. $this->position = (int) $this->position;
  294. }
  295. if (isset($this->fk_country)) {
  296. $this->fk_country = (int) $this->fk_country;
  297. }
  298. if (isset($this->active)) {
  299. $this->active = (int) $this->active;
  300. }
  301. // Check parameters
  302. // Put here code to add control on parameters values
  303. // Update request
  304. $sql = "UPDATE ".MAIN_DB_PREFIX."c_accounting_category SET";
  305. $sql .= " code=".(isset($this->code) ? "'".$this->db->escape($this->code)."'" : "null").",";
  306. $sql .= " label=".(isset($this->label) ? "'".$this->db->escape($this->label)."'" : "null").",";
  307. $sql .= " range_account=".(isset($this->range_account) ? "'".$this->db->escape($this->range_account)."'" : "null").",";
  308. $sql .= " sens=".(isset($this->sens) ? $this->sens : "null").",";
  309. $sql .= " category_type=".(isset($this->category_type) ? $this->category_type : "null").",";
  310. $sql .= " formula=".(isset($this->formula) ? "'".$this->db->escape($this->formula)."'" : "null").",";
  311. $sql .= " position=".(isset($this->position) ? $this->position : "null").",";
  312. $sql .= " fk_country=".(isset($this->fk_country) ? $this->fk_country : "null").",";
  313. $sql .= " active=".(isset($this->active) ? $this->active : "null")."";
  314. $sql .= " WHERE rowid=".((int) $this->id);
  315. $this->db->begin();
  316. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  317. $resql = $this->db->query($sql);
  318. if (!$resql) {
  319. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  320. }
  321. // Commit or rollback
  322. if ($error) {
  323. foreach ($this->errors as $errmsg) {
  324. dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
  325. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  326. }
  327. $this->db->rollback();
  328. return -1 * $error;
  329. } else {
  330. $this->db->commit();
  331. return 1;
  332. }
  333. }
  334. /**
  335. * Delete object in database
  336. *
  337. * @param User $user User that delete
  338. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  339. * @return int <0 if KO, >0 if OK
  340. */
  341. public function delete($user, $notrigger = 0)
  342. {
  343. global $conf, $langs;
  344. $error = 0;
  345. $sql = "DELETE FROM ".MAIN_DB_PREFIX."c_accounting_category";
  346. $sql .= " WHERE rowid=".((int) $this->id);
  347. $this->db->begin();
  348. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  349. $resql = $this->db->query($sql);
  350. if (!$resql) {
  351. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  352. }
  353. // Commit or rollback
  354. if ($error) {
  355. foreach ($this->errors as $errmsg) {
  356. dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
  357. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  358. }
  359. $this->db->rollback();
  360. return -1 * $error;
  361. } else {
  362. $this->db->commit();
  363. return 1;
  364. }
  365. }
  366. /**
  367. * Function to select all accounting accounts from an accounting category
  368. *
  369. * @param int $id Id
  370. * @return int <0 if KO, 0 if not found, >0 if OK
  371. */
  372. public function display($id)
  373. {
  374. global $conf;
  375. $sql = "SELECT t.rowid, t.account_number, t.label";
  376. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
  377. $sql .= " WHERE t.fk_accounting_category = ".((int) $id);
  378. $sql .= " AND t.entity = ".$conf->entity;
  379. $this->lines_display = array();
  380. dol_syslog(__METHOD__." sql=".$sql, LOG_DEBUG);
  381. $resql = $this->db->query($sql);
  382. if ($resql) {
  383. $num = $this->db->num_rows($resql);
  384. if ($num) {
  385. while ($obj = $this->db->fetch_object($resql)) {
  386. $this->lines_display[] = $obj;
  387. }
  388. }
  389. return $num;
  390. } else {
  391. $this->error = "Error ".$this->db->lasterror();
  392. $this->errors[] = $this->error;
  393. dol_syslog(__METHOD__." ".implode(','.$this->errors), LOG_ERR);
  394. return -1;
  395. }
  396. }
  397. /**
  398. * Function to select accounting category of an accounting account present in chart of accounts
  399. *
  400. * @param int $id Id category
  401. *
  402. * @return int <0 if KO, 0 if not found, >0 if OK
  403. */
  404. public function getCptBK($id)
  405. {
  406. global $conf;
  407. $sql = "SELECT t.numero_compte, t.label_operation, t.doc_ref";
  408. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t";
  409. $sql .= " WHERE t.numero_compte NOT IN (";
  410. $sql .= " SELECT t.account_number";
  411. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
  412. $sql .= " WHERE t.fk_accounting_category = ".$id." AND t.entity = ".$conf->entity.")";
  413. $sql .= " AND t.numero_compte IN (";
  414. $sql .= " SELECT DISTINCT aa.account_number";
  415. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa";
  416. $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
  417. $sql .= " AND asy.rowid = ".$conf->global->CHARTOFACCOUNTS;
  418. $sql .= " AND aa.active = 1";
  419. $sql .= " AND aa.entity = ".$conf->entity.")";
  420. $sql .= " GROUP BY t.numero_compte, t.label_operation, t.doc_ref";
  421. $sql .= " ORDER BY t.numero_compte";
  422. $this->lines_CptBk = array();
  423. dol_syslog(__METHOD__, LOG_DEBUG);
  424. $resql = $this->db->query($sql);
  425. if ($resql) {
  426. $num = $this->db->num_rows($resql);
  427. if ($num) {
  428. while ($obj = $this->db->fetch_object($resql)) {
  429. $this->lines_cptbk[] = $obj;
  430. }
  431. }
  432. return $num;
  433. } else {
  434. $this->error = "Error ".$this->db->lasterror();
  435. $this->errors[] = $this->error;
  436. dol_syslog(__METHOD__." ".implode(','.$this->errors), LOG_ERR);
  437. return -1;
  438. }
  439. }
  440. /**
  441. * Function to select accounting category of an accounting account present in chart of accounts
  442. *
  443. * @param int $id Id of category to know which account to exclude
  444. *
  445. * @return int <0 if KO, 0 if not found, >0 if OK
  446. */
  447. public function getAccountsWithNoCategory($id)
  448. {
  449. global $conf;
  450. $sql = "SELECT aa.account_number as numero_compte, aa.label as label_compte";
  451. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa";
  452. $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
  453. $sql .= " WHERE (aa.fk_accounting_category != ".$id." OR aa.fk_accounting_category IS NULL)";
  454. $sql .= " AND asy.rowid = ".$conf->global->CHARTOFACCOUNTS;
  455. $sql .= " AND aa.active = 1";
  456. $sql .= " AND aa.entity = ".$conf->entity;
  457. $sql .= " GROUP BY aa.account_number, aa.label";
  458. $sql .= " ORDER BY aa.account_number, aa.label";
  459. $this->lines_CptBk = array();
  460. dol_syslog(__METHOD__, LOG_DEBUG);
  461. $resql = $this->db->query($sql);
  462. if ($resql) {
  463. $num = $this->db->num_rows($resql);
  464. if ($num) {
  465. while ($obj = $this->db->fetch_object($resql)) {
  466. $this->lines_cptbk[] = $obj;
  467. }
  468. }
  469. return $num;
  470. } else {
  471. $this->error = "Error ".$this->db->lasterror();
  472. $this->errors[] = $this->error;
  473. dol_syslog(__METHOD__." ".implode(','.$this->errors), LOG_ERR);
  474. return -1;
  475. }
  476. }
  477. /**
  478. * Function to add an accounting account in an accounting category
  479. *
  480. * @param int $id_cat Id category
  481. * @param array $cpts list of accounts array
  482. *
  483. * @return int <0 if KO, >0 if OK
  484. */
  485. public function updateAccAcc($id_cat, $cpts = array())
  486. {
  487. global $conf;
  488. $error = 0;
  489. require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
  490. $sql = "SELECT aa.rowid, aa.account_number";
  491. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as aa";
  492. $sql .= " INNER JOIN ".MAIN_DB_PREFIX."accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version";
  493. $sql .= " AND asy.rowid = ".$conf->global->CHARTOFACCOUNTS;
  494. $sql .= " AND aa.active = 1";
  495. $sql .= " AND aa.entity = ".$conf->entity;
  496. $sql .= " ORDER BY LENGTH(aa.account_number) DESC;"; // LENGTH is ok with mysql and postgresql
  497. $this->db->begin();
  498. dol_syslog(__METHOD__, LOG_DEBUG);
  499. $resql = $this->db->query($sql);
  500. if (!$resql) {
  501. $error++;
  502. $this->errors[] = "Error ".$this->db->lasterror();
  503. $this->db->rollback();
  504. return -1;
  505. }
  506. $accountincptsadded = array();
  507. while ($obj = $this->db->fetch_object($resql)) {
  508. $account_number_formated = length_accountg($obj->account_number);
  509. if (!empty($accountincptsadded[$account_number_formated])) {
  510. continue;
  511. }
  512. if (array_key_exists($account_number_formated, $cpts)) {
  513. $accountincptsadded[$account_number_formated] = 1;
  514. // We found an account number that is in list $cpts of account to add
  515. $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account";
  516. $sql .= " SET fk_accounting_category=".$id_cat;
  517. $sql .= " WHERE rowid=".$obj->rowid;
  518. dol_syslog(__METHOD__, LOG_DEBUG);
  519. $resqlupdate = $this->db->query($sql);
  520. if (!$resqlupdate) {
  521. $error++;
  522. $this->errors[] = "Error ".$this->db->lasterror();
  523. }
  524. }
  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 delete an accounting account from an accounting category
  541. *
  542. * @param int $cpt_id Id of accounting account
  543. *
  544. * @return int <0 if KO, >0 if OK
  545. */
  546. public function deleteCptCat($cpt_id)
  547. {
  548. $error = 0;
  549. $sql = "UPDATE ".MAIN_DB_PREFIX."accounting_account as aa";
  550. $sql .= " SET fk_accounting_category= 0";
  551. $sql .= " WHERE aa.rowid= ".$cpt_id;
  552. $this->db->begin();
  553. dol_syslog(__METHOD__." sql=".$sql, LOG_DEBUG);
  554. $resql = $this->db->query($sql);
  555. if (!$resql) {
  556. $error++;
  557. $this->errors[] = "Error ".$this->db->lasterror();
  558. }
  559. // Commit or rollback
  560. if ($error) {
  561. foreach ($this->errors as $errmsg) {
  562. dol_syslog(__METHOD__." ".$errmsg, LOG_ERR);
  563. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  564. }
  565. $this->db->rollback();
  566. return -1 * $error;
  567. } else {
  568. $this->db->commit();
  569. return 1;
  570. }
  571. }
  572. /**
  573. * Function to know all category from accounting account
  574. *
  575. * @return array|integer Result in table (array), -1 if KO
  576. */
  577. public function getCatsCpts()
  578. {
  579. global $mysoc, $conf;
  580. if (empty($mysoc->country_id)) {
  581. dol_print_error('', 'Call to select_accounting_account with mysoc country not yet defined');
  582. exit();
  583. }
  584. $sql = "SELECT t.rowid, t.account_number, t.label as account_label, cat.code, cat.position, cat.label as name_cat, cat.sens ";
  585. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t, ".MAIN_DB_PREFIX."c_accounting_category as cat";
  586. $sql .= " WHERE t.fk_accounting_category IN ( SELECT c.rowid ";
  587. $sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
  588. $sql .= " WHERE c.active = 1";
  589. $sql .= " AND c.entity = ".$conf->entity;
  590. $sql .= " AND (c.fk_country = ".$mysoc->country_id." OR c.fk_country = 0)";
  591. $sql .= " AND cat.rowid = t.fk_accounting_category";
  592. $sql .= " AND t.entity = ".$conf->entity;
  593. $sql .= " ORDER BY cat.position ASC";
  594. $resql = $this->db->query($sql);
  595. if ($resql) {
  596. $i = 0;
  597. $obj = '';
  598. $num = $this->db->num_rows($resql);
  599. $data = array();
  600. if ($num) {
  601. while ($obj = $this->db->fetch_object($resql)) {
  602. $name_cat = $obj->name_cat;
  603. $data[$name_cat][$i] = array(
  604. 'id' => $obj->rowid,
  605. 'code' => $obj->code,
  606. 'position' => $obj->position,
  607. 'account_number' => $obj->account_number,
  608. 'account_label' => $obj->account_label,
  609. 'sens' => $obj->sens
  610. );
  611. $i++;
  612. }
  613. }
  614. return $data;
  615. } else {
  616. $this->error = "Error ".$this->db->lasterror();
  617. dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
  618. return -1;
  619. }
  620. }
  621. /**
  622. * Function to show result of an accounting account from the ledger with a direction and a period
  623. *
  624. * @param int|array $cpt Accounting account or array of accounting account
  625. * @param string $date_start Date start
  626. * @param string $date_end Date end
  627. * @param int $sens Sens of the account: 0: credit - debit (use this by default), 1: debit - credit
  628. * @param string $thirdparty_code Thirdparty code
  629. * @param int $month Specifig month - Can be empty
  630. * @param int $year Specifig year - Can be empty
  631. * @return integer <0 if KO, >= 0 if OK
  632. */
  633. public function getSumDebitCredit($cpt, $date_start, $date_end, $sens, $thirdparty_code = 'nofilter', $month = 0, $year = 0)
  634. {
  635. global $conf;
  636. $this->sdc = 0;
  637. $this->sdcpermonth = array();
  638. $sql = "SELECT SUM(t.debit) as debit, SUM(t.credit) as credit";
  639. if (is_array($cpt)) {
  640. $sql .= ", t.numero_compte as accountancy_account";
  641. }
  642. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as t";
  643. //if (in_array($this->db->type, array('mysql', 'mysqli'))) $sql.=' USE INDEX idx_accounting_bookkeeping_doc_date';
  644. $sql .= " WHERE t.entity = ".$conf->entity;
  645. if (is_array($cpt)) {
  646. $listofaccount = '';
  647. foreach ($cpt as $cptcursor) {
  648. if ($listofaccount) {
  649. $listofaccount .= ",";
  650. }
  651. $listofaccount .= "'".$cptcursor."'";
  652. }
  653. $sql .= " AND t.numero_compte IN (".$this->db->sanitize($listofaccount).")";
  654. } else {
  655. $sql .= " AND t.numero_compte = '".$this->db->escape($cpt)."'";
  656. }
  657. if (!empty($date_start) && !empty($date_end) && (empty($month) || empty($year))) { // If month/year provided, it is stronger than filter date_start/date_end
  658. $sql .= " AND (t.doc_date BETWEEN '".$this->db->idate($date_start)."' AND '".$this->db->idate($date_end)."')";
  659. }
  660. if (!empty($month) && !empty($year)) {
  661. $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))."')";
  662. }
  663. if ($thirdparty_code != 'nofilter') {
  664. $sql .= " AND t.thirdparty_code = '".$this->db->escape($thirdparty_code)."'";
  665. }
  666. if (is_array($cpt)) {
  667. $sql .= " GROUP BY t.numero_compte";
  668. }
  669. //print $sql;
  670. $resql = $this->db->query($sql);
  671. if ($resql) {
  672. $num = $this->db->num_rows($resql);
  673. if ($num) {
  674. $obj = $this->db->fetch_object($resql);
  675. if ($sens == 1) {
  676. $this->sdc = $obj->debit - $obj->credit;
  677. } else {
  678. $this->sdc = $obj->credit - $obj->debit;
  679. }
  680. if (is_array($cpt)) {
  681. $this->sdcperaccount[$obj->accountancy_account] = $this->sdc;
  682. }
  683. }
  684. return $num;
  685. } else {
  686. $this->error = "Error ".$this->db->lasterror();
  687. $this->errors[] = $this->error;
  688. dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
  689. return -1;
  690. }
  691. }
  692. /**
  693. * Return list of personalized groups that are active
  694. *
  695. * @param int $categorytype -1=All, 0=Only non computed groups, 1=Only computed groups
  696. * @return array|int Array of groups or -1 if error
  697. */
  698. public function getCats($categorytype = -1)
  699. {
  700. global $conf, $mysoc;
  701. if (empty($mysoc->country_id)) {
  702. dol_print_error('', 'Call to select_accounting_account with mysoc country not yet defined');
  703. exit();
  704. }
  705. $sql = "SELECT c.rowid, c.code, c.label, c.formula, c.position, c.category_type, c.sens";
  706. $sql .= " FROM ".MAIN_DB_PREFIX."c_accounting_category as c";
  707. $sql .= " WHERE c.active = 1";
  708. $sql .= " AND c.entity = ".$conf->entity;
  709. if ($categorytype >= 0) {
  710. $sql .= " AND c.category_type = 1";
  711. }
  712. $sql .= " AND (c.fk_country = ".$mysoc->country_id." OR c.fk_country = 0)";
  713. $sql .= " ORDER BY c.position ASC";
  714. $resql = $this->db->query($sql);
  715. if ($resql) {
  716. $i = 0;
  717. $obj = '';
  718. $num = $this->db->num_rows($resql);
  719. $data = array();
  720. if ($num) {
  721. while ($i < $num) {
  722. $obj = $this->db->fetch_object($resql);
  723. $data[] = array(
  724. 'rowid' => $obj->rowid,
  725. 'code' => $obj->code,
  726. 'label' => $obj->label,
  727. 'formula' => $obj->formula,
  728. 'position' => $obj->position,
  729. 'category_type' => $obj->category_type,
  730. 'bc' => $obj->sens
  731. );
  732. $i++;
  733. }
  734. }
  735. return $data;
  736. } else {
  737. $this->error = "Error ".$this->db->lasterror();
  738. $this->errors[] = $this->error;
  739. dol_syslog(__METHOD__." ".implode(',', $this->errors), LOG_ERR);
  740. return -1;
  741. }
  742. }
  743. /**
  744. * Get all accounting account of a group.
  745. * You must choose between first parameter (personalized group) or the second (free criteria filter)
  746. *
  747. * @param int $cat_id Id if personalized accounting group/category
  748. * @param string $predefinedgroupwhere Sql criteria filter to select accounting accounts
  749. * @return array|int Array of accounting accounts or -1 if error
  750. */
  751. public function getCptsCat($cat_id, $predefinedgroupwhere = '')
  752. {
  753. global $conf, $mysoc;
  754. $sql = '';
  755. if (empty($mysoc->country_id) && empty($mysoc->country_code)) {
  756. dol_print_error('', 'Call to select_accounting_account with mysoc country not yet defined');
  757. exit();
  758. }
  759. if (!empty($cat_id)) {
  760. $sql = "SELECT t.rowid, t.account_number, t.label as account_label";
  761. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
  762. $sql .= " WHERE t.fk_accounting_category = ".((int) $cat_id);
  763. $sql .= " AND t.entity = ".$conf->entity;
  764. $sql .= " ORDER BY t.account_number";
  765. } else {
  766. $sql = "SELECT t.rowid, t.account_number, t.label as account_label";
  767. $sql .= " FROM ".MAIN_DB_PREFIX."accounting_account as t";
  768. $sql .= " WHERE ".$predefinedgroupwhere;
  769. $sql .= " AND t.entity = ".$conf->entity;
  770. $sql .= " ORDER BY t.account_number";
  771. }
  772. //echo $sql;
  773. $resql = $this->db->query($sql);
  774. if ($resql) {
  775. $i = 0;
  776. $obj = '';
  777. $num = $this->db->num_rows($resql);
  778. $data = array();
  779. if ($num) {
  780. while ($obj = $this->db->fetch_object($resql)) {
  781. $data[] = array(
  782. 'id' => $obj->rowid,
  783. 'account_number' => $obj->account_number,
  784. 'account_label' => $obj->account_label,
  785. );
  786. $i++;
  787. }
  788. }
  789. return $data;
  790. } else {
  791. $this->error = "Error ".$this->db->lasterror();
  792. dol_syslog(__METHOD__." ".$this->error, LOG_ERR);
  793. return -1;
  794. }
  795. }
  796. }