don.class.php 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145
  1. <?php
  2. /* Copyright (C) 2002 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net>
  4. * Copyright (C) 2009 Regis Houssin <regis.houssin@inodbox.com>
  5. * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
  6. * Copyright (C) 2015-2017 Alexandre Spangaro <aspangaro@open-dsi.fr>
  7. * Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
  8. * Copyright (C) 2019 Thibault FOUCART <support@ptibogxiv.net>
  9. * Copyright (C) 2019-2020 Frédéric France <frederic.france@netlogic.fr>
  10. * Copyright (C) 2021 Maxime DEMAREST <maxime@indelog.fr>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  24. */
  25. /**
  26. * \file htdocs/don/class/don.class.php
  27. * \ingroup Donation
  28. * \brief File of class to manage donations
  29. */
  30. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  31. /**
  32. * Class to manage donations
  33. */
  34. class Don extends CommonObject
  35. {
  36. /**
  37. * @var string ID to identify managed object
  38. */
  39. public $element = 'don';
  40. /**
  41. * @var string Name of table without prefix where object is stored
  42. */
  43. public $table_element = 'don';
  44. /**
  45. * @var string Field with ID of parent key if this field has a parent
  46. */
  47. public $fk_element = 'fk_donation';
  48. /**
  49. * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  50. * @var int
  51. */
  52. public $ismultientitymanaged = 1;
  53. /**
  54. * @var string String with name of icon for object don. Must be the part after the 'object_' into object_myobject.png
  55. */
  56. public $picto = 'donation';
  57. /**
  58. * @var string Date of the donation
  59. */
  60. public $date;
  61. /**
  62. * amount of donation
  63. * @var double
  64. */
  65. public $amount;
  66. /**
  67. * @var string Thirdparty name
  68. */
  69. public $societe;
  70. /**
  71. * @var string Address
  72. */
  73. public $address;
  74. /**
  75. * @var string Zipcode
  76. */
  77. public $zip;
  78. /**
  79. * @var string Town
  80. */
  81. public $town;
  82. /**
  83. * @var string Email
  84. */
  85. public $email;
  86. /**
  87. * @var int 0 or 1
  88. */
  89. public $public;
  90. /**
  91. * @var int project ID
  92. */
  93. public $fk_project;
  94. /**
  95. * @var int type payment ID
  96. */
  97. public $fk_typepayment;
  98. public $num_payment;
  99. public $date_valid;
  100. /**
  101. * @var int payment mode id
  102. */
  103. public $modepaymentid = 0;
  104. /**
  105. * @var array Array of status label
  106. */
  107. public $labelStatus;
  108. /**
  109. * @var array Array of status label short
  110. */
  111. public $labelStatusShort;
  112. const STATUS_DRAFT = 0;
  113. const STATUS_VALIDATED = 1;
  114. const STATUS_PAID = 2;
  115. const STATUS_CANCELED = -1;
  116. /**
  117. * Constructor
  118. *
  119. * @param DoliDB $db Database handler
  120. */
  121. public function __construct($db)
  122. {
  123. $this->db = $db;
  124. }
  125. /**
  126. * Returns the donation status label (draft, valid, abandoned, paid)
  127. *
  128. * @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
  129. * @return string Label of status
  130. */
  131. public function getLibStatut($mode = 0)
  132. {
  133. return $this->LibStatut($this->statut, $mode);
  134. }
  135. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  136. /**
  137. * Return the label of a given status
  138. *
  139. * @param int $status Id statut
  140. * @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
  141. * @return string Label of status
  142. */
  143. public function LibStatut($status, $mode = 0)
  144. {
  145. // phpcs:enable
  146. if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
  147. global $langs;
  148. $langs->load("donations");
  149. $this->labelStatus[-1] = $langs->transnoentitiesnoconv("Canceled");
  150. $this->labelStatus[0] = $langs->transnoentitiesnoconv("DonationStatusPromiseNotValidated");
  151. $this->labelStatus[1] = $langs->transnoentitiesnoconv("DonationStatusPromiseValidated");
  152. $this->labelStatus[2] = $langs->transnoentitiesnoconv("DonationStatusPaid");
  153. $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv("Canceled");
  154. $this->labelStatusShort[0] = $langs->transnoentitiesnoconv("DonationStatusPromiseNotValidatedShort");
  155. $this->labelStatusShort[1] = $langs->transnoentitiesnoconv("DonationStatusPromiseValidatedShort");
  156. $this->labelStatusShort[2] = $langs->transnoentitiesnoconv("DonationStatusPaidShort");
  157. }
  158. $statusType = 'status'.$status;
  159. if ($status == self::STATUS_CANCELED) {
  160. $statusType = 'status9';
  161. }
  162. if ($status == self::STATUS_PAID) {
  163. $statusType = 'status6';
  164. }
  165. return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
  166. }
  167. /**
  168. * Initialise an instance with random values.
  169. * Used to build previews or test instances.
  170. * id must be 0 if object instance is a specimen.
  171. *
  172. * @return void
  173. */
  174. public function initAsSpecimen()
  175. {
  176. global $conf, $user, $langs;
  177. $now = dol_now();
  178. // Charge tableau des id de societe socids
  179. $socids = array();
  180. $sql = "SELECT rowid";
  181. $sql .= " FROM ".MAIN_DB_PREFIX."societe";
  182. $sql .= " WHERE client IN (1, 3)";
  183. $sql .= " AND entity = ".$conf->entity;
  184. $sql .= " LIMIT 10";
  185. $resql = $this->db->query($sql);
  186. if ($resql) {
  187. $num_socs = $this->db->num_rows($resql);
  188. $i = 0;
  189. while ($i < $num_socs) {
  190. $i++;
  191. $row = $this->db->fetch_row($resql);
  192. $socids[$i] = $row[0];
  193. }
  194. }
  195. // Initialise parametres
  196. $this->id = 0;
  197. $this->ref = 'SPECIMEN';
  198. $this->specimen = 1;
  199. $this->lastname = 'Doe';
  200. $this->firstname = 'John';
  201. $this->socid = 1;
  202. $this->date = $now;
  203. $this->date_valid = $now;
  204. $this->amount = 100.90;
  205. $this->public = 1;
  206. $this->societe = 'The Company';
  207. $this->address = 'Twist road';
  208. $this->zip = '99999';
  209. $this->town = 'Town';
  210. $this->note_private = 'Private note';
  211. $this->note_public = 'Public note';
  212. $this->email = 'email@email.com';
  213. $this->phone = '0123456789';
  214. $this->phone_mobile = '0606060606';
  215. $this->statut = 1;
  216. }
  217. /**
  218. * Check params and init ->errors array.
  219. * TODO This function seems to not be used by core code.
  220. *
  221. * @param int $minimum Minimum
  222. * @return int 0 if KO, >0 if OK
  223. */
  224. public function check($minimum = 0)
  225. {
  226. global $langs;
  227. $langs->load('main');
  228. $langs->load('companies');
  229. $error_string = array();
  230. $err = 0;
  231. if (dol_strlen(trim($this->societe)) == 0) {
  232. if ((dol_strlen(trim($this->lastname)) + dol_strlen(trim($this->firstname))) == 0) {
  233. $error_string[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Company').'/'.$langs->transnoentitiesnoconv('Firstname').'-'.$langs->transnoentitiesnoconv('Lastname'));
  234. $err++;
  235. }
  236. }
  237. if (dol_strlen(trim($this->address)) == 0) {
  238. $error_string[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Address'));
  239. $err++;
  240. }
  241. if (dol_strlen(trim($this->zip)) == 0) {
  242. $error_string[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Zip'));
  243. $err++;
  244. }
  245. if (dol_strlen(trim($this->town)) == 0) {
  246. $error_string[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Town'));
  247. $err++;
  248. }
  249. if (dol_strlen(trim($this->email)) == 0) {
  250. $error_string[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('EMail'));
  251. $err++;
  252. }
  253. $this->amount = trim($this->amount);
  254. $map = range(0, 9);
  255. $len = dol_strlen($this->amount);
  256. for ($i = 0; $i < $len; $i++) {
  257. if (!isset($map[substr($this->amount, $i, 1)])) {
  258. $error_string[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Amount'));
  259. $err++;
  260. $amount_invalid = 1;
  261. break;
  262. }
  263. }
  264. if (!$amount_invalid) {
  265. if ($this->amount == 0) {
  266. $error_string[] = $langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Amount'));
  267. $err++;
  268. } else {
  269. if ($this->amount < $minimum && $minimum > 0) {
  270. $error_string[] = $langs->trans('MinimumAmount', $langs->transnoentitiesnoconv('$minimum'));
  271. $err++;
  272. }
  273. }
  274. }
  275. if ($err) {
  276. $this->errors = $error_string;
  277. return 0;
  278. } else {
  279. return 1;
  280. }
  281. }
  282. /**
  283. * Create donation record into database
  284. *
  285. * @param User $user User who created the donation
  286. * @param int $notrigger Disable triggers
  287. * @return int <0 if KO, id of created donation if OK
  288. * TODO add numbering module for Ref
  289. */
  290. public function create($user, $notrigger = 0)
  291. {
  292. global $conf, $langs;
  293. $error = 0;
  294. $ret = 0;
  295. $now = dol_now();
  296. // Clean parameters
  297. $this->address = ($this->address > 0 ? $this->address : $this->address);
  298. $this->zip = ($this->zip > 0 ? $this->zip : $this->zip);
  299. $this->town = ($this->town > 0 ? $this->town : $this->town);
  300. $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
  301. $this->country = ($this->country ? $this->country : $this->country);
  302. $this->amount = price2num($this->amount);
  303. // Check parameters
  304. if ($this->amount < 0) {
  305. $this->error = $langs->trans('FieldCannotBeNegative', $langs->transnoentitiesnoconv("Amount"));
  306. return -1;
  307. }
  308. $this->db->begin();
  309. $sql = "INSERT INTO ".MAIN_DB_PREFIX."don (";
  310. $sql .= "datec";
  311. $sql .= ", entity";
  312. $sql .= ", amount";
  313. $sql .= ", fk_payment";
  314. $sql .= ", fk_soc";
  315. $sql .= ", firstname";
  316. $sql .= ", lastname";
  317. $sql .= ", societe";
  318. $sql .= ", address";
  319. $sql .= ", zip";
  320. $sql .= ", town";
  321. $sql .= ", fk_country";
  322. $sql .= ", public";
  323. $sql .= ", fk_projet";
  324. $sql .= ", note_private";
  325. $sql .= ", note_public";
  326. $sql .= ", fk_user_author";
  327. $sql .= ", fk_user_valid";
  328. $sql .= ", datedon";
  329. $sql .= ", email";
  330. $sql .= ", phone";
  331. $sql .= ", phone_mobile";
  332. $sql .= ") VALUES (";
  333. $sql .= "'".$this->db->idate($this->date ? $this->date : $now)."'";
  334. $sql .= ", ".((int) $conf->entity);
  335. $sql .= ", ".((float) $this->amount);
  336. $sql .= ", ".($this->modepaymentid ? $this->modepaymentid : "null");
  337. $sql .= ", ".($this->socid > 0 ? $this->socid : "null");
  338. $sql .= ", '".$this->db->escape($this->firstname)."'";
  339. $sql .= ", '".$this->db->escape($this->lastname)."'";
  340. $sql .= ", '".$this->db->escape($this->societe)."'";
  341. $sql .= ", '".$this->db->escape($this->address)."'";
  342. $sql .= ", '".$this->db->escape($this->zip)."'";
  343. $sql .= ", '".$this->db->escape($this->town)."'";
  344. $sql .= ", ".(int) ($this->country_id > 0 ? $this->country_id : 0);
  345. $sql .= ", ".(int) $this->public;
  346. $sql .= ", ".($this->fk_project > 0 ? (int) $this->fk_project : "null");
  347. $sql .= ", ".(!empty($this->note_private) ? ("'".$this->db->escape($this->note_private)."'") : "NULL");
  348. $sql .= ", ".(!empty($this->note_public) ? ("'".$this->db->escape($this->note_public)."'") : "NULL");
  349. $sql .= ", ".((int) $user->id);
  350. $sql .= ", null";
  351. $sql .= ", '".$this->db->idate($this->date)."'";
  352. $sql .= ", '".(!empty($this->email) ? $this->db->escape(trim($this->email)) : "")."'";
  353. $sql .= ", '".(!empty($this->phone) ? $this->db->escape(trim($this->phone)) : "")."'";
  354. $sql .= ", '".(!empty($this->phone_mobile) ? $this->db->escape(trim($this->phone_mobile)) : "")."'";
  355. $sql .= ")";
  356. $resql = $this->db->query($sql);
  357. if ($resql) {
  358. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."don");
  359. $ret = $this->id;
  360. if (!$notrigger) {
  361. // Call trigger
  362. $result = $this->call_trigger('DON_CREATE', $user);
  363. if ($result < 0) {
  364. $error++;
  365. }
  366. // End call triggers
  367. }
  368. } else {
  369. $this->error = $this->db->lasterror();
  370. $this->errno = $this->db->lasterrno();
  371. $error++;
  372. }
  373. // Update extrafield
  374. if (!$error) {
  375. $result = $this->insertExtraFields();
  376. if ($result < 0) {
  377. $error++;
  378. }
  379. }
  380. if (!$error && (getDolGlobalString('MAIN_DISABLEDRAFTSTATUS') || getDolGlobalString('MAIN_DISABLEDRAFTSTATUS_DONATION'))) {
  381. //$res = $this->setValid($user);
  382. //if ($res < 0) $error++;
  383. }
  384. if (!$error) {
  385. $this->db->commit();
  386. return $ret;
  387. } else {
  388. $this->db->rollback();
  389. return -1;
  390. }
  391. }
  392. /**
  393. * Update a donation record
  394. *
  395. * @param User $user Objet utilisateur qui met a jour le don
  396. * @param int $notrigger Disable triggers
  397. * @return int >0 if OK, <0 if KO
  398. */
  399. public function update($user, $notrigger = 0)
  400. {
  401. global $langs, $conf;
  402. $error = 0;
  403. // Clean parameters
  404. $this->address = ($this->address > 0 ? $this->address : $this->address);
  405. $this->zip = ($this->zip > 0 ? $this->zip : $this->zip);
  406. $this->town = ($this->town > 0 ? $this->town : $this->town);
  407. $this->country_id = ($this->country_id > 0 ? $this->country_id : $this->country_id);
  408. $this->country = ($this->country ? $this->country : $this->country);
  409. $this->amount = price2num($this->amount);
  410. // Check parameters
  411. if ($this->amount < 0) {
  412. $this->error = $langs->trans('FieldCannotBeNegative', $langs->transnoentitiesnoconv("Amount"));
  413. return -1;
  414. }
  415. $this->db->begin();
  416. $sql = "UPDATE ".MAIN_DB_PREFIX."don SET";
  417. $sql .= " amount = ".((float) $this->amount);
  418. $sql .= ", fk_payment = ".($this->modepaymentid ? $this->modepaymentid : "null");
  419. $sql .= ", firstname = '".$this->db->escape($this->firstname)."'";
  420. $sql .= ", lastname='".$this->db->escape($this->lastname)."'";
  421. $sql .= ", societe='".$this->db->escape($this->societe)."'";
  422. $sql .= ", address='".$this->db->escape($this->address)."'";
  423. $sql .= ", zip='".$this->db->escape($this->zip)."'";
  424. $sql .= ", town='".$this->db->escape($this->town)."'";
  425. $sql .= ", fk_country = ".($this->country_id > 0 ? ((int) $this->country_id) : '0');
  426. $sql .= ", public=".((int) $this->public);
  427. $sql .= ", fk_projet=".($this->fk_project > 0 ? $this->fk_project : 'null');
  428. $sql .= ", note_private=".(!empty($this->note_private) ? ("'".$this->db->escape($this->note_private)."'") : "NULL");
  429. $sql .= ", note_public=".(!empty($this->note_public) ? ("'".$this->db->escape($this->note_public)."'") : "NULL");
  430. $sql .= ", datedon='".$this->db->idate($this->date)."'";
  431. $sql .= ", date_valid=".($this->date_valid ? "'".$this->db->idate($this->date)."'" : "null");
  432. $sql .= ", email='".$this->db->escape(trim($this->email))."'";
  433. $sql .= ", phone='".$this->db->escape(trim($this->phone))."'";
  434. $sql .= ", phone_mobile='".$this->db->escape(trim($this->phone_mobile))."'";
  435. $sql .= ", fk_statut=".((int) $this->statut);
  436. $sql .= " WHERE rowid = ".((int) $this->id);
  437. dol_syslog(get_class($this)."::Update", LOG_DEBUG);
  438. $resql = $this->db->query($sql);
  439. if ($resql) {
  440. if (!$notrigger) {
  441. // Call trigger
  442. $result = $this->call_trigger('DON_MODIFY', $user);
  443. if ($result < 0) {
  444. $error++;
  445. }
  446. // End call triggers
  447. }
  448. // Update extrafield
  449. if (!$error) {
  450. $result = $this->insertExtraFields();
  451. if ($result < 0) {
  452. $error++;
  453. }
  454. }
  455. if (!$error) {
  456. $this->db->commit();
  457. $result = 1;
  458. } else {
  459. $this->db->rollback();
  460. $result = -1;
  461. }
  462. } else {
  463. $this->error = $this->db->lasterror();
  464. $this->errors[] = $this->error;
  465. $this->db->rollback();
  466. dol_syslog(get_class($this)."::Update error -2 ".$this->error, LOG_ERR);
  467. $result = -2;
  468. }
  469. return $result;
  470. }
  471. /**
  472. * Delete a donation from database
  473. *
  474. * @param User $user User
  475. * @param int $notrigger Disable triggers
  476. * @return int <0 if KO, 0 if not possible, >0 if OK
  477. */
  478. public function delete($user, $notrigger = 0)
  479. {
  480. global $user, $conf, $langs;
  481. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  482. $error = 0;
  483. $this->db->begin();
  484. if (!$error && !$notrigger) {
  485. // Call trigger
  486. $result = $this->call_trigger('DON_DELETE', $user);
  487. if ($result < 0) {
  488. $error++;
  489. }
  490. // End call triggers
  491. }
  492. // Delete donation
  493. if (!$error) {
  494. $sql = "DELETE FROM ".MAIN_DB_PREFIX."don_extrafields";
  495. $sql .= " WHERE fk_object = ".((int) $this->id);
  496. $resql = $this->db->query($sql);
  497. if (!$resql) {
  498. $this->errors[] = $this->db->lasterror();
  499. $error++;
  500. }
  501. }
  502. if (!$error) {
  503. $sql = "DELETE FROM ".MAIN_DB_PREFIX."don";
  504. $sql .= " WHERE rowid=".((int) $this->id);
  505. $resql = $this->db->query($sql);
  506. if (!$resql) {
  507. $this->errors[] = $this->db->lasterror();
  508. $error++;
  509. }
  510. }
  511. if (!$error) {
  512. $this->db->commit();
  513. return 1;
  514. } else {
  515. foreach ($this->errors as $errmsg) {
  516. dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
  517. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  518. }
  519. dol_syslog(get_class($this)."::delete ".$this->error, LOG_ERR);
  520. $this->db->rollback();
  521. return -1;
  522. }
  523. }
  524. /**
  525. * Load donation from database
  526. *
  527. * @param int $id Id of donation to load
  528. * @param string $ref Ref of donation to load
  529. * @return int <0 if KO, >0 if OK
  530. */
  531. public function fetch($id, $ref = '')
  532. {
  533. global $conf;
  534. $sql = "SELECT d.rowid, d.datec, d.date_valid, d.tms as datem, d.datedon,";
  535. $sql .= " d.fk_soc as socid,d.firstname, d.lastname, d.societe, d.amount, d.fk_statut, d.address, d.zip, d.town, ";
  536. $sql .= " d.fk_country, d.country as country_olddata, d.public, d.amount, d.fk_payment, d.paid, d.note_private, d.note_public, d.email, d.phone, ";
  537. $sql .= " d.phone_mobile, d.fk_projet as fk_project, d.model_pdf,";
  538. $sql .= " p.ref as project_ref,";
  539. $sql .= " cp.libelle as payment_label, cp.code as payment_code,";
  540. $sql .= " c.code as country_code, c.label as country";
  541. $sql .= " FROM ".MAIN_DB_PREFIX."don as d";
  542. $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = d.fk_projet";
  543. $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON cp.id = d.fk_payment";
  544. $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.fk_country = c.rowid";
  545. $sql .= " WHERE d.entity IN (".getEntity('donation').")";
  546. if (!empty($id)) {
  547. $sql .= " AND d.rowid=".((int) $id);
  548. } elseif (!empty($ref)) {
  549. $sql .= " AND d.ref='".$this->db->escape($ref)."'";
  550. }
  551. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  552. $resql = $this->db->query($sql);
  553. if ($resql) {
  554. if ($this->db->num_rows($resql)) {
  555. $obj = $this->db->fetch_object($resql);
  556. $this->id = $obj->rowid;
  557. $this->ref = $obj->rowid;
  558. $this->date_creation = $this->db->jdate($obj->datec);
  559. $this->datec = $this->db->jdate($obj->datec);
  560. $this->date_validation = $this->db->jdate($obj->date_valid);
  561. $this->date_valid = $this->db->jdate($obj->date_valid);
  562. $this->date_modification = $this->db->jdate($obj->datem);
  563. $this->datem = $this->db->jdate($obj->datem);
  564. $this->date = $this->db->jdate($obj->datedon);
  565. $this->socid = $obj->socid;
  566. $this->firstname = $obj->firstname;
  567. $this->lastname = $obj->lastname;
  568. $this->societe = $obj->societe;
  569. $this->statut = $obj->fk_statut;
  570. $this->address = $obj->address;
  571. $this->zip = $obj->zip;
  572. $this->town = $obj->town;
  573. $this->country_id = $obj->fk_country;
  574. $this->country_code = $obj->country_code;
  575. $this->country = $obj->country;
  576. $this->country_olddata = $obj->country_olddata; // deprecated
  577. $this->email = $obj->email;
  578. $this->phone = $obj->phone;
  579. $this->phone_mobile = $obj->phone_mobile;
  580. $this->project = $obj->project_ref;
  581. $this->fk_projet = $obj->fk_project; // deprecated
  582. $this->fk_project = $obj->fk_project;
  583. $this->public = $obj->public;
  584. $this->mode_reglement_id = $obj->fk_payment;
  585. $this->mode_reglement_code = $obj->payment_code;
  586. $this->mode_reglement = $obj->payment_label;
  587. $this->paid = $obj->paid;
  588. $this->amount = $obj->amount;
  589. $this->note_private = $obj->note_private;
  590. $this->note_public = $obj->note_public;
  591. $this->model_pdf = $obj->model_pdf;
  592. $this->modelpdf = $obj->model_pdf; // deprecated
  593. // Retrieve all extrafield
  594. // fetch optionals attributes and labels
  595. $this->fetch_optionals();
  596. }
  597. return 1;
  598. } else {
  599. dol_print_error($this->db);
  600. return -1;
  601. }
  602. }
  603. /**
  604. * Validate a intervention
  605. *
  606. * @param User $user User that validate
  607. * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
  608. * @return int <0 if KO, >0 if OK
  609. */
  610. public function setValid($user, $notrigger = 0)
  611. {
  612. return $this->valid_promesse($this->id, $user->id, $notrigger);
  613. }
  614. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  615. /**
  616. * Validate a promise of donation
  617. *
  618. * @param int $id id of donation
  619. * @param int $userid User who validate the donation/promise
  620. * @param int $notrigger Disable triggers
  621. * @return int <0 if KO, >0 if OK
  622. */
  623. public function valid_promesse($id, $userid, $notrigger = 0)
  624. {
  625. // phpcs:enable
  626. global $langs, $user;
  627. $error = 0;
  628. $this->db->begin();
  629. $sql = "UPDATE ".MAIN_DB_PREFIX."don SET fk_statut = 1, fk_user_valid = ".((int) $userid)." WHERE rowid = ".((int) $id)." AND fk_statut = 0";
  630. $resql = $this->db->query($sql);
  631. if ($resql) {
  632. if ($this->db->affected_rows($resql)) {
  633. if (!$notrigger) {
  634. // Call trigger
  635. $result = $this->call_trigger('DON_VALIDATE', $user);
  636. if ($result < 0) {
  637. $error++;
  638. }
  639. // End call triggers
  640. }
  641. }
  642. } else {
  643. $error++;
  644. $this->error = $this->db->lasterror();
  645. }
  646. if (!$error) {
  647. $this->statut = 1;
  648. $this->db->commit();
  649. return 1;
  650. } else {
  651. $this->db->rollback();
  652. return -1;
  653. }
  654. }
  655. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  656. /**
  657. * Classify the donation as paid, the donation was received
  658. *
  659. * @deprecated
  660. * @see setPaid()
  661. * @param int $id id of donation
  662. * @param int $modepayment mode of payment
  663. * @return int <0 if KO, >0 if OK
  664. */
  665. public function set_paid($id, $modepayment = 0)
  666. {
  667. // phpcs:enable
  668. dol_syslog(get_class($this)."::set_paid is deprecated, use setPaid instead", LOG_NOTICE);
  669. return $this->setPaid($id, $modepayment);
  670. }
  671. /**
  672. * Classify the donation as paid, the donation was received
  673. *
  674. * @param int $id id of donation
  675. * @param int $modepayment mode of payment
  676. * @return int <0 if KO, >0 if OK
  677. */
  678. public function setPaid($id, $modepayment = 0)
  679. {
  680. $sql = "UPDATE ".MAIN_DB_PREFIX."don SET fk_statut = 2, paid = 1";
  681. if ($modepayment) {
  682. $sql .= ", fk_payment = ".((int) $modepayment);
  683. }
  684. $sql .= " WHERE rowid = ".((int) $id)." AND fk_statut = 1";
  685. $resql = $this->db->query($sql);
  686. if ($resql) {
  687. if ($this->db->affected_rows($resql)) {
  688. $this->statut = 2;
  689. $this->paid = 1;
  690. return 1;
  691. } else {
  692. return 0;
  693. }
  694. } else {
  695. dol_print_error($this->db);
  696. return -1;
  697. }
  698. }
  699. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  700. /**
  701. * Set donation to status cancelled
  702. *
  703. * @param int $id id of donation
  704. * @return int <0 if KO, >0 if OK
  705. */
  706. public function set_cancel($id)
  707. {
  708. // phpcs:enable
  709. $sql = "UPDATE ".MAIN_DB_PREFIX."don SET fk_statut = -1 WHERE rowid = ".((int) $id);
  710. $resql = $this->db->query($sql);
  711. if ($resql) {
  712. if ($this->db->affected_rows($resql)) {
  713. $this->statut = -1;
  714. return 1;
  715. } else {
  716. return 0;
  717. }
  718. } else {
  719. dol_print_error($this->db);
  720. return -1;
  721. }
  722. }
  723. /**
  724. * Set cancel status
  725. *
  726. * @param User $user Object user that modify
  727. * @param int $notrigger 1=Does not execute triggers, 0=Execute triggers
  728. * @return int <0 if KO, 0=Nothing done, >0 if OK
  729. */
  730. public function reopen($user, $notrigger = 0)
  731. {
  732. // Protection
  733. if ($this->statut != self::STATUS_CANCELED) {
  734. return 0;
  735. }
  736. /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->bom->write))
  737. || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->bom->bom_advance->validate))))
  738. {
  739. $this->error='Permission denied';
  740. return -1;
  741. }*/
  742. return $this->setStatusCommon($user, self::STATUS_VALIDATED, $notrigger, 'DON_REOPEN');
  743. }
  744. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  745. /**
  746. * Sum of donations
  747. *
  748. * @param string $param 1=promesses de dons validees , 2=xxx, 3=encaisses
  749. * @return int Summ of donations
  750. */
  751. public function sum_donations($param)
  752. {
  753. // phpcs:enable
  754. global $conf;
  755. $result = 0;
  756. $sql = "SELECT sum(amount) as total";
  757. $sql .= " FROM ".MAIN_DB_PREFIX."don";
  758. $sql .= " WHERE fk_statut = ".((int) $param);
  759. $sql .= " AND entity = ".$conf->entity;
  760. $resql = $this->db->query($sql);
  761. if ($resql) {
  762. $obj = $this->db->fetch_object($resql);
  763. $result = $obj->total;
  764. }
  765. return $result;
  766. }
  767. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  768. /**
  769. * Charge indicateurs this->nb pour le tableau de bord
  770. *
  771. * @return int <0 if KO, >0 if OK
  772. */
  773. public function load_state_board()
  774. {
  775. // phpcs:enable
  776. global $conf;
  777. $this->nb = array();
  778. $sql = "SELECT count(d.rowid) as nb";
  779. $sql .= " FROM ".MAIN_DB_PREFIX."don as d";
  780. $sql .= " WHERE d.fk_statut > 0";
  781. $sql .= " AND d.entity IN (".getEntity('donation').")";
  782. $resql = $this->db->query($sql);
  783. if ($resql) {
  784. while ($obj = $this->db->fetch_object($resql)) {
  785. $this->nb["donations"] = $obj->nb;
  786. }
  787. $this->db->free($resql);
  788. return 1;
  789. } else {
  790. dol_print_error($this->db);
  791. $this->error = $this->db->error();
  792. return -1;
  793. }
  794. }
  795. /**
  796. * Return clicable name (with picto eventually)
  797. *
  798. * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto
  799. * @param int $notooltip 1=Disable tooltip
  800. * @param string $moretitle Add more text to title tooltip
  801. * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
  802. * @return string Chaine avec URL
  803. */
  804. public function getNomUrl($withpicto = 0, $notooltip = 0, $moretitle = '', $save_lastsearch_value = -1)
  805. {
  806. global $conf, $langs, $hookmanager;
  807. if (!empty($conf->dol_no_mouse_hover)) {
  808. $notooltip = 1; // Force disable tooltips
  809. }
  810. $result = '';
  811. $label = img_picto('', $this->picto).' <u class="paddingrightonly">'.$langs->trans("Donation").'</u>';
  812. if (isset($this->status)) {
  813. $label .= ' '.$this->getLibStatut(5);
  814. }
  815. if (!empty($this->id)) {
  816. $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->id;
  817. $label .= '<br><b>'.$langs->trans('Date').':</b> '.dol_print_date($this->date, 'day');
  818. }
  819. if ($moretitle) {
  820. $label .= ' - '.$moretitle;
  821. }
  822. $url = DOL_URL_ROOT.'/don/card.php?id='.$this->id;
  823. $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
  824. if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
  825. $add_save_lastsearch_values = 1;
  826. }
  827. if ($add_save_lastsearch_values) {
  828. $url .= '&save_lastsearch_values=1';
  829. }
  830. $linkstart = '<a href="'.$url.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
  831. $linkend = '</a>';
  832. $result .= $linkstart;
  833. if ($withpicto) {
  834. $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
  835. }
  836. if ($withpicto != 2) {
  837. $result .= $this->ref;
  838. }
  839. $result .= $linkend;
  840. global $action;
  841. $hookmanager->initHooks(array($this->element . 'dao'));
  842. $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
  843. $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
  844. if ($reshook > 0) {
  845. $result = $hookmanager->resPrint;
  846. } else {
  847. $result .= $hookmanager->resPrint;
  848. }
  849. return $result;
  850. }
  851. /**
  852. * Information on record
  853. *
  854. * @param int $id Id of record
  855. * @return void
  856. */
  857. public function info($id)
  858. {
  859. $sql = 'SELECT d.rowid, d.datec, d.fk_user_author, d.fk_user_valid,';
  860. $sql .= ' d.tms as datem';
  861. $sql .= ' FROM '.MAIN_DB_PREFIX.'don as d';
  862. $sql .= ' WHERE d.rowid = '.((int) $id);
  863. dol_syslog(get_class($this).'::info', LOG_DEBUG);
  864. $result = $this->db->query($sql);
  865. if ($result) {
  866. if ($this->db->num_rows($result)) {
  867. $obj = $this->db->fetch_object($result);
  868. $this->id = $obj->rowid;
  869. $this->user_creation_id = $obj->fk_user_author;
  870. $this->user_validation_id = $obj->fk_user_valid;
  871. $this->date_creation = $this->db->jdate($obj->datec);
  872. $this->date_modification = (!empty($obj->tms) ? $this->db->jdate($obj->tms) : "");
  873. }
  874. $this->db->free($result);
  875. } else {
  876. dol_print_error($this->db);
  877. }
  878. }
  879. /**
  880. * Create a document onto disk according to template module.
  881. *
  882. * @param string $modele Force template to use ('' to not force)
  883. * @param Translate $outputlangs objet lang a utiliser pour traduction
  884. * @param int $hidedetails Hide details of lines
  885. * @param int $hidedesc Hide description
  886. * @param int $hideref Hide ref
  887. * @return int 0 if KO, 1 if OK
  888. */
  889. public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0)
  890. {
  891. global $conf, $langs;
  892. $langs->load("bills");
  893. if (!dol_strlen($modele)) {
  894. $modele = 'html_cerfafr';
  895. if ($this->model_pdf) {
  896. $modele = $this->model_pdf;
  897. } elseif (!empty($conf->global->DON_ADDON_MODEL)) {
  898. $modele = $conf->global->DON_ADDON_MODEL;
  899. }
  900. }
  901. $modelpath = "core/modules/dons/";
  902. // TODO Restore use of commonGenerateDocument instead of dedicated code here
  903. //return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
  904. // Increase limit for PDF build
  905. $err = error_reporting();
  906. error_reporting(0);
  907. @set_time_limit(120);
  908. error_reporting($err);
  909. $srctemplatepath = '';
  910. // If selected modele is a filename template (then $modele="modelname:filename")
  911. $tmp = explode(':', $modele, 2);
  912. if (!empty($tmp[1])) {
  913. $modele = $tmp[0];
  914. $srctemplatepath = $tmp[1];
  915. }
  916. // Search template files
  917. $file = ''; $classname = ''; $filefound = 0;
  918. $dirmodels = array('/');
  919. if (is_array($conf->modules_parts['models'])) {
  920. $dirmodels = array_merge($dirmodels, $conf->modules_parts['models']);
  921. }
  922. foreach ($dirmodels as $reldir) {
  923. foreach (array('html', 'doc', 'pdf') as $prefix) {
  924. $file = $prefix."_".preg_replace('/^html_/', '', $modele).".modules.php";
  925. // On verifie l'emplacement du modele
  926. $file = dol_buildpath($reldir."core/modules/dons/".$file, 0);
  927. if (file_exists($file)) {
  928. $filefound = 1;
  929. $classname = $prefix.'_'.$modele;
  930. break;
  931. }
  932. }
  933. if ($filefound) {
  934. break;
  935. }
  936. }
  937. // Charge le modele
  938. if ($filefound) {
  939. require_once $file;
  940. $object = $this;
  941. $classname = $modele;
  942. $obj = new $classname($this->db);
  943. // We save charset_output to restore it because write_file can change it if needed for
  944. // output format that does not support UTF8.
  945. $sav_charset_output = $outputlangs->charset_output;
  946. if ($obj->write_file($object, $outputlangs, $srctemplatepath, $hidedetails, $hidedesc, $hideref) > 0) {
  947. $outputlangs->charset_output = $sav_charset_output;
  948. // we delete preview files
  949. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  950. dol_delete_preview($object);
  951. return 1;
  952. } else {
  953. $outputlangs->charset_output = $sav_charset_output;
  954. dol_syslog("Erreur dans don_create");
  955. dol_print_error($this->db, $obj->error);
  956. return 0;
  957. }
  958. } else {
  959. print $langs->trans("Error")." ".$langs->trans("ErrorFileDoesNotExists", $file);
  960. return 0;
  961. }
  962. }
  963. /**
  964. * Function used to replace a thirdparty id with another one.
  965. *
  966. * @param DoliDB $db Database handler
  967. * @param int $origin_id Old third-party id
  968. * @param int $dest_id New third-party id
  969. * @return bool
  970. */
  971. public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
  972. {
  973. $tables = array(
  974. 'don'
  975. );
  976. return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
  977. }
  978. /**
  979. * Function to get reamain to pay for a donation
  980. *
  981. * @return int <0 if KO, > reamain to pay if OK
  982. */
  983. public function getRemainToPay()
  984. {
  985. dol_syslog(__METHOD__, LOG_DEBUG);
  986. if (empty($this->id)) {
  987. $this->error = 'Missing object id';
  988. $this->errors[] = $this->error;
  989. dol_syslog(__METHOD__.' : '.$this->error, LOG_ERR);
  990. return -1;
  991. }
  992. $sql = "SELECT SUM(amount) as sum_amount FROM ".MAIN_DB_PREFIX."payment_donation WHERE fk_donation = ".((int) $this->id);
  993. $resql = $this->db->query($sql);
  994. if (!$resql) {
  995. dol_print_error($this->db);
  996. return -2;
  997. } else {
  998. $sum_amount = (float) $this->db->fetch_object($resql)->sum_amount;
  999. return (float) $this->amount - $sum_amount;
  1000. }
  1001. }
  1002. }