remisecheque.class.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023
  1. <?php
  2. /* Copyright (C) 2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2007-2011 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
  5. * Copyright (C) 2011-2016 Juanjo Menent <jmenent@2byte.es>
  6. * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * \file htdocs/compta/paiement/cheque/class/remisecheque.class.php
  23. * \ingroup compta
  24. * \brief File with class to manage cheque delivery receipts
  25. */
  26. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  27. require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  28. /**
  29. * Class to manage cheque delivery receipts
  30. */
  31. class RemiseCheque extends CommonObject
  32. {
  33. /**
  34. * @var string ID to identify managed object
  35. */
  36. public $element = 'chequereceipt';
  37. /**
  38. * @var string Name of table without prefix where object is stored
  39. */
  40. public $table_element = 'bordereau_cheque';
  41. /**
  42. * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
  43. */
  44. public $picto = 'payment';
  45. public $num;
  46. public $intitule;
  47. //! Numero d'erreur Plage 1024-1279
  48. public $errno;
  49. public $amount;
  50. public $date_bordereau;
  51. public $account_id;
  52. public $account_label;
  53. public $author_id;
  54. public $nbcheque;
  55. /**
  56. * @var string Ref
  57. */
  58. public $ref;
  59. const STATUS_DRAFT = 0;
  60. const STATUS_VALIDATED = 1;
  61. /**
  62. * Constructor
  63. *
  64. * @param DoliDB $db Database handler
  65. */
  66. public function __construct($db)
  67. {
  68. $this->db = $db;
  69. $this->next_id = 0;
  70. $this->previous_id = 0;
  71. }
  72. /**
  73. * Load record
  74. *
  75. * @param int $id Id record
  76. * @param string $ref Ref record
  77. * @return int <0 if KO, > 0 if OK
  78. */
  79. public function fetch($id, $ref = '')
  80. {
  81. global $conf;
  82. $sql = "SELECT bc.rowid, bc.datec, bc.fk_user_author, bc.fk_bank_account, bc.amount, bc.ref, bc.statut, bc.nbcheque, bc.ref_ext";
  83. $sql .= ", bc.date_bordereau as date_bordereau";
  84. $sql .= ", ba.label as account_label";
  85. $sql .= " FROM ".MAIN_DB_PREFIX."bordereau_cheque as bc";
  86. $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank_account as ba ON bc.fk_bank_account = ba.rowid";
  87. $sql .= " WHERE bc.entity = ".$conf->entity;
  88. if ($id) {
  89. $sql .= " AND bc.rowid = ".((int) $id);
  90. }
  91. if ($ref) {
  92. $sql .= " AND bc.ref = '".$this->db->escape($ref)."'";
  93. }
  94. dol_syslog("RemiseCheque::fetch", LOG_DEBUG);
  95. $resql = $this->db->query($sql);
  96. if ($resql) {
  97. if ($obj = $this->db->fetch_object($resql)) {
  98. $this->id = $obj->rowid;
  99. $this->amount = $obj->amount;
  100. $this->date_bordereau = $this->db->jdate($obj->date_bordereau);
  101. $this->account_id = $obj->fk_bank_account;
  102. $this->account_label = $obj->account_label;
  103. $this->author_id = $obj->fk_user_author;
  104. $this->nbcheque = $obj->nbcheque;
  105. $this->statut = $obj->statut;
  106. $this->ref_ext = $obj->ref_ext;
  107. if ($this->statut == 0) {
  108. $this->ref = "(PROV".$this->id.")";
  109. } else {
  110. $this->ref = $obj->ref;
  111. }
  112. }
  113. $this->db->free($resql);
  114. return 1;
  115. } else {
  116. $this->error = $this->db->lasterror();
  117. return -1;
  118. }
  119. }
  120. /**
  121. * Create a receipt to send cheques
  122. *
  123. * @param User $user User making creation
  124. * @param int $account_id Bank account for cheque receipt
  125. * @param int $limit Limit ref of cheque to this
  126. * @param array $toRemise array with cheques to remise
  127. * @return int <0 if KO, >0 if OK
  128. */
  129. public function create($user, $account_id, $limit, $toRemise)
  130. {
  131. global $conf;
  132. $this->errno = 0;
  133. $this->id = 0;
  134. $now = dol_now();
  135. dol_syslog("RemiseCheque::Create start", LOG_DEBUG);
  136. $this->db->begin();
  137. $sql = "INSERT INTO ".MAIN_DB_PREFIX."bordereau_cheque (";
  138. $sql .= "datec";
  139. $sql .= ", date_bordereau";
  140. $sql .= ", fk_user_author";
  141. $sql .= ", fk_bank_account";
  142. $sql .= ", statut";
  143. $sql .= ", amount";
  144. $sql .= ", ref";
  145. $sql .= ", entity";
  146. $sql .= ", nbcheque";
  147. $sql .= ", ref_ext";
  148. $sql .= ") VALUES (";
  149. $sql .= "'".$this->db->idate($now)."'";
  150. $sql .= ", '".$this->db->idate($now)."'";
  151. $sql .= ", ".((int) $user->id);
  152. $sql .= ", ".((int) $account_id);
  153. $sql .= ", 0";
  154. $sql .= ", 0";
  155. $sql .= ", 0";
  156. $sql .= ", ".((int) $conf->entity);
  157. $sql .= ", 0";
  158. $sql .= ", ''";
  159. $sql .= ")";
  160. $resql = $this->db->query($sql);
  161. if ($resql) {
  162. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."bordereau_cheque");
  163. if ($this->id == 0) {
  164. $this->errno = -1024;
  165. dol_syslog("Remisecheque::Create Error read id ".$this->errno, LOG_ERR);
  166. }
  167. if ($this->id > 0 && $this->errno == 0) {
  168. $sql = "UPDATE ".MAIN_DB_PREFIX."bordereau_cheque";
  169. $sql .= " SET ref='(PROV".$this->id.")'";
  170. $sql .= " WHERE rowid=".((int) $this->id)."";
  171. $resql = $this->db->query($sql);
  172. if (!$resql) {
  173. $this->errno = -1025;
  174. dol_syslog("RemiseCheque::Create Error update ".$this->errno, LOG_ERR);
  175. }
  176. }
  177. $lines = array();
  178. if ($this->id > 0 && $this->errno == 0) {
  179. $sql = "SELECT b.rowid";
  180. $sql .= " FROM ".MAIN_DB_PREFIX."bank as b";
  181. $sql .= " WHERE b.fk_type = 'CHQ'";
  182. $sql .= " AND b.amount > 0";
  183. $sql .= " AND b.fk_bordereau = 0";
  184. $sql .= " AND b.fk_account = ".((int) $account_id);
  185. if ($limit) {
  186. $sql .= $this->db->plimit($limit);
  187. }
  188. dol_syslog("RemiseCheque::Create", LOG_DEBUG);
  189. $resql = $this->db->query($sql);
  190. if ($resql) {
  191. while ($row = $this->db->fetch_row($resql)) {
  192. array_push($lines, $row[0]);
  193. }
  194. $this->db->free($resql);
  195. } else {
  196. $this->errno = -1026;
  197. dol_syslog("RemiseCheque::Create Error ".$this->errno, LOG_ERR);
  198. }
  199. }
  200. if ($this->id > 0 && $this->errno == 0) {
  201. foreach ($lines as $lineid) {
  202. $checkremise = false;
  203. foreach ($toRemise as $linetoremise) {
  204. if ($linetoremise == $lineid) {
  205. $checkremise = true;
  206. }
  207. }
  208. if ($checkremise) {
  209. $sql = "UPDATE ".MAIN_DB_PREFIX."bank";
  210. $sql .= " SET fk_bordereau = ".((int) $this->id);
  211. $sql .= " WHERE rowid = ".((int) $lineid);
  212. $resql = $this->db->query($sql);
  213. if (!$resql) {
  214. $this->errno = -18;
  215. dol_syslog("RemiseCheque::Create Error update bank ".$this->errno, LOG_ERR);
  216. }
  217. }
  218. }
  219. }
  220. if ($this->id > 0 && $this->errno == 0) {
  221. if ($this->updateAmount() <> 0) {
  222. $this->errno = -1027;
  223. dol_syslog("RemiseCheque::Create Error update amount ".$this->errno, LOG_ERR);
  224. }
  225. }
  226. } else {
  227. $this->errno = -1;
  228. $this->error = $this->db->lasterror();
  229. $this->errno = $this->db->lasterrno();
  230. }
  231. if (!$this->errno && (getDolGlobalString('MAIN_DISABLEDRAFTSTATUS') || getDolGlobalString('MAIN_DISABLEDRAFTSTATUS_CHEQUE'))) {
  232. $res = $this->validate($user);
  233. //if ($res < 0) $error++;
  234. }
  235. if (!$this->errno) {
  236. $this->db->commit();
  237. dol_syslog("RemiseCheque::Create end", LOG_DEBUG);
  238. return $this->id;
  239. } else {
  240. $this->db->rollback();
  241. dol_syslog("RemiseCheque::Create end", LOG_DEBUG);
  242. return $this->errno;
  243. }
  244. }
  245. /**
  246. * Supprime la remise en base
  247. *
  248. * @param User $user Utilisateur qui effectue l'operation
  249. * @return int
  250. */
  251. public function delete($user = '')
  252. {
  253. global $conf;
  254. $this->errno = 0;
  255. $this->db->begin();
  256. $sql = "DELETE FROM ".MAIN_DB_PREFIX."bordereau_cheque";
  257. $sql .= " WHERE rowid = ".((int) $this->id);
  258. $sql .= " AND entity = ".$conf->entity;
  259. $resql = $this->db->query($sql);
  260. if ($resql) {
  261. $num = $this->db->affected_rows($resql);
  262. if ($num <> 1) {
  263. $this->errno = -2;
  264. dol_syslog("Remisecheque::Delete Erreur Lecture ID ($this->errno)");
  265. }
  266. if ($this->errno === 0) {
  267. $sql = "UPDATE ".MAIN_DB_PREFIX."bank";
  268. $sql .= " SET fk_bordereau = 0";
  269. $sql .= " WHERE fk_bordereau = ".((int) $this->id);
  270. $resql = $this->db->query($sql);
  271. if (!$resql) {
  272. $this->errno = -1028;
  273. dol_syslog("RemiseCheque::Delete ERREUR UPDATE ($this->errno)");
  274. }
  275. }
  276. }
  277. if ($this->errno === 0) {
  278. $this->db->commit();
  279. } else {
  280. $this->db->rollback();
  281. dol_syslog("RemiseCheque::Delete ROLLBACK ($this->errno)");
  282. }
  283. return $this->errno;
  284. }
  285. /**
  286. * Validate a receipt
  287. *
  288. * @param User $user User
  289. * @return int <0 if KO, >0 if OK
  290. */
  291. public function validate($user)
  292. {
  293. global $langs, $conf;
  294. $this->errno = 0;
  295. $this->db->begin();
  296. $numref = $this->getNextNumRef();
  297. if ($this->errno == 0 && $numref) {
  298. $sql = "UPDATE ".MAIN_DB_PREFIX."bordereau_cheque";
  299. $sql .= " SET statut = 1, ref = '".$this->db->escape($numref)."'";
  300. $sql .= " WHERE rowid = ".((int) $this->id);
  301. $sql .= " AND entity = ".$conf->entity;
  302. $sql .= " AND statut = 0";
  303. dol_syslog("RemiseCheque::Validate", LOG_DEBUG);
  304. $resql = $this->db->query($sql);
  305. if ($resql) {
  306. $num = $this->db->affected_rows($resql);
  307. if ($num == 1) {
  308. $this->ref = $numref;
  309. $this->statut = 1;
  310. } else {
  311. $this->errno = -1029;
  312. dol_syslog("Remisecheque::Validate Error ".$this->errno, LOG_ERR);
  313. }
  314. } else {
  315. $this->errno = -1033;
  316. dol_syslog("Remisecheque::Validate Error ".$this->errno, LOG_ERR);
  317. }
  318. }
  319. // Commit/Rollback
  320. if ($this->errno == 0) {
  321. $this->db->commit();
  322. return 1;
  323. } else {
  324. $this->db->rollback();
  325. dol_syslog("RemiseCheque::Validate ".$this->errno, LOG_ERR);
  326. return $this->errno;
  327. }
  328. }
  329. /**
  330. * Return next reference of cheque receipts not already used (or last reference)
  331. * according to numbering module defined into constant FACTURE_ADDON
  332. *
  333. * @param string $mode 'next' for next value or 'last' for last value
  334. * @return string free ref or last ref
  335. */
  336. public function getNextNumRef($mode = 'next')
  337. {
  338. global $conf, $db, $langs, $mysoc;
  339. $langs->load("bills");
  340. // Clean parameters (if not defined or using deprecated value)
  341. if (empty($conf->global->CHEQUERECEIPTS_ADDON)) {
  342. $conf->global->CHEQUERECEIPTS_ADDON = 'mod_chequereceipt_mint';
  343. } elseif ($conf->global->CHEQUERECEIPTS_ADDON == 'thyme') {
  344. $conf->global->CHEQUERECEIPTS_ADDON = 'mod_chequereceipt_thyme';
  345. } elseif ($conf->global->CHEQUERECEIPTS_ADDON == 'mint') {
  346. $conf->global->CHEQUERECEIPTS_ADDON = 'mod_chequereceipt_mint';
  347. }
  348. if (!empty($conf->global->CHEQUERECEIPTS_ADDON)) {
  349. $mybool = false;
  350. $file = $conf->global->CHEQUERECEIPTS_ADDON.".php";
  351. $classname = $conf->global->CHEQUERECEIPTS_ADDON;
  352. // Include file with class
  353. $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
  354. foreach ($dirmodels as $reldir) {
  355. $dir = dol_buildpath($reldir."core/modules/cheque/");
  356. // Load file with numbering class (if found)
  357. if (is_file($dir.$file) && is_readable($dir.$file)) {
  358. $mybool |= include_once $dir.$file;
  359. }
  360. }
  361. // For compatibility
  362. if (!$mybool) {
  363. $file = $conf->global->CHEQUERECEIPTS_ADDON.".php";
  364. $classname = "mod_chequereceipt_".$conf->global->CHEQUERECEIPTS_ADDON;
  365. $classname = preg_replace('/\-.*$/', '', $classname);
  366. // Include file with class
  367. foreach ($conf->file->dol_document_root as $dirroot) {
  368. $dir = $dirroot."/core/modules/cheque/";
  369. // Load file with numbering class (if found)
  370. if (is_file($dir.$file) && is_readable($dir.$file)) {
  371. $mybool |= include_once $dir.$file;
  372. }
  373. }
  374. }
  375. if (!$mybool) {
  376. dol_print_error('', "Failed to include file ".$file);
  377. return '';
  378. }
  379. $obj = new $classname();
  380. $numref = "";
  381. $numref = $obj->getNextValue($mysoc, $this);
  382. /**
  383. * $numref can be empty in case we ask for the last value because if there is no invoice created with the
  384. * set up mask.
  385. */
  386. if ($mode != 'last' && !$numref) {
  387. dol_print_error($db, "ChequeReceipts::getNextNumRef ".$obj->error);
  388. return "";
  389. }
  390. return $numref;
  391. } else {
  392. $langs->load("errors");
  393. print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Bank"));
  394. return "";
  395. }
  396. }
  397. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  398. /**
  399. * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
  400. *
  401. * @param User $user Objet user
  402. * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
  403. */
  404. public function load_board($user)
  405. {
  406. // phpcs:enable
  407. global $conf, $langs;
  408. if ($user->socid) {
  409. return -1; // protection pour eviter appel par utilisateur externe
  410. }
  411. $sql = "SELECT b.rowid, b.datev as datefin";
  412. $sql .= " FROM ".MAIN_DB_PREFIX."bank as b";
  413. $sql .= ", ".MAIN_DB_PREFIX."bank_account as ba";
  414. $sql .= " WHERE b.fk_account = ba.rowid";
  415. $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
  416. $sql .= " AND b.fk_type = 'CHQ'";
  417. $sql .= " AND b.fk_bordereau = 0";
  418. $sql .= " AND b.amount > 0";
  419. $resql = $this->db->query($sql);
  420. if ($resql) {
  421. $langs->load("banks");
  422. $now = dol_now();
  423. $response = new WorkboardResponse();
  424. $response->warning_delay = $conf->bank->cheque->warning_delay / 60 / 60 / 24;
  425. $response->label = $langs->trans("BankChecksToReceipt");
  426. $response->labelShort = $langs->trans("BankChecksToReceiptShort");
  427. $response->url = DOL_URL_ROOT.'/compta/paiement/cheque/index.php?leftmenu=checks&amp;mainmenu=bank';
  428. $response->img = img_object('', "payment");
  429. while ($obj = $this->db->fetch_object($resql)) {
  430. $response->nbtodo++;
  431. if ($this->db->jdate($obj->datefin) < ($now - $conf->bank->cheque->warning_delay)) {
  432. $response->nbtodolate++;
  433. }
  434. }
  435. return $response;
  436. } else {
  437. dol_print_error($this->db);
  438. $this->error = $this->db->error();
  439. return -1;
  440. }
  441. }
  442. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  443. /**
  444. * Charge indicateurs this->nb de tableau de bord
  445. *
  446. * @return int <0 if ko, >0 if ok
  447. */
  448. public function load_state_board()
  449. {
  450. // phpcs:enable
  451. global $user;
  452. if ($user->socid) {
  453. return -1; // protection pour eviter appel par utilisateur externe
  454. }
  455. $sql = "SELECT count(b.rowid) as nb";
  456. $sql .= " FROM ".MAIN_DB_PREFIX."bank as b";
  457. $sql .= ", ".MAIN_DB_PREFIX."bank_account as ba";
  458. $sql .= " WHERE b.fk_account = ba.rowid";
  459. $sql .= " AND ba.entity IN (".getEntity('bank_account').")";
  460. $sql .= " AND b.fk_type = 'CHQ'";
  461. $sql .= " AND b.amount > 0";
  462. $resql = $this->db->query($sql);
  463. if ($resql) {
  464. while ($obj = $this->db->fetch_object($resql)) {
  465. $this->nb["cheques"] = $obj->nb;
  466. }
  467. $this->db->free($resql);
  468. return 1;
  469. } else {
  470. dol_print_error($this->db);
  471. $this->error = $this->db->error();
  472. return -1;
  473. }
  474. }
  475. /**
  476. * Build document
  477. *
  478. * @param string $model Model name
  479. * @param Translate $outputlangs Object langs
  480. * @return int <0 if KO, >0 if OK
  481. */
  482. public function generatePdf($model, $outputlangs)
  483. {
  484. global $langs, $conf;
  485. if (empty($model)) {
  486. $model = 'blochet';
  487. }
  488. dol_syslog("RemiseCheque::generatePdf model=".$model." id=".$this->id, LOG_DEBUG);
  489. $dir = DOL_DOCUMENT_ROOT."/core/modules/cheque/doc/";
  490. // Charge le modele
  491. $file = "pdf_".$model.".class.php";
  492. if (file_exists($dir.$file)) {
  493. include_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
  494. include_once $dir.$file;
  495. $classname = 'BordereauCheque'.ucfirst($model);
  496. $docmodel = new $classname($this->db);
  497. $sql = "SELECT b.banque, b.emetteur, b.amount, b.num_chq";
  498. $sql .= " FROM ".MAIN_DB_PREFIX."bank as b";
  499. $sql .= ", ".MAIN_DB_PREFIX."bank_account as ba";
  500. $sql .= ", ".MAIN_DB_PREFIX."bordereau_cheque as bc";
  501. $sql .= " WHERE b.fk_account = ba.rowid";
  502. $sql .= " AND b.fk_bordereau = bc.rowid";
  503. $sql .= " AND bc.rowid = ".((int) $this->id);
  504. $sql .= " AND bc.entity = ".$conf->entity;
  505. $sql .= " ORDER BY b.dateo ASC, b.rowid ASC";
  506. dol_syslog("RemiseCheque::generatePdf", LOG_DEBUG);
  507. $result = $this->db->query($sql);
  508. if ($result) {
  509. $i = 0;
  510. while ($objp = $this->db->fetch_object($result)) {
  511. $docmodel->lines[$i] = new stdClass();
  512. $docmodel->lines[$i]->bank_chq = $objp->banque;
  513. $docmodel->lines[$i]->emetteur_chq = $objp->emetteur;
  514. $docmodel->lines[$i]->amount_chq = $objp->amount;
  515. $docmodel->lines[$i]->num_chq = $objp->num_chq;
  516. $i++;
  517. }
  518. }
  519. $docmodel->nbcheque = $this->nbcheque;
  520. $docmodel->ref = $this->ref;
  521. $docmodel->amount = $this->amount;
  522. $docmodel->date = $this->date_bordereau;
  523. $account = new Account($this->db);
  524. $account->fetch($this->account_id);
  525. $docmodel->account = &$account;
  526. // We save charset_output to restore it because write_file can change it if needed for
  527. // output format that does not support UTF8.
  528. $sav_charseSupprimert_output = $outputlangs->charset_output;
  529. $result = $docmodel->write_file($this, $conf->bank->dir_output.'/checkdeposits', $this->ref, $outputlangs);
  530. if ($result > 0) {
  531. //$outputlangs->charset_output=$sav_charset_output;
  532. return 1;
  533. } else {
  534. //$outputlangs->charset_output=$sav_charset_output;
  535. dol_syslog("Error");
  536. dol_print_error($this->db, $docmodel->error);
  537. return 0;
  538. }
  539. } else {
  540. $this->error = $langs->trans("ErrorFileDoesNotExists", $dir.$file);
  541. return -1;
  542. }
  543. }
  544. /**
  545. * Mets a jour le montant total
  546. *
  547. * @return int 0 en cas de succes
  548. */
  549. public function updateAmount()
  550. {
  551. global $conf;
  552. $this->errno = 0;
  553. $this->db->begin();
  554. $total = 0;
  555. $nb = 0;
  556. $sql = "SELECT amount ";
  557. $sql .= " FROM ".MAIN_DB_PREFIX."bank";
  558. $sql .= " WHERE fk_bordereau = ".((int) $this->id);
  559. $resql = $this->db->query($sql);
  560. if ($resql) {
  561. while ($row = $this->db->fetch_row($resql)) {
  562. $total += $row[0];
  563. $nb++;
  564. }
  565. $this->db->free($resql);
  566. $sql = "UPDATE ".MAIN_DB_PREFIX."bordereau_cheque";
  567. $sql .= " SET amount = ".price2num($total);
  568. $sql .= ", nbcheque = ".((int) $nb);
  569. $sql .= " WHERE rowid = ".((int) $this->id);
  570. $sql .= " AND entity = ".$conf->entity;
  571. $resql = $this->db->query($sql);
  572. if (!$resql) {
  573. $this->errno = -1030;
  574. dol_syslog("RemiseCheque::updateAmount ERREUR UPDATE ($this->errno)");
  575. }
  576. } else {
  577. $this->errno = -1031;
  578. dol_syslog("RemiseCheque::updateAmount ERREUR SELECT ($this->errno)");
  579. }
  580. if ($this->errno === 0) {
  581. $this->db->commit();
  582. } else {
  583. $this->db->rollback();
  584. dol_syslog("RemiseCheque::updateAmount ROLLBACK ($this->errno)");
  585. }
  586. return $this->errno;
  587. }
  588. /**
  589. * Insere la remise en base
  590. *
  591. * @param int $account_id Compte bancaire concerne
  592. * @return int
  593. */
  594. public function removeCheck($account_id)
  595. {
  596. $this->errno = 0;
  597. if ($this->id > 0) {
  598. $sql = "UPDATE ".MAIN_DB_PREFIX."bank";
  599. $sql .= " SET fk_bordereau = 0";
  600. $sql .= " WHERE rowid = ".((int) $account_id);
  601. $sql .= " AND fk_bordereau = ".((int) $this->id);
  602. $resql = $this->db->query($sql);
  603. if ($resql) {
  604. $this->updateAmount();
  605. } else {
  606. $this->errno = -1032;
  607. dol_syslog("RemiseCheque::removeCheck ERREUR UPDATE ($this->errno)");
  608. }
  609. }
  610. return 0;
  611. }
  612. /**
  613. * Check return management
  614. * Reopen linked invoices and create a new negative payment.
  615. *
  616. * @param int $bank_id Id of bank transaction line concerned
  617. * @param integer $rejection_date Date to use on the negative payment
  618. * @return int Id of negative payment line created
  619. */
  620. public function rejectCheck($bank_id, $rejection_date)
  621. {
  622. global $db, $user;
  623. $payment = new Paiement($db);
  624. $payment->fetch(0, 0, $bank_id);
  625. $bankline = new AccountLine($db);
  626. $bankline->fetch($bank_id);
  627. /* Reconciliation is allowed because when check is returned, a new line is created onto bank transaction log.
  628. if ($bankline->rappro)
  629. {
  630. $this->error='ActionRefusedLineAlreadyConciliated';
  631. return -1;
  632. }*/
  633. $this->db->begin();
  634. // Not reconciled, we can delete it
  635. //$bankline->delete($user); // We delete
  636. $bankaccount = $payment->fk_account;
  637. // Get invoices list to reopen them
  638. $sql = 'SELECT pf.fk_facture, pf.amount';
  639. $sql .= ' FROM '.MAIN_DB_PREFIX.'paiement_facture as pf';
  640. $sql .= ' WHERE pf.fk_paiement = '.((int) $payment->id);
  641. $resql = $this->db->query($sql);
  642. if ($resql) {
  643. $rejectedPayment = new Paiement($this->db);
  644. $rejectedPayment->amounts = array();
  645. $rejectedPayment->datepaye = $rejection_date;
  646. $rejectedPayment->paiementid = dol_getIdFromCode($this->db, 'CHQ', 'c_paiement', 'code', 'id', 1);
  647. $rejectedPayment->num_payment = $payment->num_payment;
  648. while ($obj = $this->db->fetch_object($resql)) {
  649. $invoice = new Facture($this->db);
  650. $invoice->fetch($obj->fk_facture);
  651. $invoice->setUnpaid($user);
  652. $rejectedPayment->amounts[$obj->fk_facture] = price2num($obj->amount) * -1;
  653. }
  654. $result = $rejectedPayment->create($user);
  655. if ($result > 0) {
  656. // We created a negative payment, we also add the line as bank transaction
  657. $result = $rejectedPayment->addPaymentToBank($user, 'payment', '(CheckRejected)', $bankaccount, '', '');
  658. if ($result > 0) {
  659. $result = $payment->reject();
  660. if ($result > 0) {
  661. $this->db->commit();
  662. return $rejectedPayment->id;
  663. } else {
  664. $this->db->rollback();
  665. return -1;
  666. }
  667. } else {
  668. $this->error = $rejectedPayment->error;
  669. $this->errors = $rejectedPayment->errors;
  670. $this->db->rollback();
  671. return -1;
  672. }
  673. } else {
  674. $this->error = $rejectedPayment->error;
  675. $this->errors = $rejectedPayment->errors;
  676. $this->db->rollback();
  677. return -1;
  678. }
  679. } else {
  680. $this->error = $this->db->lasterror();
  681. $this->db->rollback();
  682. return -1;
  683. }
  684. }
  685. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  686. /**
  687. * Charge les proprietes ref_previous et ref_next
  688. *
  689. * @return int <0 if KO, 0 if OK
  690. */
  691. public function load_previous_next_id()
  692. {
  693. // phpcs:enable
  694. global $conf;
  695. $this->errno = 0;
  696. $sql = "SELECT MAX(rowid)";
  697. $sql .= " FROM ".MAIN_DB_PREFIX."bordereau_cheque";
  698. $sql .= " WHERE rowid < ".$this->id;
  699. $sql .= " AND entity = ".$conf->entity;
  700. $result = $this->db->query($sql);
  701. if (!$result) {
  702. $this->errno = -1035;
  703. }
  704. $row = $this->db->fetch_row($result);
  705. $this->previous_id = $row[0];
  706. $sql = "SELECT MIN(rowid)";
  707. $sql .= " FROM ".MAIN_DB_PREFIX."bordereau_cheque";
  708. $sql .= " WHERE rowid > ".$this->id;
  709. $sql .= " AND entity = ".$conf->entity;
  710. $result = $this->db->query($sql);
  711. if (!$result) {
  712. $this->errno = -1035;
  713. }
  714. $row = $this->db->fetch_row($result);
  715. $this->next_id = $row[0];
  716. return $this->errno;
  717. }
  718. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  719. /**
  720. * Set the creation date
  721. *
  722. * @param User $user Object user
  723. * @param int $date Date creation
  724. * @return int <0 if KO, >0 if OK
  725. */
  726. public function set_date($user, $date)
  727. {
  728. // phpcs:enable
  729. if ($user->rights->banque->cheque) {
  730. $sql = "UPDATE ".MAIN_DB_PREFIX."bordereau_cheque";
  731. $sql .= " SET date_bordereau = ".($date ? "'".$this->db->idate($date)."'" : 'null');
  732. $sql .= " WHERE rowid = ".((int) $this->id);
  733. dol_syslog("RemiseCheque::set_date", LOG_DEBUG);
  734. $resql = $this->db->query($sql);
  735. if ($resql) {
  736. $this->date_bordereau = $date;
  737. return 1;
  738. } else {
  739. $this->error = $this->db->error();
  740. return -1;
  741. }
  742. } else {
  743. return -2;
  744. }
  745. }
  746. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  747. /**
  748. * Set the ref of bordereau
  749. *
  750. * @param User $user Object user
  751. * @param int $ref ref of bordereau
  752. * @return int <0 if KO, >0 if OK
  753. */
  754. public function set_number($user, $ref)
  755. {
  756. // phpcs:enable
  757. if ($user->rights->banque->cheque) {
  758. $sql = "UPDATE ".MAIN_DB_PREFIX."bordereau_cheque";
  759. $sql .= " SET ref = '".$this->db->escape($ref)."'";
  760. $sql .= " WHERE rowid = ".((int) $this->id);
  761. dol_syslog("RemiseCheque::set_number", LOG_DEBUG);
  762. $resql = $this->db->query($sql);
  763. if ($resql) {
  764. return 1;
  765. } else {
  766. $this->error = $this->db->error();
  767. return -1;
  768. }
  769. } else {
  770. return -2;
  771. }
  772. }
  773. /**
  774. * Initialise an instance with random values.
  775. * Used to build previews or test instances.
  776. * id must be 0 if object instance is a specimen.
  777. *
  778. * @param string $option ''=Create a specimen invoice with lines, 'nolines'=No lines
  779. * @return void
  780. */
  781. public function initAsSpecimen($option = '')
  782. {
  783. global $user, $langs, $conf;
  784. $now = dol_now();
  785. $arraynow = dol_getdate($now);
  786. $nownotime = dol_mktime(0, 0, 0, $arraynow['mon'], $arraynow['mday'], $arraynow['year']);
  787. // Initialize parameters
  788. $this->id = 0;
  789. $this->ref = 'SPECIMEN';
  790. $this->specimen = 1;
  791. $this->date_bordereau = $nownotime;
  792. }
  793. /**
  794. * Return clicable name (with picto eventually)
  795. *
  796. * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto
  797. * @param string $option Sur quoi pointe le lien
  798. * @param int $notooltip 1=Disable tooltip
  799. * @param string $morecss Add more css on link
  800. * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
  801. * @return string Chaine avec URL
  802. */
  803. public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1)
  804. {
  805. global $conf, $langs;
  806. $result = '';
  807. $label = '<u>'.$langs->trans("ShowCheckReceipt").'</u>';
  808. $label .= '<br>';
  809. $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
  810. $url = DOL_URL_ROOT.'/compta/paiement/cheque/card.php?id='.$this->id;
  811. if ($option != 'nolink') {
  812. // Add param to save lastsearch_values or not
  813. $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
  814. if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
  815. $add_save_lastsearch_values = 1;
  816. }
  817. if ($add_save_lastsearch_values) {
  818. $url .= '&save_lastsearch_values=1';
  819. }
  820. }
  821. $linkclose = '';
  822. if (empty($notooltip)) {
  823. if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
  824. $label = $langs->trans("ShowCheckReceipt");
  825. $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
  826. }
  827. $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
  828. $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"';
  829. } else {
  830. $linkclose = ($morecss ? ' class="'.$morecss.'"' : '');
  831. }
  832. $linkstart = '<a href="'.$url.'"';
  833. $linkstart .= $linkclose.'>';
  834. $linkend = '</a>';
  835. $result .= $linkstart;
  836. if ($withpicto) {
  837. $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
  838. }
  839. if ($withpicto != 2) {
  840. $result .= $this->ref;
  841. }
  842. $result .= $linkend;
  843. return $result;
  844. }
  845. /**
  846. * Retourne le libelle du statut d'une facture (brouillon, validee, abandonnee, payee)
  847. *
  848. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  849. * @return string Libelle
  850. */
  851. public function getLibStatut($mode = 0)
  852. {
  853. return $this->LibStatut($this->statut, $mode);
  854. }
  855. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  856. /**
  857. * Return label of a status
  858. *
  859. * @param int $status Id status
  860. * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=short label + picto, 6=Long label + picto
  861. * @return string Libelle du statut
  862. */
  863. public function LibStatut($status, $mode = 0)
  864. {
  865. // phpcs:enable
  866. if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
  867. global $langs;
  868. $langs->load('compta');
  869. $this->labelStatus[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('ToValidate');
  870. $this->labelStatus[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
  871. $this->labelStatusShort[self::STATUS_DRAFT] = $langs->transnoentitiesnoconv('ToValidate');
  872. $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->transnoentitiesnoconv('Validated');
  873. }
  874. $statusType = 'status'.$status;
  875. if ($status == self::STATUS_VALIDATED) {
  876. $statusType = 'status4';
  877. }
  878. return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
  879. }
  880. }