accountancycategory.class.php 26 KB

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