1<?php
2/* Copyright (C) 2015       Alexandre Spangaro	  	<aspangaro@open-dsi.fr>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18/**
19 *  \file       htdocs/don/class/paymentdonation.class.php
20 *  \ingroup    Donation
21 *  \brief      File of class to manage payment of donations
22 */
23
24require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
25
26
27/**
28 *	Class to manage payments of donations
29 */
30class PaymentDonation extends CommonObject
31{
32	/**
33	 * @var string ID to identify managed object
34	 */
35	public $element = 'payment_donation';
36
37	/**
38	 * @var string Name of table without prefix where object is stored
39	 */
40	public $table_element = 'payment_donation';
41
42	/**
43	 * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
44	 */
45	public $picto = 'payment';
46
47	/**
48	 * @var int ID
49	 */
50	public $rowid;
51
52	/**
53	 * @var int ID
54	 */
55	public $fk_donation;
56
57	public $datec = '';
58
59	public $tms = '';
60
61	public $datep = '';
62
63	public $amount; // Total amount of payment
64
65	public $amounts = array(); // Array of amounts
66
67	public $typepayment;
68
69	public $num_payment;
70
71	/**
72	 * @var int ID
73	 */
74	public $fk_bank;
75
76	/**
77	 * @var int ID
78	 */
79	public $fk_user_creat;
80
81	/**
82	 * @var int ID
83	 */
84	public $fk_user_modif;
85
86	/**
87	 * @deprecated
88	 * @see $amount, $amounts
89	 */
90	public $total;
91
92	public $type_code;
93	public $type_label;
94
95
96	/**
97	 *	Constructor
98	 *
99	 *  @param		DoliDB		$db      Database handler
100	 */
101	public function __construct($db)
102	{
103		$this->db = $db;
104	}
105
106	/**
107	 *  Create payment of donation into database.
108	 *  Use this->amounts to have list of lines for the payment
109	 *
110	 *  @param      User		$user			User making payment
111	 *  @param      bool 		$notrigger 		false=launch triggers after, true=disable triggers
112	 *  @return     int     					<0 if KO, id of payment if OK
113	 */
114	public function create($user, $notrigger = false)
115	{
116		global $conf, $langs;
117
118		$error = 0;
119
120		$now = dol_now();
121
122		// Validate parameters
123		if (!$this->datepaid)
124		{
125			$this->error = 'ErrorBadValueForParameterCreatePaymentDonation';
126			return -1;
127		}
128
129		// Clean parameters
130		if (isset($this->fk_donation)) 		$this->fk_donation = (int) $this->fk_donation;
131		if (isset($this->amount))			$this->amount = trim($this->amount);
132		if (isset($this->fk_typepayment))   $this->fk_typepayment = trim($this->fk_typepayment);
133		if (isset($this->num_payment))      $this->num_payment    = trim($this->num_payment);
134		if (isset($this->note_public))		$this->note_public = trim($this->note_public);
135		if (isset($this->fk_bank))			$this->fk_bank = (int) $this->fk_bank;
136		if (isset($this->fk_user_creat))	$this->fk_user_creat  = (int) $this->fk_user_creat;
137		if (isset($this->fk_user_modif))	$this->fk_user_modif  = (int) $this->fk_user_modif;
138
139		$totalamount = 0;
140		foreach ($this->amounts as $key => $value)  // How payment is dispatch
141		{
142			$newvalue = price2num($value, 'MT');
143			$this->amounts[$key] = $newvalue;
144			$totalamount += $newvalue;
145		}
146		$totalamount = price2num($totalamount);
147
148		// Check parameters
149		if ($totalamount == 0) return -1; // On accepte les montants negatifs pour les rejets de prelevement mais pas null
150
151
152		$this->db->begin();
153
154		if ($totalamount != 0)
155		{
156			$sql = "INSERT INTO ".MAIN_DB_PREFIX."payment_donation (fk_donation, datec, datep, amount,";
157			$sql .= " fk_typepayment, num_payment, note, fk_user_creat, fk_bank)";
158			$sql .= " VALUES ($this->chid, '".$this->db->idate($now)."',";
159			$sql .= " '".$this->db->idate($this->datepaid)."',";
160			$sql .= " ".$totalamount.",";
161			$sql .= " ".$this->paymenttype.", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note_public)."', ".$user->id.",";
162			$sql .= " 0)";
163
164			dol_syslog(get_class($this)."::create", LOG_DEBUG);
165			$resql = $this->db->query($sql);
166			if ($resql)
167			{
168				$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."payment_donation");
169				$this->ref = $this->id;
170			} else {
171				$error++;
172			}
173		}
174
175		if (!$error && !$notrigger)
176		{
177			// Call triggers
178			$result = $this->call_trigger('DONATION_PAYMENT_CREATE', $user);
179			if ($result < 0) { $error++; }
180			// End call triggers
181		}
182
183		if ($totalamount != 0 && !$error)
184		{
185			$this->amount = $totalamount;
186			$this->total = $totalamount; // deprecated
187			$this->db->commit();
188			return $this->id;
189		} else {
190			$this->error = $this->db->error();
191			$this->db->rollback();
192			return -1;
193		}
194	}
195
196	/**
197	 *  Load object in memory from database
198	 *
199	 *  @param	int		$id         Id object
200	 *  @return int         		<0 if KO, >0 if OK
201	 */
202	public function fetch($id)
203	{
204		global $langs;
205		$sql = "SELECT";
206		$sql .= " t.rowid,";
207		$sql .= " t.fk_donation,";
208		$sql .= " t.datec,";
209		$sql .= " t.tms,";
210		$sql .= " t.datep,";
211		$sql .= " t.amount,";
212		$sql .= " t.fk_typepayment,";
213		$sql .= " t.num_payment,";
214		$sql .= " t.note as note_public,";
215		$sql .= " t.fk_bank,";
216		$sql .= " t.fk_user_creat,";
217		$sql .= " t.fk_user_modif,";
218		$sql .= " pt.code as type_code, pt.libelle as type_label,";
219		$sql .= ' b.fk_account';
220		$sql .= " FROM ".MAIN_DB_PREFIX."payment_donation as t";
221		$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as pt ON t.fk_typepayment = pt.id";
222		$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON t.fk_bank = b.rowid';
223		$sql .= " WHERE t.rowid = ".$id;
224
225		dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
226		$resql = $this->db->query($sql);
227		if ($resql)
228		{
229			if ($this->db->num_rows($resql))
230			{
231				$obj = $this->db->fetch_object($resql);
232
233				$this->id  = $obj->rowid;
234				$this->ref = $obj->rowid;
235
236				$this->fk_donation    = $obj->fk_donation;
237				$this->datec		  = $this->db->jdate($obj->datec);
238				$this->tms            = $this->db->jdate($obj->tms);
239				$this->datep		  = $this->db->jdate($obj->datep);
240				$this->amount         = $obj->amount;
241				$this->fk_typepayment = $obj->fk_typepayment;
242				$this->num_payment    = $obj->num_payment;
243				$this->note_public    = $obj->note_public;
244				$this->fk_bank        = $obj->fk_bank;
245				$this->fk_user_creat  = $obj->fk_user_creat;
246				$this->fk_user_modif  = $obj->fk_user_modif;
247
248				$this->type_code  = $obj->type_code;
249				$this->type_label = $obj->type_label;
250
251				$this->bank_account = $obj->fk_account;
252				$this->bank_line    = $obj->fk_bank;
253			}
254			$this->db->free($resql);
255
256			return 1;
257		} else {
258			$this->error = "Error ".$this->db->lasterror();
259			return -1;
260		}
261	}
262
263
264	/**
265	 *  Update database
266	 *
267	 *  @param	User	$user        	User that modify
268	 *  @param  int		$notrigger	    0=launch triggers after, 1=disable triggers
269	 *  @return int         			<0 if KO, >0 if OK
270	 */
271	public function update($user, $notrigger = 0)
272	{
273		global $conf, $langs;
274		$error = 0;
275
276		// Clean parameters
277
278		if (isset($this->fk_donation))		$this->fk_donation = (int) $this->fk_donation;
279		if (isset($this->amount))			$this->amount = trim($this->amount);
280		if (isset($this->fk_typepayment))	$this->fk_typepayment = trim($this->fk_typepayment);
281		if (isset($this->num_payment))		$this->num_payment = trim($this->num_payment);
282		if (isset($this->note_public))		$this->note_public = trim($this->note_public);
283		if (isset($this->fk_bank))			$this->fk_bank = (int) $this->fk_bank;
284		if (isset($this->fk_user_creat))	$this->fk_user_creat = (int) $this->fk_user_creat;
285		if (isset($this->fk_user_modif))	$this->fk_user_modif = (int) $this->fk_user_modif;
286
287		// Check parameters
288		// Put here code to add control on parameters values
289
290		// Update request
291		$sql = "UPDATE ".MAIN_DB_PREFIX."payment_donation SET";
292		$sql .= " fk_donation=".(isset($this->fk_donation) ? $this->fk_donation : "null").",";
293		$sql .= " datec=".(dol_strlen($this->datec) != 0 ? "'".$this->db->idate($this->datec)."'" : 'null').",";
294		$sql .= " tms=".(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
295		$sql .= " datep=".(dol_strlen($this->datep) != 0 ? "'".$this->db->idate($this->datep)."'" : 'null').",";
296		$sql .= " amount=".(isset($this->amount) ? $this->amount : "null").",";
297		$sql .= " fk_typepayment=".(isset($this->fk_typepayment) ? $this->fk_typepayment : "null").",";
298		$sql .= " num_payment=".(isset($this->num_payment) ? "'".$this->db->escape($this->num_payment)."'" : "null").",";
299		$sql .= " note=".(isset($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : "null").",";
300		$sql .= " fk_bank=".(isset($this->fk_bank) ? $this->fk_bank : "null").",";
301		$sql .= " fk_user_creat=".(isset($this->fk_user_creat) ? $this->fk_user_creat : "null").",";
302		$sql .= " fk_user_modif=".(isset($this->fk_user_modif) ? $this->fk_user_modif : "null")."";
303		$sql .= " WHERE rowid=".(int) $this->id;
304
305		$this->db->begin();
306
307		dol_syslog(get_class($this)."::update", LOG_DEBUG);
308		$resql = $this->db->query($sql);
309		if (!$resql) {
310			$error++;
311			$this->errors[] = "Error ".$this->db->lasterror();
312		}
313
314		if (!$error)
315		{
316			if (!$notrigger)
317			{
318				if (!$error && !$notrigger)
319				{
320					// Call triggers
321					$result = $this->call_trigger('DONATION_PAYMENT_MODIFY', $user);
322					if ($result < 0) { $error++; }
323					// End call triggers
324				}
325			}
326		}
327
328		// Commit or rollback
329		if ($error)
330		{
331			foreach ($this->errors as $errmsg)
332			{
333				dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
334				$this->error .= ($this->error ? ', '.$errmsg : $errmsg);
335			}
336			$this->db->rollback();
337			return -1 * $error;
338		} else {
339			$this->db->commit();
340			return 1;
341		}
342	}
343
344
345	/**
346	 *  Delete object in database
347	 *
348	 *  @param	User	$user        	User that delete
349	 *  @param  int		$notrigger		0=launch triggers after, 1=disable triggers
350	 *  @return int						<0 if KO, >0 if OK
351	 */
352	public function delete($user, $notrigger = 0)
353	{
354		global $conf, $langs;
355		$error = 0;
356
357		$this->db->begin();
358
359		if (!$error)
360		{
361			$sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url";
362			$sql .= " WHERE type='payment_donation' AND url_id=".(int) $this->id;
363
364			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
365			$resql = $this->db->query($sql);
366			if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); }
367		}
368
369		if (!$error)
370		{
371			$sql = "DELETE FROM ".MAIN_DB_PREFIX."payment_donation";
372			$sql .= " WHERE rowid=".$this->id;
373
374			dol_syslog(get_class($this)."::delete", LOG_DEBUG);
375			$resql = $this->db->query($sql);
376			if (!$resql) {
377				$error++;
378				$this->errors[] = "Error ".$this->db->lasterror();
379			}
380		}
381
382		if (!$error)
383		{
384			if (!$notrigger)
385			{
386				if (!$error && !$notrigger)
387				{
388					// Call triggers
389					$result = $this->call_trigger('DONATION_PAYMENT_DELETE', $user);
390					if ($result < 0) { $error++; }
391					// End call triggers
392				}
393			}
394		}
395
396		// Commit or rollback
397		if ($error)
398		{
399			foreach ($this->errors as $errmsg)
400			{
401				dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
402				$this->error .= ($this->error ? ', '.$errmsg : $errmsg);
403			}
404			$this->db->rollback();
405			return -1 * $error;
406		} else {
407			$this->db->commit();
408			return 1;
409		}
410	}
411
412
413
414	/**
415	 *	Load an object from its id and create a new one in database
416	 *
417	 *  @param	User	$user		    User making the clone
418	 *	@param	int		$fromid     	Id of object to clone
419	 * 	@return	int						New id of clone
420	 */
421	public function createFromClone(User $user, $fromid)
422	{
423		$error = 0;
424
425		$object = new PaymentDonation($this->db);
426
427		$this->db->begin();
428
429		// Load source object
430		$object->fetch($fromid);
431		$object->id = 0;
432		$object->statut = 0;
433
434		// Clear fields
435		// ...
436
437		// Create clone
438		$object->context['createfromclone'] = 'createfromclone';
439		$result = $object->create($user);
440
441		// Other options
442		if ($result < 0)
443		{
444			$this->error = $object->error;
445			$error++;
446		}
447
448		if (!$error)
449		{
450		}
451
452		unset($object->context['createfromclone']);
453
454		// End
455		if (!$error)
456		{
457			$this->db->commit();
458			return $object->id;
459		} else {
460			$this->db->rollback();
461			return -1;
462		}
463	}
464
465
466	/**
467	 * 	Retourne le libelle du statut d'un don (brouillon, validee, abandonnee, payee)
468	 *
469	 *  @param	int		$mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long
470	 *  @return string        		Libelle
471	 */
472	public function getLibStatut($mode = 0)
473	{
474		return '';
475	}
476
477	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
478	/**
479	 *  Renvoi le libelle d'un statut donne
480	 *
481	 *  @param	int		$status        	Id status
482	 *  @param  int		$mode          	0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
483	 *  @return string 			       	Libelle du statut
484	 */
485	public function LibStatut($status, $mode = 0)
486	{
487		// phpcs:enable
488		global $langs;
489
490		return '';
491	}
492
493
494	/**
495	 *  Initialise an instance with random values.
496	 *  Used to build previews or test instances.
497	 *	id must be 0 if object instance is a specimen.
498	 *
499	 *  @return	void
500	 */
501	public function initAsSpecimen()
502	{
503		$this->id = 0;
504
505		$this->fk_donation = '';
506		$this->datec = '';
507		$this->tms = '';
508		$this->datep = '';
509		$this->amount = '';
510		$this->fk_typepayment = '';
511		$this->num_payment = '';
512		$this->note_public = '';
513		$this->fk_bank = '';
514		$this->fk_user_creat = '';
515		$this->fk_user_modif = '';
516	}
517
518
519	/**
520	 *      Add record into bank for payment with links between this bank record and invoices of payment.
521	 *      All payment properties must have been set first like after a call to create().
522	 *
523	 *      @param	User	$user               Object of user making payment
524	 *      @param  string	$mode               'payment_donation'
525	 *      @param  string	$label              Label to use in bank record
526	 *      @param  int		$accountid          Id of bank account to do link with
527	 *      @param  string	$emetteur_nom       Name of transmitter
528	 *      @param  string	$emetteur_banque    Name of bank
529	 *      @return int                 		<0 if KO, >0 if OK
530	 */
531	public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque)
532	{
533		global $conf;
534
535		$error = 0;
536
537		if (!empty($conf->banque->enabled))
538		{
539			require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php';
540
541			$acc = new Account($this->db);
542			$acc->fetch($accountid);
543
544			$total = $this->total;
545			if ($mode == 'payment_donation') $amount = $total;
546
547			// Insert payment into llx_bank
548			$bank_line_id = $acc->addline(
549				$this->datepaid,
550				$this->paymenttype, // Payment mode id or code ("CHQ or VIR for example")
551				$label,
552				$amount,
553				$this->num_payment,
554				'',
555				$user,
556				$emetteur_nom,
557				$emetteur_banque
558			);
559
560			// Update fk_bank in llx_paiement.
561			// On connait ainsi le paiement qui a genere l'ecriture bancaire
562			if ($bank_line_id > 0)
563			{
564				$result = $this->update_fk_bank($bank_line_id);
565				if ($result <= 0)
566				{
567					$error++;
568					dol_print_error($this->db);
569				}
570
571				// Add link 'payment', 'payment_supplier', 'payment_donation' in bank_url between payment and bank transaction
572				$url = '';
573				if ($mode == 'payment_donation') $url = DOL_URL_ROOT.'/don/payment/card.php?rowid=';
574				if ($url)
575				{
576					$result = $acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode);
577					if ($result <= 0)
578					{
579						$error++;
580						dol_print_error($this->db);
581					}
582				}
583			} else {
584				$this->error = $acc->error;
585				$error++;
586			}
587		}
588
589		if (!$error)
590		{
591			return 1;
592		} else {
593			return -1;
594		}
595	}
596
597
598	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
599	/**
600	 *  Update link between the donation payment and the generated line in llx_bank
601	 *
602	 *  @param	int		$id_bank         Id if bank
603	 *  @return	int			             >0 if OK, <=0 if KO
604	 */
605	public function update_fk_bank($id_bank)
606	{
607		// phpcs:enable
608		$sql = "UPDATE ".MAIN_DB_PREFIX."payment_donation SET fk_bank = ".(int) $id_bank." WHERE rowid = ".(int) $this->id;
609
610		dol_syslog(get_class($this)."::update_fk_bank", LOG_DEBUG);
611		$result = $this->db->query($sql);
612		if ($result)
613		{
614			return 1;
615		} else {
616			$this->error = $this->db->error();
617			return 0;
618		}
619	}
620
621	/**
622	 *  Return clicable name (with picto eventually)
623	 *
624	 *	@param	int		$withpicto		0=No picto, 1=Include picto into link, 2=Only picto
625	 * 	@param	int		$maxlen			Max length
626	 *	@return	string					String with URL
627	 */
628	public function getNomUrl($withpicto = 0, $maxlen = 0)
629	{
630		global $langs;
631
632		$result = '';
633
634		$label = '<u>'.$langs->trans("DonationPayment").'</u>';
635		$label .= '<br>';
636		$label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref;
637
638		if (!empty($this->id))
639		{
640			$link = '<a href="'.DOL_URL_ROOT.'/don/payment/card.php?id='.$this->id.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
641			$linkend = '</a>';
642
643			if ($withpicto) $result .= ($link.img_object($label, 'payment', 'class="classfortooltip"').$linkend.' ');
644			if ($withpicto && $withpicto != 2) $result .= ' ';
645			if ($withpicto != 2) $result .= $link.($maxlen ?dol_trunc($this->ref, $maxlen) : $this->ref).$linkend;
646		}
647
648		return $result;
649	}
650}
651