Add : register donation payment when public payment

- When we paid a donation whit public link, create the associated payment and
  put its status to payed if all the promised amount is it.

- Set the amount to pay on public page depending to the rest to pay for
  the don.
This commit is contained in:
Indelog 2021-04-22 14:48:05 +02:00
parent 891de3350f
commit eb52f5daa0
6 changed files with 177 additions and 8 deletions

View File

@ -7,6 +7,7 @@
* Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2019 Thibault FOUCART <support@ptibogxiv.net>
* Copyright (C) 2019-2020 Frédéric France <frederic.france@netlogic.fr>
* Copyright (C) 2021 Maxime DEMAREST <maxime@indelog.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -1098,4 +1099,33 @@ class Don extends CommonObject
return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
}
/**
* Function to get reamain to pay for a donation
*
* @return int <0 if KO, > reamain to pay if OK
*/
public function getRemainToPay()
{
dol_syslog(__METHOD__, LOG_DEBUG);
if (empty($this->id))
{
$this->error = 'Missing object id';
$this->errors[] = $this->error;
dol_syslog(__METHOD__.' : '.$this->error, LOG_ERR);
return -1;
}
$sql = 'SELECT SUM(amount) as sum_amount FROM '.MAIN_DB_PREFIX.'payment_donation WHERE fk_donation = '.$this->id;
$resql = $this->db->query($sql);
if (!$resql) {
dol_print_error($this->db);
return -2;
} else {
$sum_amount = (float) $this->db->fetch_object($resql)->sum_amount;
return (float) $this->amount - $sum_amount;
}
}
}

View File

@ -92,6 +92,15 @@ class PaymentDonation extends CommonObject
public $type_code;
public $type_label;
/**
* @var string Id of external payment mode
*/
public $ext_payment_id;
/**
* @var string Name of external payment mode
*/
public $ext_payment_site;
/**
* Constructor
@ -126,6 +135,14 @@ class PaymentDonation extends CommonObject
}
// Clean parameters
if (isset($this->chid)) {
$this->chid = (int) $this->chid;
}
// NOTE : The property used in INSERT for fk_donation is not fk_donation but chid
// (keep priority to chid property)
elseif (isset($this->fk_donation)) {
$this->chid = (int) $this->fk_donation;
}
if (isset($this->fk_donation)) {
$this->fk_donation = (int) $this->fk_donation;
}
@ -169,12 +186,14 @@ class PaymentDonation extends CommonObject
if ($totalamount != 0) {
$sql = "INSERT INTO ".MAIN_DB_PREFIX."payment_donation (fk_donation, datec, datep, amount,";
$sql .= " fk_typepayment, num_payment, note, fk_user_creat, fk_bank)";
$sql .= " fk_typepayment, num_payment, note, ext_payment_id, ext_payment_site,";
$sql .= " fk_user_creat, fk_bank)";
$sql .= " VALUES ($this->chid, '".$this->db->idate($now)."',";
$sql .= " '".$this->db->idate($this->datepaid)."',";
$sql .= " ".$totalamount.",";
$sql .= " ".$this->paymenttype.", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note_public)."', ".$user->id.",";
$sql .= " 0)";
$sql .= " ".$this->paymenttype.", '".$this->db->escape($this->num_payment)."', '".$this->db->escape($this->note_public)."', ";
$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").",";
$sql .= " ".$user->id.", 0)";
dol_syslog(get_class($this)."::create", LOG_DEBUG);
$resql = $this->db->query($sql);

View File

@ -431,6 +431,10 @@ ALTER TABLE llx_facture_fourn ADD COLUMN fk_user_closing integer DEFAULT NULL af
ALTER TABLE llx_entrepot ADD COLUMN fk_project INTEGER DEFAULT NULL AFTER entity; -- project associated to warehouse if any
-- Add external payement suport for donation
ALTER TABLE llx_payment_donation ADD COLUMN ext_payment_site varchar(128) AFTER note;
ALTER TABLE llx_payment_donation ADD COLUMN ext_payment_id varchar(128) AFTER note;
-- Rebuild sequence for postgres only after query INSERT INTO llx_salary(rowid, ...
-- VPGSQL8.2 SELECT dol_util_rebuild_sequences();

View File

@ -20,14 +20,16 @@ create table llx_payment_donation
(
rowid integer AUTO_INCREMENT PRIMARY KEY,
fk_donation integer,
datec datetime, -- date de creation
datec datetime, -- date de creation
tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
datep datetime, -- payment date
datep datetime, -- payment date
amount double(24,8) DEFAULT 0,
fk_typepayment integer NOT NULL,
num_payment varchar(50),
note text,
ext_payment_id varchar(128), -- external id of payment (for example Stripe charge id)
ext_payment_site varchar(128), -- name of external paymentmode (for example 'stripe')
fk_bank integer NOT NULL,
fk_user_creat integer, -- creation user
fk_user_modif integer -- last modification user
fk_user_creat integer, -- creation user
fk_user_modif integer -- last modification user
)ENGINE=innodb;

View File

@ -1587,9 +1587,10 @@ if ($source == 'donation') {
$object = $don;
if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment
$amount = $subscription->total_ttc;
if (GETPOST("amount", 'alpha')) {
$amount = GETPOST("amount", 'alpha');
} else {
$amount = $don->getRemainToPay();
}
$amount = price2num($amount);
}

View File

@ -3,6 +3,7 @@
* Copyright (C) 2006-2013 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2021 Waël Almoman <info@almoman.com>
* Copyright (C) 2021 Maxime Demarest <maxime@indelog.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -776,6 +777,117 @@ if ($ispaymentok) {
$postactionmessages[] = 'Invoice paid '.$tmptag['INV'].' was not found';
$ispostactionok = -1;
}
} elseif (array_key_exists('DON', $tmptag) && $tmptag['DON'] > 0) {
include_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
$don = new Don($db);
$result = $don->fetch($tmptag['DON']);
if ($result) {
$FinalPaymentAmt = $_SESSION["FinalPaymentAmt"];
$paymentTypeId = 0;
if ($paymentmethod == 'paybox') {
$paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS;
}
if ($paymentmethod == 'paypal') {
$paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS;
}
if ($paymentmethod == 'stripe') {
$paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS;
}
if (empty($paymentTypeId)) {
$paymentType = $_SESSION["paymentType"];
if (empty($paymentType)) {
$paymentType = 'CB';
}
$paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1);
}
$currencyCodeType = $_SESSION['currencyCodeType'];
// Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time)
if (!empty($FinalPaymentAmt) && $paymentTypeId > 0) {
$db->begin();
// Creation of paiement line for donation
include_once DOL_DOCUMENT_ROOT.'/don/class/paymentdonation.class.php';
$paiement = new PaymentDonation($db);
if ($currencyCodeType == $conf->currency) {
$paiement->amounts = array($object->id => $FinalPaymentAmt); // Array with all payments dispatching with donation
} else {
// PaymentDonation does not support multi currency
$postactionmessages[] = 'Payment donation can\'t be payed with diffent currency than '.$conf->currency;
$ispostactionok = -1;
$error++; // Not yet supported
}
$paiement->fk_donation = $don->id;
$paiement->datepaid = $now;
$paiement->paymenttype = $paymentTypeId;
$paiement->num_payment = '';
$paiement->note_public = 'Online payment '.dol_print_date($now, 'standard').' from '.$ipaddress;
$paiement->ext_payment_id = $TRANSACTIONID;
$paiement->ext_payment_site = $service;
if (!$error) {
$paiement_id = $paiement->create($user, 1);
if ($paiement_id < 0) {
$postactionmessages[] = $paiement->error.' '.join("<br>\n", $paiement->errors);
$ispostactionok = -1;
$error++;
} else {
$postactionmessages[] = 'Payment created';
$ispostactionok = 1;
if ($totalpayed >= $don->getRemainToPay()) $don->setPaid($don->id);
}
}
if (!$error && !empty($conf->banque->enabled)) {
$bankaccountid = 0;
if ($paymentmethod == 'paybox') {
$bankaccountid = $conf->global->PAYBOX_BANK_ACCOUNT_FOR_PAYMENTS;
} elseif ($paymentmethod == 'paypal') {
$bankaccountid = $conf->global->PAYPAL_BANK_ACCOUNT_FOR_PAYMENTS;
} elseif ($paymentmethod == 'stripe') {
$bankaccountid = $conf->global->STRIPE_BANK_ACCOUNT_FOR_PAYMENTS;
}
if ($bankaccountid > 0) {
$result = $paiement->addPaymentToBank($user, 'payment_donation', '(DonationPayment)', $bankaccountid, '', '');
if ($result < 0) {
$postactionmessages[] = $paiement->error.' '.join("<br>\n", $paiement->errors);
$ispostactionok = -1;
$error++;
} else {
$postactionmessages[] = 'Bank transaction of payment created';
$ispostactionok = 1;
}
} else {
$postactionmessages[] = 'Setup of bank account to use in module '.$paymentmethod.' was not set. No way to record the payment.';
$ispostactionok = -1;
$error++;
}
}
if (!$error) {
$db->commit();
} else {
$db->rollback();
}
} else {
$postactionmessages[] = 'Failed to get a valid value for "amount paid" ('.$FinalPaymentAmt.') or "payment type" ('.$paymentType.') to record the payment of donation '.$tmptag['DON'].'. May be payment was already recorded.';
$ispostactionok = -1;
}
} else {
$postactionmessages[] = 'Donation paid '.$tmptag['DON'].' was not found';
$ispostactionok = -1;
}
// TODO send email with acknowledgment for the donation
// (need that the donation module can gen a pdf document for the cerfa with pre filled content)
} else {
// Nothing done
}
@ -903,6 +1015,7 @@ if ($ispaymentok) {
$content .= "ErrorSeverityCode = ".$ErrorSeverityCode."<br>\n";
}
$ishtml = dol_textishtml($content); // May contain urls
require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';