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 * @var string Id of external payment mode 97 */ 98 public $ext_payment_id; 99 100 /** 101 * @var string Name of external payment mode 102 */ 103 public $ext_payment_site; 104 105 /** 106 * Constructor 107 * 108 * @param DoliDB $db Database handler 109 */ 110 public function __construct($db) 111 { 112 $this->db = $db; 113 } 114 115 /** 116 * Create payment of donation into database. 117 * Use this->amounts to have list of lines for the payment 118 * 119 * @param User $user User making payment 120 * @param bool $notrigger false=launch triggers after, true=disable triggers 121 * @return int <0 if KO, id of payment if OK 122 */ 123 public function create($user, $notrigger = false) 124 { 125 global $conf, $langs; 126 127 $error = 0; 128 129 $now = dol_now(); 130 131 // Validate parameters 132 if (!$this->datepaid) { 133 $this->error = 'ErrorBadValueForParameterCreatePaymentDonation'; 134 return -1; 135 } 136 137 // Clean parameters 138 if (isset($this->chid)) { 139 $this->chid = (int) $this->chid; 140 } elseif (isset($this->fk_donation)) { 141 // NOTE : The property used in INSERT for fk_donation is not fk_donation but chid 142 // (keep priority to chid property) 143 $this->chid = (int) $this->fk_donation; 144 } 145 if (isset($this->fk_donation)) { 146 $this->fk_donation = (int) $this->fk_donation; 147 } 148 if (isset($this->amount)) { 149 $this->amount = trim($this->amount); 150 } 151 if (isset($this->fk_typepayment)) { 152 $this->fk_typepayment = trim($this->fk_typepayment); 153 } 154 if (isset($this->num_payment)) { 155 $this->num_payment = trim($this->num_payment); 156 } 157 if (isset($this->note_public)) { 158 $this->note_public = trim($this->note_public); 159 } 160 if (isset($this->fk_bank)) { 161 $this->fk_bank = (int) $this->fk_bank; 162 } 163 if (isset($this->fk_user_creat)) { 164 $this->fk_user_creat = (int) $this->fk_user_creat; 165 } 166 if (isset($this->fk_user_modif)) { 167 $this->fk_user_modif = (int) $this->fk_user_modif; 168 } 169 170 $totalamount = 0; 171 foreach ($this->amounts as $key => $value) { // How payment is dispatch 172 $newvalue = price2num($value, 'MT'); 173 $this->amounts[$key] = $newvalue; 174 $totalamount += $newvalue; 175 } 176 $totalamount = price2num($totalamount); 177 178 // Check parameters 179 if ($totalamount == 0) { 180 return -1; // On accepte les montants negatifs pour les rejets de prelevement mais pas null 181 } 182 183 184 $this->db->begin(); 185 186 if ($totalamount != 0) { 187 $sql = "INSERT INTO ".MAIN_DB_PREFIX."payment_donation (fk_donation, datec, datep, amount,"; 188 $sql .= " fk_typepayment, num_payment, note, ext_payment_id, ext_payment_site,"; 189 $sql .= " fk_user_creat, fk_bank)"; 190 $sql .= " VALUES ($this->chid, '".$this->db->idate($now)."',"; 191 $sql .= " '".$this->db->idate($this->datepaid)."',"; 192 $sql .= " ".price2num($totalamount).","; 193 $sql .= " ".((int) $this->paymenttype).", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note_public)."', "; 194 $sql .= " ".($this->ext_payment_id ? "'".$this->db->escape($this->ext_payment_id)."'" : "null").", ".($this->ext_payment_site ? "'".$this->db->escape($this->ext_payment_site)."'" : "null").","; 195 $sql .= " ".$user->id.", 0)"; 196 197 dol_syslog(get_class($this)."::create", LOG_DEBUG); 198 $resql = $this->db->query($sql); 199 if ($resql) { 200 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."payment_donation"); 201 $this->ref = $this->id; 202 } else { 203 $error++; 204 } 205 } 206 207 if (!$error && !$notrigger) { 208 // Call triggers 209 $result = $this->call_trigger('DONATION_PAYMENT_CREATE', $user); 210 if ($result < 0) { 211 $error++; 212 } 213 // End call triggers 214 } 215 216 if ($totalamount != 0 && !$error) { 217 $this->amount = $totalamount; 218 $this->total = $totalamount; // deprecated 219 $this->db->commit(); 220 return $this->id; 221 } else { 222 $this->error = $this->db->error(); 223 $this->db->rollback(); 224 return -1; 225 } 226 } 227 228 /** 229 * Load object in memory from database 230 * 231 * @param int $id Id object 232 * @return int <0 if KO, >0 if OK 233 */ 234 public function fetch($id) 235 { 236 global $langs; 237 $sql = "SELECT"; 238 $sql .= " t.rowid,"; 239 $sql .= " t.fk_donation,"; 240 $sql .= " t.datec,"; 241 $sql .= " t.tms,"; 242 $sql .= " t.datep,"; 243 $sql .= " t.amount,"; 244 $sql .= " t.fk_typepayment,"; 245 $sql .= " t.num_payment,"; 246 $sql .= " t.note as note_public,"; 247 $sql .= " t.fk_bank,"; 248 $sql .= " t.fk_user_creat,"; 249 $sql .= " t.fk_user_modif,"; 250 $sql .= " pt.code as type_code, pt.libelle as type_label,"; 251 $sql .= ' b.fk_account'; 252 $sql .= " FROM ".MAIN_DB_PREFIX."payment_donation as t"; 253 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as pt ON t.fk_typepayment = pt.id"; 254 $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON t.fk_bank = b.rowid'; 255 $sql .= " WHERE t.rowid = ".((int) $id); 256 257 dol_syslog(get_class($this)."::fetch", LOG_DEBUG); 258 $resql = $this->db->query($sql); 259 if ($resql) { 260 if ($this->db->num_rows($resql)) { 261 $obj = $this->db->fetch_object($resql); 262 263 $this->id = $obj->rowid; 264 $this->ref = $obj->rowid; 265 266 $this->fk_donation = $obj->fk_donation; 267 $this->datec = $this->db->jdate($obj->datec); 268 $this->tms = $this->db->jdate($obj->tms); 269 $this->datep = $this->db->jdate($obj->datep); 270 $this->amount = $obj->amount; 271 $this->fk_typepayment = $obj->fk_typepayment; 272 $this->num_payment = $obj->num_payment; 273 $this->note_public = $obj->note_public; 274 $this->fk_bank = $obj->fk_bank; 275 $this->fk_user_creat = $obj->fk_user_creat; 276 $this->fk_user_modif = $obj->fk_user_modif; 277 278 $this->type_code = $obj->type_code; 279 $this->type_label = $obj->type_label; 280 281 $this->bank_account = $obj->fk_account; 282 $this->bank_line = $obj->fk_bank; 283 } 284 $this->db->free($resql); 285 286 return 1; 287 } else { 288 $this->error = "Error ".$this->db->lasterror(); 289 return -1; 290 } 291 } 292 293 294 /** 295 * Update database 296 * 297 * @param User $user User that modify 298 * @param int $notrigger 0=launch triggers after, 1=disable triggers 299 * @return int <0 if KO, >0 if OK 300 */ 301 public function update($user, $notrigger = 0) 302 { 303 global $conf, $langs; 304 $error = 0; 305 306 // Clean parameters 307 308 if (isset($this->fk_donation)) { 309 $this->fk_donation = (int) $this->fk_donation; 310 } 311 if (isset($this->amount)) { 312 $this->amount = trim($this->amount); 313 } 314 if (isset($this->fk_typepayment)) { 315 $this->fk_typepayment = trim($this->fk_typepayment); 316 } 317 if (isset($this->num_payment)) { 318 $this->num_payment = trim($this->num_payment); 319 } 320 if (isset($this->note_public)) { 321 $this->note_public = trim($this->note_public); 322 } 323 if (isset($this->fk_bank)) { 324 $this->fk_bank = (int) $this->fk_bank; 325 } 326 if (isset($this->fk_user_creat)) { 327 $this->fk_user_creat = (int) $this->fk_user_creat; 328 } 329 if (isset($this->fk_user_modif)) { 330 $this->fk_user_modif = (int) $this->fk_user_modif; 331 } 332 333 // Check parameters 334 // Put here code to add control on parameters values 335 336 // Update request 337 $sql = "UPDATE ".MAIN_DB_PREFIX."payment_donation SET"; 338 $sql .= " fk_donation=".(isset($this->fk_donation) ? $this->fk_donation : "null").","; 339 $sql .= " datec=".(dol_strlen($this->datec) != 0 ? "'".$this->db->idate($this->datec)."'" : 'null').","; 340 $sql .= " tms=".(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').","; 341 $sql .= " datep=".(dol_strlen($this->datep) != 0 ? "'".$this->db->idate($this->datep)."'" : 'null').","; 342 $sql .= " amount=".(isset($this->amount) ? $this->amount : "null").","; 343 $sql .= " fk_typepayment=".(isset($this->fk_typepayment) ? $this->fk_typepayment : "null").","; 344 $sql .= " num_payment=".(isset($this->num_payment) ? "'".$this->db->escape($this->num_payment)."'" : "null").","; 345 $sql .= " note=".(isset($this->note_public) ? "'".$this->db->escape($this->note_public)."'" : "null").","; 346 $sql .= " fk_bank=".(isset($this->fk_bank) ? $this->fk_bank : "null").","; 347 $sql .= " fk_user_creat=".(isset($this->fk_user_creat) ? $this->fk_user_creat : "null").","; 348 $sql .= " fk_user_modif=".(isset($this->fk_user_modif) ? $this->fk_user_modif : "null").""; 349 $sql .= " WHERE rowid=".(int) $this->id; 350 351 $this->db->begin(); 352 353 dol_syslog(get_class($this)."::update", LOG_DEBUG); 354 $resql = $this->db->query($sql); 355 if (!$resql) { 356 $error++; 357 $this->errors[] = "Error ".$this->db->lasterror(); 358 } 359 360 if (!$error) { 361 if (!$notrigger) { 362 if (!$error && !$notrigger) { 363 // Call triggers 364 $result = $this->call_trigger('DONATION_PAYMENT_MODIFY', $user); 365 if ($result < 0) { 366 $error++; 367 } 368 // End call triggers 369 } 370 } 371 } 372 373 // Commit or rollback 374 if ($error) { 375 foreach ($this->errors as $errmsg) { 376 dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); 377 $this->error .= ($this->error ? ', '.$errmsg : $errmsg); 378 } 379 $this->db->rollback(); 380 return -1 * $error; 381 } else { 382 $this->db->commit(); 383 return 1; 384 } 385 } 386 387 388 /** 389 * Delete object in database 390 * 391 * @param User $user User that delete 392 * @param int $notrigger 0=launch triggers after, 1=disable triggers 393 * @return int <0 if KO, >0 if OK 394 */ 395 public function delete($user, $notrigger = 0) 396 { 397 global $conf, $langs; 398 $error = 0; 399 400 $this->db->begin(); 401 402 if (!$error) { 403 $sql = "DELETE FROM ".MAIN_DB_PREFIX."bank_url"; 404 $sql .= " WHERE type='payment_donation' AND url_id=".(int) $this->id; 405 406 dol_syslog(get_class($this)."::delete", LOG_DEBUG); 407 $resql = $this->db->query($sql); 408 if (!$resql) { 409 $error++; $this->errors[] = "Error ".$this->db->lasterror(); 410 } 411 } 412 413 if (!$error) { 414 $sql = "DELETE FROM ".MAIN_DB_PREFIX."payment_donation"; 415 $sql .= " WHERE rowid=".((int) $this->id); 416 417 dol_syslog(get_class($this)."::delete", LOG_DEBUG); 418 $resql = $this->db->query($sql); 419 if (!$resql) { 420 $error++; 421 $this->errors[] = "Error ".$this->db->lasterror(); 422 } 423 } 424 425 if (!$error) { 426 if (!$notrigger) { 427 if (!$error && !$notrigger) { 428 // Call triggers 429 $result = $this->call_trigger('DONATION_PAYMENT_DELETE', $user); 430 if ($result < 0) { 431 $error++; 432 } 433 // End call triggers 434 } 435 } 436 } 437 438 // Commit or rollback 439 if ($error) { 440 foreach ($this->errors as $errmsg) { 441 dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); 442 $this->error .= ($this->error ? ', '.$errmsg : $errmsg); 443 } 444 $this->db->rollback(); 445 return -1 * $error; 446 } else { 447 $this->db->commit(); 448 return 1; 449 } 450 } 451 452 453 454 /** 455 * Load an object from its id and create a new one in database 456 * 457 * @param User $user User making the clone 458 * @param int $fromid Id of object to clone 459 * @return int New id of clone 460 */ 461 public function createFromClone(User $user, $fromid) 462 { 463 $error = 0; 464 465 $object = new PaymentDonation($this->db); 466 467 $this->db->begin(); 468 469 // Load source object 470 $object->fetch($fromid); 471 $object->id = 0; 472 $object->statut = 0; 473 474 // Clear fields 475 // ... 476 477 // Create clone 478 $object->context['createfromclone'] = 'createfromclone'; 479 $result = $object->create($user); 480 481 // Other options 482 if ($result < 0) { 483 $this->error = $object->error; 484 $error++; 485 } 486 487 if (!$error) { 488 } 489 490 unset($object->context['createfromclone']); 491 492 // End 493 if (!$error) { 494 $this->db->commit(); 495 return $object->id; 496 } else { 497 $this->db->rollback(); 498 return -1; 499 } 500 } 501 502 503 /** 504 * Retourne le libelle du statut d'un don (brouillon, validee, abandonnee, payee) 505 * 506 * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long 507 * @return string Libelle 508 */ 509 public function getLibStatut($mode = 0) 510 { 511 return ''; 512 } 513 514 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 515 /** 516 * Renvoi le libelle d'un statut donne 517 * 518 * @param int $status Id status 519 * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto 520 * @return string Libelle du statut 521 */ 522 public function LibStatut($status, $mode = 0) 523 { 524 // phpcs:enable 525 global $langs; 526 527 return ''; 528 } 529 530 531 /** 532 * Initialise an instance with random values. 533 * Used to build previews or test instances. 534 * id must be 0 if object instance is a specimen. 535 * 536 * @return void 537 */ 538 public function initAsSpecimen() 539 { 540 $this->id = 0; 541 542 $this->fk_donation = ''; 543 $this->datec = ''; 544 $this->tms = ''; 545 $this->datep = ''; 546 $this->amount = ''; 547 $this->fk_typepayment = ''; 548 $this->num_payment = ''; 549 $this->note_public = ''; 550 $this->fk_bank = ''; 551 $this->fk_user_creat = ''; 552 $this->fk_user_modif = ''; 553 } 554 555 556 /** 557 * Add record into bank for payment with links between this bank record and invoices of payment. 558 * All payment properties must have been set first like after a call to create(). 559 * 560 * @param User $user Object of user making payment 561 * @param string $mode 'payment_donation' 562 * @param string $label Label to use in bank record 563 * @param int $accountid Id of bank account to do link with 564 * @param string $emetteur_nom Name of transmitter 565 * @param string $emetteur_banque Name of bank 566 * @return int <0 if KO, >0 if OK 567 */ 568 public function addPaymentToBank($user, $mode, $label, $accountid, $emetteur_nom, $emetteur_banque) 569 { 570 global $conf; 571 572 $error = 0; 573 574 if (!empty($conf->banque->enabled)) { 575 require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; 576 577 $acc = new Account($this->db); 578 $acc->fetch($accountid); 579 580 $total = $this->total; 581 if ($mode == 'payment_donation') { 582 $amount = $total; 583 } 584 585 // Insert payment into llx_bank 586 $bank_line_id = $acc->addline( 587 $this->datepaid, 588 $this->paymenttype, // Payment mode id or code ("CHQ or VIR for example") 589 $label, 590 $amount, 591 $this->num_payment, 592 '', 593 $user, 594 $emetteur_nom, 595 $emetteur_banque 596 ); 597 598 // Update fk_bank in llx_paiement. 599 // On connait ainsi le paiement qui a genere l'ecriture bancaire 600 if ($bank_line_id > 0) { 601 $result = $this->update_fk_bank($bank_line_id); 602 if ($result <= 0) { 603 $error++; 604 dol_print_error($this->db); 605 } 606 607 // Add link 'payment', 'payment_supplier', 'payment_donation' in bank_url between payment and bank transaction 608 $url = ''; 609 if ($mode == 'payment_donation') { 610 $url = DOL_URL_ROOT.'/don/payment/card.php?rowid='; 611 } 612 if ($url) { 613 $result = $acc->add_url_line($bank_line_id, $this->id, $url, '(paiement)', $mode); 614 if ($result <= 0) { 615 $error++; 616 dol_print_error($this->db); 617 } 618 } 619 } else { 620 $this->error = $acc->error; 621 $error++; 622 } 623 } 624 625 if (!$error) { 626 return 1; 627 } else { 628 return -1; 629 } 630 } 631 632 633 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps 634 /** 635 * Update link between the donation payment and the generated line in llx_bank 636 * 637 * @param int $id_bank Id if bank 638 * @return int >0 if OK, <=0 if KO 639 */ 640 public function update_fk_bank($id_bank) 641 { 642 // phpcs:enable 643 $sql = "UPDATE ".MAIN_DB_PREFIX."payment_donation SET fk_bank = ".(int) $id_bank." WHERE rowid = ".(int) $this->id; 644 645 dol_syslog(get_class($this)."::update_fk_bank", LOG_DEBUG); 646 $result = $this->db->query($sql); 647 if ($result) { 648 return 1; 649 } else { 650 $this->error = $this->db->error(); 651 return 0; 652 } 653 } 654 655 /** 656 * Return clicable name (with picto eventually) 657 * 658 * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto 659 * @param int $maxlen Max length 660 * @return string String with URL 661 */ 662 public function getNomUrl($withpicto = 0, $maxlen = 0) 663 { 664 global $langs; 665 666 $result = ''; 667 668 $label = '<u>'.$langs->trans("DonationPayment").'</u>'; 669 $label .= '<br>'; 670 $label .= '<b>'.$langs->trans('Ref').':</b> '.$this->ref; 671 672 if (!empty($this->id)) { 673 $link = '<a href="'.DOL_URL_ROOT.'/don/payment/card.php?id='.$this->id.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; 674 $linkend = '</a>'; 675 676 if ($withpicto) { 677 $result .= ($link.img_object($label, 'payment', 'class="classfortooltip"').$linkend.' '); 678 } 679 if ($withpicto && $withpicto != 2) { 680 $result .= ' '; 681 } 682 if ($withpicto != 2) { 683 $result .= $link.($maxlen ?dol_trunc($this->ref, $maxlen) : $this->ref).$linkend; 684 } 685 } 686 687 return $result; 688 } 689} 690