PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/compta/bank/class/account.class.php

https://github.com/asterix14/dolibarr
PHP | 1376 lines | 962 code | 178 blank | 236 comment | 137 complexity | 197ad5ace2717767c745f27721577eca MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2001-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
  4. * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2004 Christophe Combelles <ccomb@free.fr>
  6. * Copyright (C) 2005-2010 Regis Houssin <regis@dolibarr.fr>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * \file htdocs/compta/bank/class/account.class.php
  23. * \ingroup banque
  24. * \brief File of class to manage bank accounts
  25. */
  26. require_once(DOL_DOCUMENT_ROOT ."/core/class/commonobject.class.php");
  27. /**
  28. * \class Account
  29. * \brief Class to manage bank accounts
  30. */
  31. class Account extends CommonObject
  32. {
  33. public $element='bank_account';
  34. public $table_element='bank_account';
  35. var $rowid;
  36. var $ref;
  37. var $label;
  38. //! 1=Compte courant/check/carte, 2=Compte liquide, 0=Compte ĂŠpargne
  39. var $courant;
  40. var $type; // same as courant
  41. //! Name
  42. var $bank;
  43. var $clos;
  44. var $rappro; // If bank need to be conciliated
  45. var $url;
  46. //! BBAN field for French Code banque
  47. var $code_banque;
  48. //! BBAN field for French Code guichet
  49. var $code_guichet;
  50. //! BBAN main account number
  51. var $number;
  52. //! BBAN field for French Cle de controle
  53. var $cle_rib;
  54. //! BIC/SWIFT number
  55. var $bic;
  56. //! IBAN number (International Bank Account Number)
  57. var $iban_prefix;
  58. var $proprio;
  59. var $adresse_proprio;
  60. var $fk_departement;
  61. var $departement_code;
  62. var $departement;
  63. var $fk_pays;
  64. var $pays_code;
  65. var $pays;
  66. var $type_lib=array();
  67. var $account_number;
  68. var $currency_code;
  69. var $min_allowed;
  70. var $min_desired;
  71. var $comment;
  72. /**
  73. * Constructeur
  74. */
  75. function Account($DB)
  76. {
  77. global $langs;
  78. $this->db = $DB;
  79. $this->clos = 0;
  80. $this->solde = 0;
  81. $this->type_lib[0]=$langs->trans("BankType0");
  82. $this->type_lib[1]=$langs->trans("BankType1");
  83. $this->type_lib[2]=$langs->trans("BankType2");
  84. $this->status[0]=$langs->trans("StatusAccountOpened");
  85. $this->status[1]=$langs->trans("StatusAccountClosed");
  86. return 1;
  87. }
  88. /**
  89. * Return if a bank account need to be conciliated
  90. * @return int 1 if need to be concialiated, < 0 otherwise.
  91. */
  92. function canBeConciliated()
  93. {
  94. if (empty($this->rappro)) return -1;
  95. if ($this->courant == 2) return -2;
  96. if ($this->clos) return -3;
  97. return 1;
  98. }
  99. /**
  100. * Add a link between bank line record and its source
  101. * @param line_id Id ecriture bancaire
  102. * @param url_id Id parametre url
  103. * @param url Url
  104. * @param label Link label
  105. * @param type Type of link ('payment', 'company', 'member', ...)
  106. * @return int <0 if KO, id line if OK
  107. */
  108. function add_url_line($line_id, $url_id, $url, $label, $type)
  109. {
  110. $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_url (";
  111. $sql.= "fk_bank";
  112. $sql.= ", url_id";
  113. $sql.= ", url";
  114. $sql.= ", label";
  115. $sql.= ", type";
  116. $sql.= ") VALUES (";
  117. $sql.= "'".$line_id."'";
  118. $sql.= ", '".$url_id."'";
  119. $sql.= ", '".$url."'";
  120. $sql.= ", '".$this->db->escape($label)."'";
  121. $sql.= ", '".$type."'";
  122. $sql.= ")";
  123. dol_syslog(get_class($this)."::add_url_line sql=".$sql);
  124. if ($this->db->query($sql))
  125. {
  126. $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_url");
  127. return $rowid;
  128. }
  129. else
  130. {
  131. $this->error=$this->db->lasterror();
  132. dol_syslog(get_class($this)."::add_url_line ".$this->error, LOG_ERR);
  133. return -1;
  134. }
  135. }
  136. /**
  137. * TODO Move this into AccountLine
  138. * Return array with links from llx_bank_url
  139. * @param fk_bank To search using bank transaction id
  140. * @param url_id To search using link to
  141. * @param type To search using type
  142. * @return array Array of links
  143. */
  144. function get_url($fk_bank='', $url_id='', $type='')
  145. {
  146. $lines = array();
  147. // Check parameters
  148. if (! empty($fk_bank) && (! empty($url_id) || ! empty($type)))
  149. {
  150. $this->error="ErrorBadParameter";
  151. return -1;
  152. }
  153. $sql = "SELECT fk_bank, url_id, url, label, type";
  154. $sql.= " FROM ".MAIN_DB_PREFIX."bank_url";
  155. if ($fk_bank > 0) { $sql.= " WHERE fk_bank = ".$fk_bank; }
  156. else { $sql.= " WHERE url_id = ".$url_id." AND type = '".$type."'"; }
  157. $sql.= " ORDER BY type, label";
  158. dol_syslog(get_class($this)."::get_url sql=".$sql);
  159. $result = $this->db->query($sql);
  160. if ($result)
  161. {
  162. $i = 0;
  163. $num = $this->db->num_rows($result);
  164. while ($i < $num)
  165. {
  166. $obj = $this->db->fetch_object($result);
  167. // Anciens liens (pour compatibilite)
  168. $lines[$i][0] = $obj->url;
  169. $lines[$i][1] = $obj->url_id;
  170. $lines[$i][2] = $obj->label;
  171. $lines[$i][3] = $obj->type;
  172. // Nouveaux liens
  173. $lines[$i]['url'] = $obj->url;
  174. $lines[$i]['url_id'] = $obj->url_id;
  175. $lines[$i]['label'] = $obj->label;
  176. $lines[$i]['type'] = $obj->type;
  177. $lines[$i]['fk_bank'] = $obj->fk_bank;
  178. $i++;
  179. }
  180. }
  181. else dol_print_error($this->db);
  182. return $lines;
  183. }
  184. /**
  185. * Add an entry into table ".MAIN_DB_PREFIX."bank
  186. * @param $date Date operation
  187. * @param $oper 1,2,3,4... (deprecated) or TYP,VIR,PRE,LIQ,VAD,CB,CHQ...
  188. * @param $label Descripton
  189. * @param $amount Amount
  190. * @param $num_chq Numero cheque ou virement
  191. * @param $categorie Categorie optionnelle
  192. * @param $user User that create
  193. * @param $emetteur Name of cheque writer
  194. * @param $banque Bank of cheque writer
  195. * @return int Rowid of added entry, <0 if KO
  196. */
  197. function addline($date, $oper, $label, $amount, $num_chq='', $categorie='', $user, $emetteur='',$banque='')
  198. {
  199. // Clean parameters
  200. $emetteur=trim($emetteur);
  201. $banque=trim($banque);
  202. $now=dol_now();
  203. if (is_numeric($oper)) // Clean oper to have a code instead of a rowid
  204. {
  205. $sql ="SELECT code FROM ".MAIN_DB_PREFIX."c_paiement";
  206. $sql.=" WHERE id=".$oper;
  207. $resql=$this->db->query($sql);
  208. if ($resql)
  209. {
  210. $obj=$this->db->fetch_object($resql);
  211. $oper=$obj->code;
  212. }
  213. else
  214. {
  215. dol_print_error($this->db,'Failed to get payment type code');
  216. return -1;
  217. }
  218. }
  219. // Check parameters
  220. if (! $oper)
  221. {
  222. $this->error="Account::addline oper not defined";
  223. return -1;
  224. }
  225. if (! $this->rowid)
  226. {
  227. $this->error="Account::addline this->rowid not defined";
  228. return -2;
  229. }
  230. if ($this->courant == 2 && $oper != 'LIQ')
  231. {
  232. $this->error="ErrorCashAccountAcceptsOnlyCashMoney";
  233. return -3;
  234. }
  235. $this->db->begin();
  236. $datev = $date;
  237. $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
  238. $sql.= "datec";
  239. $sql.= ", dateo";
  240. $sql.= ", datev";
  241. $sql.= ", label";
  242. $sql.= ", amount";
  243. $sql.= ", fk_user_author";
  244. $sql.= ", num_chq";
  245. $sql.= ", fk_account";
  246. $sql.= ", fk_type";
  247. $sql.= ",emetteur,banque";
  248. $sql.= ") VALUES (";
  249. $sql.= "'".$this->db->idate($now)."'";
  250. $sql.= ", '".$this->db->idate($date)."'";
  251. $sql.= ", '".$this->db->idate($datev)."'";
  252. $sql.= ", '".$this->db->escape($label)."'";
  253. $sql.= ", ".price2num($amount);
  254. $sql.= ", '".$user->id."'";
  255. $sql.= ", ".($num_chq?"'".$num_chq."'":"null");
  256. $sql.= ", '".$this->rowid."'";
  257. $sql.= ", '".$oper."'";
  258. $sql.= ", ".($emetteur?"'".$this->db->escape($emetteur)."'":"null");
  259. $sql.= ", ".($banque?"'".$this->db->escape($banque)."'":"null");
  260. $sql.= ")";
  261. dol_syslog("Account::addline sql=".$sql);
  262. if ($this->db->query($sql))
  263. {
  264. $rowid = $this->db->last_insert_id(MAIN_DB_PREFIX."bank");
  265. if ($categorie)
  266. {
  267. $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
  268. $sql.= "lineid";
  269. $sql.= ", fk_categ";
  270. $sql.= ") VALUES (";
  271. $sql.= "'".$rowid."'";
  272. $sql.= ", '".$categorie."'";
  273. $sql.= ")";
  274. $result = $this->db->query($sql);
  275. if (! $result)
  276. {
  277. $this->db->rollback();
  278. $this->error=$this->db->error();
  279. return -3;
  280. }
  281. }
  282. $this->db->commit();
  283. return $rowid;
  284. }
  285. else
  286. {
  287. $this->error=$this->db->lasterror();
  288. dol_syslog("Account::addline ".$this->error, LOG_ERR);
  289. $this->db->rollback();
  290. return -2;
  291. }
  292. }
  293. /**
  294. * Create bank account into database
  295. * @param user Object user making action
  296. * @return int < 0 if KO, > 0 if OK
  297. */
  298. function create($user='')
  299. {
  300. global $langs,$conf;
  301. // Check parameters
  302. if (! $this->min_allowed) $this->min_allowed=0;
  303. if (! $this->min_desired) $this->min_desired=0;
  304. if (empty($this->fk_pays))
  305. {
  306. $this->error=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Country"));
  307. dol_syslog("Account::update ".$this->error, LOG_ERR);
  308. return -1;
  309. }
  310. if (empty($this->ref))
  311. {
  312. $this->error=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref"));
  313. dol_syslog("Account::update ".$this->error, LOG_ERR);
  314. return -1;
  315. }
  316. // Chargement librairie pour acces fonction controle RIB
  317. require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php';
  318. $now=dol_now();
  319. $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_account (";
  320. $sql.= "datec";
  321. $sql.= ", ref";
  322. $sql.= ", label";
  323. $sql.= ", entity";
  324. $sql.= ", account_number";
  325. $sql.= ", currency_code";
  326. $sql.= ", rappro";
  327. $sql.= ", min_allowed";
  328. $sql.= ", min_desired";
  329. $sql.= ", comment";
  330. $sql.= ", fk_departement";
  331. $sql.= ", fk_pays";
  332. $sql.= ") VALUES (";
  333. $sql.= "'".$this->db->idate($now)."'";
  334. $sql.= ", '".$this->db->escape($this->ref)."'";
  335. $sql.= ", '".$this->db->escape($this->label)."'";
  336. $sql.= ", ".$conf->entity;
  337. $sql.= ", '".$this->db->escape($this->account_number)."'";
  338. $sql.= ", '".$this->currency_code."'";
  339. $sql.= ", ".$this->rappro;
  340. $sql.= ", ".price2num($this->min_allowed);
  341. $sql.= ", ".price2num($this->min_desired);
  342. $sql.= ", '".$this->db->escape($this->comment)."'";
  343. $sql.= ", ".($this->fk_departement>0?"'".$this->fk_departement."'":"null");
  344. $sql.= ", ".$this->fk_pays;
  345. $sql.= ")";
  346. dol_syslog("Account::create sql=".$sql);
  347. $resql=$this->db->query($sql);
  348. if ($resql)
  349. {
  350. if ($this->db->affected_rows($resql))
  351. {
  352. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bank_account");
  353. if ( $this->update() )
  354. {
  355. $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank (";
  356. $sql.= "datec";
  357. $sql.= ", label";
  358. $sql.= ", amount";
  359. $sql.= ", fk_account";
  360. $sql.= ", datev";
  361. $sql.= ", dateo";
  362. $sql.= ", fk_type";
  363. $sql.= ", rappro";
  364. $sql.= ") VALUES (";
  365. $sql.= $this->db->idate($now);
  366. $sql.= ", '(".$langs->trans("InitialBankBalance").")'";
  367. $sql.= ", ".price2num($this->solde);
  368. $sql.= ", '".$this->id."'";
  369. $sql.= ", '".$this->db->idate($this->date_solde)."'";
  370. $sql.= ", '".$this->db->idate($this->date_solde)."'";
  371. $sql.= ", 'SOLD'";
  372. $sql.= ", 0"; // Not conciliated by default
  373. $sql.= ")";
  374. $this->db->query($sql);
  375. }
  376. return $this->id;
  377. }
  378. }
  379. else
  380. {
  381. if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
  382. {
  383. $this->error=$langs->trans("ErrorBankLabelAlreadyExists");
  384. dol_syslog($this->error, LOG_ERR);
  385. return -1;
  386. }
  387. else {
  388. $this->error=$this->db->error()." sql=".$sql;
  389. dol_syslog($this->error, LOG_ERR);
  390. return -2;
  391. }
  392. }
  393. }
  394. /**
  395. * Update bank account card
  396. * @param user Object user making action
  397. * @return int <0 si ko, >0 si ok
  398. */
  399. function update($user='')
  400. {
  401. global $langs,$conf;
  402. // Check parameters
  403. if (! $this->min_allowed) $this->min_allowed=0;
  404. if (! $this->min_desired) $this->min_desired=0;
  405. if (empty($this->fk_pays))
  406. {
  407. $this->error=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Country"));
  408. dol_syslog("Account::update ".$this->error, LOG_ERR);
  409. return -1;
  410. }
  411. if (empty($this->ref))
  412. {
  413. $this->error=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Ref"));
  414. dol_syslog("Account::update ".$this->error, LOG_ERR);
  415. return -1;
  416. }
  417. if (! $this->label) $this->label = "???";
  418. $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
  419. $sql.= " ref = '".$this->db->escape($this->ref)."'";
  420. $sql.= ",label = '".$this->db->escape($this->label)."'";
  421. $sql.= ",courant = ".$this->courant;
  422. $sql.= ",clos = ".$this->clos;
  423. $sql.= ",rappro = ".$this->rappro;
  424. $sql.= ",url = ".($this->url?"'".$this->url."'":"null");
  425. $sql.= ",account_number = '".$this->account_number."'";
  426. $sql.= ",currency_code = '".$this->currency_code."'";
  427. $sql.= ",min_allowed = '".price2num($this->min_allowed)."'";
  428. $sql.= ",min_desired = '".price2num($this->min_desired)."'";
  429. $sql.= ",comment = '".$this->db->escape($this->comment)."'";
  430. $sql.= ",fk_departement = ".($this->fk_departement>0?"'".$this->fk_departement."'":"null");
  431. $sql.= ",fk_pays = ".$this->fk_pays;
  432. $sql.= " WHERE rowid = ".$this->id;
  433. $sql.= " AND entity = ".$conf->entity;
  434. dol_syslog("Account::update sql=".$sql);
  435. $result = $this->db->query($sql);
  436. if ($result)
  437. {
  438. return 1;
  439. }
  440. else
  441. {
  442. $this->error=$this->db->lasterror();
  443. dol_print_error($this->db);
  444. return -1;
  445. }
  446. }
  447. /**
  448. * Update BBAN (RIB) account fields
  449. * @param user Object user making update
  450. * @return int <0 if KO, >0 if OK
  451. */
  452. function update_bban($user='')
  453. {
  454. global $conf,$langs;
  455. // Chargement librairie pour acces fonction controle RIB
  456. require_once(DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php');
  457. dol_syslog("Account::update_bban $this->code_banque,$this->code_guichet,$this->number,$this->cle_rib,$this->iban");
  458. // Check parameters
  459. if (! $this->ref)
  460. {
  461. $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("Ref"));
  462. return -2;
  463. }
  464. $sql = "UPDATE ".MAIN_DB_PREFIX."bank_account SET ";
  465. $sql.= " bank = '".$this->db->escape($this->bank)."'";
  466. $sql.= ",code_banque='".$this->code_banque."'";
  467. $sql.= ",code_guichet='".$this->code_guichet."'";
  468. $sql.= ",number='".$this->number."'";
  469. $sql.= ",cle_rib='".$this->cle_rib."'";
  470. $sql.= ",bic='".$this->bic."'";
  471. $sql.= ",iban_prefix = '".$this->iban."'";
  472. $sql.= ",domiciliation='".$this->db->escape($this->domiciliation)."'";
  473. $sql.= ",proprio = '".$this->db->escape($this->proprio)."'";
  474. $sql.= ",adresse_proprio = '".$this->db->escape($this->adresse_proprio)."'";
  475. $sql.= ",fk_departement = ".($this->fk_departement>0?"'".$this->fk_departement."'":"null");
  476. $sql.= ",fk_pays = ".$this->fk_pays;
  477. $sql.= " WHERE rowid = ".$this->id;
  478. $sql.= " AND entity = ".$conf->entity;
  479. dol_syslog("Account::update_bban sql=$sql");
  480. $result = $this->db->query($sql);
  481. if ($result)
  482. {
  483. return 1;
  484. }
  485. else
  486. {
  487. $this->error=$this->db->lasterror();
  488. dol_print_error($this->db);
  489. return -1;
  490. }
  491. }
  492. /**
  493. * Load a bank account into memory from database
  494. * @param id Id of bank account to get
  495. * @param ref Ref of bank account to get
  496. * @param ref_ext External ref of bank account to get
  497. */
  498. function fetch($id,$ref='',$ref_ext='')
  499. {
  500. global $conf;
  501. if (empty($id) && empty($ref) && empty($ref_ext))
  502. {
  503. $this->error="ErrorBadParameters";
  504. return -1;
  505. }
  506. $sql = "SELECT ba.rowid, ba.ref, ba.label, ba.bank, ba.number, ba.courant, ba.clos, ba.rappro, ba.url,";
  507. $sql.= " ba.code_banque, ba.code_guichet, ba.cle_rib, ba.bic, ba.iban_prefix as iban,";
  508. $sql.= " ba.domiciliation, ba.proprio, ba.adresse_proprio, ba.fk_departement, ba.fk_pays,";
  509. $sql.= " ba.account_number, ba.currency_code,";
  510. $sql.= " ba.min_allowed, ba.min_desired, ba.comment,";
  511. $sql.= ' p.code as pays_code, p.libelle as pays,';
  512. $sql.= ' d.code_departement as departement_code, d.nom as departement';
  513. $sql.= " FROM ".MAIN_DB_PREFIX."bank_account as ba";
  514. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_pays as p ON ba.fk_pays = p.rowid';
  515. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON ba.fk_departement = d.rowid';
  516. $sql.= " WHERE entity = ".$conf->entity;
  517. if ($id) $sql.= " AND ba.rowid = ".$id;
  518. if ($ref) $sql.= " AND ba.ref = '".$this->db->escape($ref)."'";
  519. dol_syslog("Account::fetch sql=".$sql);
  520. $result = $this->db->query($sql);
  521. if ($result)
  522. {
  523. if ($this->db->num_rows($result))
  524. {
  525. $obj = $this->db->fetch_object($result);
  526. $this->id = $obj->rowid; // deprecated
  527. $this->rowid = $obj->rowid;
  528. $this->ref = $obj->ref;
  529. $this->label = $obj->label;
  530. $this->type = $obj->courant;
  531. $this->courant = $obj->courant;
  532. $this->bank = $obj->bank;
  533. $this->clos = $obj->clos;
  534. $this->rappro = $obj->rappro;
  535. $this->url = $obj->url;
  536. $this->code_banque = $obj->code_banque;
  537. $this->code_guichet = $obj->code_guichet;
  538. $this->number = $obj->number;
  539. $this->cle_rib = $obj->cle_rib;
  540. $this->bic = $obj->bic;
  541. $this->iban = $obj->iban;
  542. $this->iban_prefix = $obj->iban; // deprecated
  543. $this->domiciliation = $obj->domiciliation;
  544. $this->proprio = $obj->proprio;
  545. $this->adresse_proprio = $obj->adresse_proprio;
  546. $this->fk_departement = $obj->fk_departement;
  547. $this->departement_code= $obj->departement_code;
  548. $this->departement = $obj->departement;
  549. $this->fk_pays = $obj->fk_pays;
  550. $this->pays_code = $obj->pays_code;
  551. $this->pays = $obj->pays;
  552. $this->account_number = $obj->account_number;
  553. $this->currency_code = $obj->currency_code;
  554. $this->account_currency_code = $obj->currency_code;
  555. $this->min_allowed = $obj->min_allowed;
  556. $this->min_desired = $obj->min_desired;
  557. $this->comment = $obj->comment;
  558. return 1;
  559. }
  560. else
  561. {
  562. return 0;
  563. }
  564. $this->db->free($result);
  565. }
  566. else
  567. {
  568. dol_print_error($this->db);
  569. return -1;
  570. }
  571. }
  572. /**
  573. * Delete bank account from database
  574. * @return int <0 if KO, >0 if OK
  575. */
  576. function delete()
  577. {
  578. global $conf;
  579. $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_account";
  580. $sql.= " WHERE rowid = ".$this->rowid;
  581. $sql.= " AND entity = ".$conf->entity;
  582. dol_syslog("Account::delete sql=".$sql);
  583. $result = $this->db->query($sql);
  584. if ($result) {
  585. return 1;
  586. }
  587. else {
  588. dol_print_error($this->db);
  589. return -1;
  590. }
  591. }
  592. /**
  593. * Retourne le libelle du statut d'une facture (brouillon, validee, abandonnee, payee)
  594. * @param mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long
  595. * @return string Libelle
  596. */
  597. function getLibStatut($mode=0)
  598. {
  599. return $this->LibStatut($this->clos,$mode);
  600. }
  601. /**
  602. * Renvoi le libelle d'un statut donne
  603. * @param statut Id statut
  604. * @param mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  605. * @return string Libelle du statut
  606. */
  607. function LibStatut($statut,$mode=0)
  608. {
  609. global $langs;
  610. $langs->load('banks');
  611. if ($mode == 0)
  612. {
  613. if ($statut==0) return $langs->trans("StatusAccountOpened");
  614. if ($statut==1) return $langs->trans("StatusAccountClosed");
  615. }
  616. if ($mode == 1)
  617. {
  618. if ($statut==0) return $langs->trans("StatusAccountOpened");
  619. if ($statut==1) return $langs->trans("StatusAccountClosed");
  620. }
  621. if ($mode == 2)
  622. {
  623. if ($statut==0) return img_picto($langs->trans("StatusAccountOpened"),'statut4').' '.$langs->trans("StatusAccountOpened");
  624. if ($statut==1) return img_picto($langs->trans("StatusAccountClosed"),'statut5').' '.$langs->trans("StatusAccountClosed");
  625. }
  626. if ($mode == 3)
  627. {
  628. if ($statut==0) return img_picto($langs->trans("StatusAccountOpened"),'statut4');
  629. if ($statut==1) return img_picto($langs->trans("StatusAccountClosed"),'statut5');
  630. }
  631. if ($mode == 4)
  632. {
  633. if ($statut==0) return img_picto($langs->trans("StatusAccountOpened"),'statut4').' '.$langs->trans("StatusAccountOpened");
  634. if ($statut==1) return img_picto($langs->trans("StatusAccountClosed"),'statut5').' '.$langs->trans("StatusAccountClosed");
  635. }
  636. if ($mode == 5)
  637. {
  638. if ($statut==0) return $langs->trans("StatusAccountOpened").' '.img_picto($langs->trans("StatusAccountOpened"),'statut4');
  639. if ($statut==1) return $langs->trans("StatusAccountClosed").' '.img_picto($langs->trans("StatusAccountClosed"),'statut5');
  640. }
  641. }
  642. /**
  643. * Renvoi si un compte peut etre supprimer ou non (sans mouvements)
  644. * @return boolean vrai si peut etre supprime, faux sinon
  645. */
  646. function can_be_deleted()
  647. {
  648. $can_be_deleted=false;
  649. $sql = "SELECT COUNT(rowid) as nb";
  650. $sql.= " FROM ".MAIN_DB_PREFIX."bank";
  651. $sql.= " WHERE fk_account=".$this->id;
  652. $resql = $this->db->query($sql);
  653. if ($resql) {
  654. $obj=$this->db->fetch_object($resql);
  655. if ($obj->nb <= 1) $can_be_deleted=true; // Juste le solde
  656. }
  657. else {
  658. dol_print_error($this->db);
  659. }
  660. return $can_be_deleted;
  661. }
  662. /**
  663. * Return error
  664. */
  665. function error()
  666. {
  667. return $this->error;
  668. }
  669. /**
  670. * Return current sold
  671. * @param option 1=Exclude future operation date (this is to exclude input made in advance and have real account sold)
  672. * @return int Current sold (value date <= today)
  673. */
  674. function solde($option=0)
  675. {
  676. $sql = "SELECT sum(amount) as amount";
  677. $sql.= " FROM ".MAIN_DB_PREFIX."bank";
  678. $sql.= " WHERE fk_account = ".$this->id;
  679. if ($option == 1) $sql.= " AND dateo <= ".$this->db->idate(time());
  680. $resql = $this->db->query($sql);
  681. if ($resql)
  682. {
  683. if ($this->db->num_rows($resql))
  684. {
  685. $obj=$this->db->fetch_object($resql);
  686. $solde = $obj->amount;
  687. }
  688. $this->db->free($resql);
  689. return $solde;
  690. }
  691. }
  692. /**
  693. * @param rowid
  694. * @param sign 1 or -1
  695. */
  696. function datev_change($rowid,$sign=1)
  697. {
  698. $sql = "SELECT datev FROM ".MAIN_DB_PREFIX."bank WHERE rowid = ".$rowid;
  699. $resql = $this->db->query($sql);
  700. if ($resql)
  701. {
  702. $obj=$this->db->fetch_object($resql);
  703. $newdate=$this->db->jdate($obj->datev)+(3600*24*$sign);
  704. $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET ";
  705. $sql.= " datev = '".$this->db->idate($newdate)."'";
  706. $sql.= " WHERE rowid = ".$rowid;
  707. $result = $this->db->query($sql);
  708. if ($result)
  709. {
  710. if ($this->db->affected_rows($result))
  711. {
  712. return 1;
  713. }
  714. }
  715. else
  716. {
  717. dol_print_error($this->db);
  718. return 0;
  719. }
  720. }
  721. else dol_print_error($this->db);
  722. return 0;
  723. }
  724. /**
  725. * @param rowid
  726. */
  727. function datev_next($rowid)
  728. {
  729. return $this->datev_change($rowid,1);
  730. }
  731. /**
  732. * @param rowid
  733. */
  734. function datev_previous($rowid)
  735. {
  736. return $this->datev_change($rowid,-1);
  737. }
  738. /**
  739. * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
  740. * @param user Objet user
  741. * @param filteraccountid To get info for a particular account id
  742. * @return int <0 if KO, 0=Nothing to show, >0 if OK
  743. */
  744. function load_board($user,$filteraccountid=0)
  745. {
  746. global $conf;
  747. if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe
  748. $now=dol_now();
  749. $this->nbtodo=$this->nbtodolate=0;
  750. $sql = "SELECT b.rowid, b.datev as datefin";
  751. $sql.= " FROM ".MAIN_DB_PREFIX."bank as b,";
  752. $sql.= " ".MAIN_DB_PREFIX."bank_account as ba";
  753. $sql.= " WHERE b.rappro=0";
  754. $sql.= " AND b.fk_account = ba.rowid";
  755. $sql.= " AND ba.entity = ".$conf->entity;
  756. $sql.= " AND (ba.rappro = 1 AND ba.courant != 2)"; // Compte rapprochable
  757. if ($filteraccountid) $sql.=" AND ba.rowid = ".$filteraccountid;
  758. //print $sql;
  759. $resql=$this->db->query($sql);
  760. if ($resql)
  761. {
  762. $num=$this->db->num_rows($resql);
  763. while ($obj=$this->db->fetch_object($resql))
  764. {
  765. $this->nbtodo++;
  766. if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->rappro->warning_delay)) $this->nbtodolate++;
  767. if ($obj->rappro) $foundaccounttoconciliate++;
  768. }
  769. return $num;
  770. }
  771. else
  772. {
  773. dol_print_error($this->db);
  774. $this->error=$this->db->error();
  775. return -1;
  776. }
  777. }
  778. /**
  779. * Renvoie nom clicable (avec eventuellement le picto)
  780. * @param withpicto Inclut le picto dans le lien
  781. * @param mode ''=Link to card, 'transactions'=Link to transactions card
  782. * @return string Chaine avec URL
  783. */
  784. function getNomUrl($withpicto=0, $mode='')
  785. {
  786. global $langs;
  787. $result='';
  788. if (empty($mode))
  789. {
  790. $lien = '<a href="'.DOL_URL_ROOT.'/compta/bank/fiche.php?id='.$this->id.'">';
  791. $lienfin='</a>';
  792. }
  793. else if ($mode == 'transactions')
  794. {
  795. $lien = '<a href="'.DOL_URL_ROOT.'/compta/bank/account.php?account='.$this->id.'">';
  796. $lienfin='</a>';
  797. }
  798. if ($withpicto) $result.=($lien.img_object($langs->trans("ShowAccount"),'account').$lienfin.' ');
  799. $result.=$lien.$this->label.$lienfin;
  800. return $result;
  801. }
  802. // Method after here are common to Account and CompanyBankAccount
  803. /**
  804. * Return if an account has valid information
  805. * @return int 1 if correct, <=0 if wrong
  806. */
  807. function verif()
  808. {
  809. require_once DOL_DOCUMENT_ROOT . '/core/lib/bank.lib.php';
  810. // Call function to check BAN
  811. if (! checkBanForAccount($this))
  812. {
  813. $this->error_number = 12;
  814. $this->error_message = 'RIBControlError';
  815. }
  816. if ($this->error_number == 0)
  817. {
  818. return 1;
  819. }
  820. else
  821. {
  822. return 0;
  823. }
  824. }
  825. /**
  826. * Return account country code
  827. * @return String country code
  828. */
  829. function getCountryCode()
  830. {
  831. global $mysoc;
  832. // We return country code of bank account
  833. if (! empty($this->pays_code)) return $this->pays_code;
  834. // For backward compatibility, we try to guess country from other information
  835. if (! empty($this->iban))
  836. {
  837. if ($mysoc->pays_code === 'IN') return $mysoc->pays_code; // Test to know if we can trust IBAN
  838. // If IBAN defined, we can know country of account from it
  839. if (preg_match("/^([a-zA-Z][a-zA-Z])/i",$this->iban,$reg)) return $reg[1];
  840. }
  841. // If this class is linked to a third party
  842. if (! empty($this->socid))
  843. {
  844. require_once(DOL_DOCUMENT_ROOT ."/societe/class/societe.class.php");
  845. $company=new Societe($this->db);
  846. $result=$company->fetch($this->socid);
  847. if (! empty($company->pays_code)) return $company->pays_code;
  848. }
  849. // We return country code of managed company
  850. if (! empty($mysoc->pays_code)) return $mysoc->pays_code;
  851. return '';
  852. }
  853. /**
  854. * Return if a bank account is defined with detailed information (bank code, desk code, number and key)
  855. * @return int 0=Use only an account number
  856. * 1=Need Bank, Desk, Number and Key (France, Spain, ...)
  857. * 2=Neek Bank only (BSB for Australia)
  858. */
  859. function useDetailedBBAN()
  860. {
  861. $country_code=$this->getCountryCode();
  862. if (in_array($country_code,array('FR','ES','GA'))) return 1; // France, Spain, Gabon
  863. if (in_array($country_code,array('AU'))) return 2; // Australia
  864. return 0;
  865. }
  866. /**
  867. * Initialise an instance with random values.
  868. * Used to build previews or test instances.
  869. * id must be 0 if object instance is a specimen.
  870. *
  871. * @return void
  872. */
  873. function initAsSpecimen()
  874. {
  875. $this->bank = 'MyBank';
  876. $this->courant = 1;
  877. $this->clos = 0;
  878. $this->code_banque = '123';
  879. $this->code_guichet = '456';
  880. $this->number = 'ABC12345';
  881. $this->cle_rib = 50;
  882. $this->bic = 'AA12';
  883. $this->iban = 'FR999999999';
  884. $this->iban_prefix = 'FR'; // deprecated
  885. $this->domiciliation = 'The bank addresse';
  886. $this->proprio = 'Owner';
  887. $this->adresse_proprio = 'Owner address';
  888. }
  889. }
  890. /**
  891. * \class AccountLine
  892. * \brief Class to manage bank transaction lines
  893. */
  894. class AccountLine extends CommonObject
  895. {
  896. var $error;
  897. var $db;
  898. var $element='bank';
  899. var $table_element='bank';
  900. var $id;
  901. var $ref;
  902. var $datec;
  903. var $dateo;
  904. var $datev;
  905. var $amount;
  906. var $label;
  907. var $note;
  908. var $fk_user_author;
  909. var $fk_user_rappro;
  910. var $fk_type;
  911. var $rappro; // Is it conciliated
  912. var $num_releve; // If conciliated, what is bank receipt
  913. var $num_chq; // Num of cheque
  914. var $bank_chq; // Bank of cheque
  915. var $fk_bordereau; // Id of cheque receipt
  916. var $fk_account; // Id of bank account
  917. var $bank_account_label; // Label of bank account
  918. /**
  919. * Constructeur
  920. */
  921. function AccountLine($DB, $rowid=0)
  922. {
  923. global $langs;
  924. $this->db = $DB;
  925. $this->rowid = $rowid;
  926. return 1;
  927. }
  928. /**
  929. * Load into memory content of a bank transaction line
  930. * @param rowid Id of bank transaction to load
  931. * @param ref Ref of bank transaction to load
  932. * @param num External num to load (ex: num of transaction for paypal fee)
  933. * @return int <0 if KO, >0 if OK
  934. */
  935. function fetch($rowid,$ref='',$num='')
  936. {
  937. global $conf;
  938. // Check parameters
  939. if (empty($rowid) && empty($ref) && empty($num)) return -1;
  940. $sql = "SELECT b.rowid, b.datec, b.datev, b.dateo, b.amount, b.label as label, b.fk_account,";
  941. $sql.= " b.fk_user_author, b.fk_user_rappro,";
  942. $sql.= " b.fk_type, b.num_releve, b.num_chq, b.rappro, b.note,";
  943. $sql.= " b.fk_bordereau, b.banque, b.emetteur,";
  944. //$sql.= " b.author"; // Is this used ?
  945. $sql.= " ba.label as bank_account_label";
  946. $sql.= " FROM ".MAIN_DB_PREFIX."bank as b";
  947. $sql.= ", ".MAIN_DB_PREFIX."bank_account as ba";
  948. $sql.= " WHERE b.fk_account = ba.rowid";
  949. $sql.= " AND ba.entity = ".$conf->entity;
  950. if ($num) $sql.= " AND b.num_chq='".$num."'";
  951. else if ($ref) $sql.= " AND b.rowid='".$ref."'";
  952. else $sql.= " AND b.rowid=".$rowid;
  953. dol_syslog("AccountLine::fetch sql=".$sql);
  954. $result = $this->db->query($sql);
  955. if ($result)
  956. {
  957. $obj = $this->db->fetch_object($result);
  958. if ($obj)
  959. {
  960. $this->id = $obj->rowid;
  961. $this->rowid = $obj->rowid;
  962. $this->ref = $obj->rowid;
  963. $this->datec = $obj->datec;
  964. $this->datev = $obj->datev;
  965. $this->dateo = $obj->dateo;
  966. $this->amount = $obj->amount;
  967. $this->label = $obj->label;
  968. $this->note = $obj->note;
  969. $this->fk_user_author = $obj->fk_user_author;
  970. $this->fk_user_rappro = $obj->fk_user_rappro;
  971. $this->fk_type = $obj->fk_type; // Type of transaction
  972. $this->rappro = $obj->rappro;
  973. $this->num_releve = $obj->num_releve;
  974. $this->num_chq = $obj->num_chq;
  975. $this->bank_chq = $obj->bank_chq;
  976. $this->fk_bordereau = $obj->fk_bordereau;
  977. $this->fk_account = $obj->fk_account;
  978. $this->bank_account_label = $obj->bank_account_label;
  979. }
  980. $this->db->free($result);
  981. return 1;
  982. }
  983. else
  984. {
  985. dol_print_error($this->db);
  986. return -1;
  987. }
  988. }
  989. /**
  990. * Delete transaction bank line record
  991. * @param user User object that delete
  992. * @return int <0 if KO, >0 if OK
  993. */
  994. function delete($user=0)
  995. {
  996. $nbko=0;
  997. if ($this->rappro)
  998. {
  999. // Protection to avoid any delete of consolidated lines
  1000. $this->error="DeleteNotPossibleLineIsConsolidated";
  1001. return -1;
  1002. }
  1003. $this->db->begin();
  1004. // Delete urls
  1005. $result=$this->delete_urls();
  1006. if ($result < 0)
  1007. {
  1008. $nbko++;
  1009. }
  1010. $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_class WHERE lineid=".$this->rowid;
  1011. dol_syslog("AccountLine::delete sql=".$sql);
  1012. $result = $this->db->query($sql);
  1013. if (! $result) $nbko++;
  1014. $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank WHERE rowid=".$this->rowid;
  1015. dol_syslog("AccountLine::delete sql=".$sql);
  1016. $result = $this->db->query($sql);
  1017. if (! $result) $nbko++;
  1018. if (! $nbko)
  1019. {
  1020. $this->db->commit();
  1021. return 1;
  1022. }
  1023. else
  1024. {
  1025. $this->db->rollback();
  1026. return -$nbko;
  1027. }
  1028. }
  1029. /**
  1030. * Delete bank line records
  1031. * @param user User object that delete
  1032. * @return int <0 if KO, >0 if OK
  1033. */
  1034. function delete_urls($user=0)
  1035. {
  1036. $nbko=0;
  1037. if ($this->rappro)
  1038. {
  1039. // Protection to avoid any delete of consolidated lines
  1040. $this->error="ErrorDeleteNotPossibleLineIsConsolidated";
  1041. return -1;
  1042. }
  1043. $this->db->begin();
  1044. $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url WHERE fk_bank=".$this->rowid;
  1045. dol_syslog("AccountLine::delete_urls sql=".$sql);
  1046. $result = $this->db->query($sql);
  1047. if (! $result) $nbko++;
  1048. if (! $nbko)
  1049. {
  1050. $this->db->commit();
  1051. return 1;
  1052. }
  1053. else
  1054. {
  1055. $this->db->rollback();
  1056. return -$nbko;
  1057. }
  1058. }
  1059. /**
  1060. * Update bank account record in database
  1061. * @param user Object user making update
  1062. * @param notrigger 0=Disable all triggers
  1063. * @return int <0 if KO, >0 if OK
  1064. */
  1065. function update($user,$notrigger=0)
  1066. {
  1067. $this->db->begin();
  1068. $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
  1069. $sql.= " amount = ".price2num($this->amount).",";
  1070. $sql.= " datev='".$this->db->idate($this->datev)."',";
  1071. $sql.= " dateo='".$this->db->idate($this->dateo)."'";
  1072. $sql.= " WHERE rowid = ".$this->rowid;
  1073. dol_syslog("AccountLine::update sql=".$sql);
  1074. $resql = $this->db->query($sql);
  1075. if ($resql)
  1076. {
  1077. $this->db->commit();
  1078. return 1;
  1079. }
  1080. else
  1081. {
  1082. $this->db->rollback();
  1083. $this->error=$this->db->error();
  1084. dol_syslog("AccountLine::update ".$this->error, LOG_ERR);
  1085. return -1;
  1086. }
  1087. }
  1088. /**
  1089. * Update conciliation field
  1090. * @param user Objet user making update
  1091. * @param cat Category id
  1092. * @return int <0 if KO, >0 if OK
  1093. */
  1094. function update_conciliation($user,$cat)
  1095. {
  1096. $this->db->begin();
  1097. $sql = "UPDATE ".MAIN_DB_PREFIX."bank SET";
  1098. $sql.= " rappro = 1";
  1099. $sql.= ", num_releve = '".$this->num_releve."'";
  1100. $sql.= ", fk_user_rappro = ".$user->id;
  1101. $sql.= " WHERE rowid = ".$this->id;
  1102. dol_syslog("AccountLine::update_conciliation sql=".$sql, LOG_DEBUG);
  1103. $resql = $this->db->query($sql);
  1104. if ($resql)
  1105. {
  1106. if (! empty($cat))
  1107. {
  1108. $sql = "INSERT INTO ".MAIN_DB_PREFIX."bank_class (";
  1109. $sql.= "lineid";
  1110. $sql.= ", fk_categ";
  1111. $sql.= ") VALUES (";
  1112. $sql.= $this->id;
  1113. $sql.= ", ".$cat;
  1114. $sql.= ")";
  1115. dol_syslog("AccountLine::update_conciliation sql=".$sql, LOG_DEBUG);
  1116. $resql = $this->db->query($sql);
  1117. // No error check. Can fail if category already affected
  1118. }
  1119. $bankline->rappro=1;
  1120. $this->db->commit();
  1121. return 1;
  1122. }
  1123. else
  1124. {
  1125. $this->db->rollback();
  1126. return -1;
  1127. }
  1128. }
  1129. /**
  1130. * Charge les informations d'ordre info dans l'objet
  1131. * @param rowid Id of object
  1132. */
  1133. function info($rowid)
  1134. {
  1135. $sql = 'SELECT b.rowid, b.datec,';
  1136. $sql.= ' b.fk_user_author, b.fk_user_rappro';
  1137. $sql.= ' FROM '.MAIN_DB_PREFIX.'bank as b';
  1138. $sql.= ' WHERE b.rowid = '.$rowid;
  1139. $result=$this->db->query($sql);
  1140. if ($result)
  1141. {
  1142. if ($this->db->num_rows($result))
  1143. {
  1144. $obj = $this->db->fetch_object($result);
  1145. $this->id = $obj->rowid;
  1146. if ($obj->fk_user_author)
  1147. {
  1148. $cuser = new User($this->db);
  1149. $cuser->fetch($obj->fk_user_author);
  1150. $this->user_creation = $cuser;
  1151. }
  1152. if ($obj->fk_user_rappro)
  1153. {
  1154. $ruser = new User($this->db);
  1155. $ruser->fetch($obj->fk_user_rappro);
  1156. $this->user_rappro = $ruser;
  1157. }
  1158. $this->date_creation = $this->db->jdate($obj->datec);
  1159. //$this->date_rappro = $obj->daterappro; // Not yet managed
  1160. }
  1161. $this->db->free($result);
  1162. }
  1163. else
  1164. {
  1165. dol_print_error($this->db);
  1166. }
  1167. }
  1168. /**
  1169. * Renvoie nom clicable (avec eventuellement le picto)
  1170. * @param withpicto 0=Pas de picto, 1=Inclut le picto dans le lien, 2=Picto seul
  1171. * @param maxlen Longueur max libelle
  1172. * @param option Option ('showall')
  1173. * @return string Chaine avec URL
  1174. */
  1175. function getNomUrl($withpicto=0,$maxlen=0,$option='')
  1176. {
  1177. global $langs;
  1178. $result='';
  1179. $lien = '<a href="'.DOL_URL_ROOT.'/compta/bank/ligne.php?rowid='.$this->rowid.'">';
  1180. $lienfin='</a>';
  1181. if ($withpicto) $result.=($lien.img_object($langs->trans("ShowTransaction"),'account').$lienfin.' ');
  1182. $result.=$lien.$this->rowid.$lienfin;
  1183. if ($option == 'showall')
  1184. {
  1185. $result.=' (';
  1186. $result.=$langs->trans("BankAccount").': ';
  1187. $accountstatic=new Account($this->db);
  1188. $accountstatic->id=$this->fk_account;
  1189. $accountstatic->label=$this->bank_account_label;
  1190. $result.=$accountstatic->getNomUrl(0).', ';
  1191. $result.=$langs->trans("BankLineConciliated").': ';
  1192. $result.=yn($this->rappro);
  1193. $result.=')';
  1194. }
  1195. return $result;
  1196. }
  1197. }
  1198. ?>