NEW Support different bank account for several direct debit payments

This commit is contained in:
Laurent Destailleur 2023-02-27 15:58:15 +01:00
parent 14d6c5fbdb
commit 570748ad79
4 changed files with 340 additions and 287 deletions

View File

@ -1,4 +1,6 @@
<?php <?php
use Stripe\BankAccount;
/* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org> /* Copyright (C) 2002-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com> * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
* Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2016 Laurent Destailleur <eldy@users.sourceforge.net>
@ -138,7 +140,7 @@ if (empty($reshook)) {
} }
} }
// Payment with Direct Debit Stripe // Make payment with Direct Debit Stripe
if ($action == 'sepastripepayment' && $usercancreate) { if ($action == 'sepastripepayment' && $usercancreate) {
$result = $object->makeStripeSepaRequest($user, GETPOST('did', 'int'), 'direct-debit', 'facture'); $result = $object->makeStripeSepaRequest($user, GETPOST('did', 'int'), 'direct-debit', 'facture');
if ($result < 0) { if ($result < 0) {
@ -153,7 +155,7 @@ if (empty($reshook)) {
} }
} }
// payments conditions // Set payments conditions
if ($action == 'setconditions' && $usercancreate) { if ($action == 'setconditions' && $usercancreate) {
$object->fetch($id); $object->fetch($id);
$object->cond_reglement_code = 0; // To clean property $object->cond_reglement_code = 0; // To clean property
@ -915,7 +917,7 @@ if ($object->id > 0) {
// Past requests // Past requests
$sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande, pfd.date_traite, pfd.fk_prelevement_bons, pfd.amount,"; $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande, pfd.date_traite, pfd.fk_prelevement_bons, pfd.amount,";
$sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as status,"; $sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as status, pb.fk_bank_account,";
$sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status"; $sql .= " u.rowid as user_id, u.email, u.lastname, u.firstname, u.login, u.statut as user_status";
$sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd";
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid";
@ -929,16 +931,16 @@ if ($object->id > 0) {
$sql .= " AND pfd.type = 'ban'"; $sql .= " AND pfd.type = 'ban'";
$sql .= " ORDER BY pfd.date_demande DESC"; $sql .= " ORDER BY pfd.date_demande DESC";
$result = $db->query($sql); $resql = $db->query($sql);
if ($result) { if ($resql) {
$num = $db->num_rows($result); $num = $db->num_rows($resql);
$numclosed = $num; $numclosed = $num;
$i = 0; $i = 0;
$tmpuser = new User($db); $tmpuser = new User($db);
while ($i < $num) { while ($i < $num) {
$obj = $db->fetch_object($result); $obj = $db->fetch_object($resql);
$tmpuser->id = $obj->user_id; $tmpuser->id = $obj->user_id;
$tmpuser->login = $obj->login; $tmpuser->login = $obj->login;
@ -975,9 +977,26 @@ if ($object->id > 0) {
$withdrawreceipt->date_creation = $db->jdate($obj->datec); $withdrawreceipt->date_creation = $db->jdate($obj->datec);
$withdrawreceipt->statut = $obj->status; $withdrawreceipt->statut = $obj->status;
$withdrawreceipt->status = $obj->status; $withdrawreceipt->status = $obj->status;
$withdrawreceipt->fk_bank_account = $obj->fk_bank_account;
//$withdrawreceipt->credite = $db->jdate($obj->credite); //$withdrawreceipt->credite = $db->jdate($obj->credite);
print $withdrawreceipt->getNomUrl(1); print $withdrawreceipt->getNomUrl(1);
print ' ';
print $withdrawreceipt->getLibStatut(2);
// Show the bank account
$fk_bank_account = $withdrawreceipt->fk_bank_account;
if (empty($fk_bank_account)) {
$fk_bank_account = ($object->type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT);
}
if ($fk_bank_account > 0) {
$bankaccount = new Account($db);
$result = $bankaccount->fetch($fk_bank_account);
if ($result > 0) {
print ' - ';
print $bankaccount->getNomUrl(1);
}
}
} }
print "</td>\n"; print "</td>\n";
@ -995,7 +1014,7 @@ if ($object->id > 0) {
print '<tr class="oddeven"><td colspan="7"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>'; print '<tr class="oddeven"><td colspan="7"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
} }
$db->free($result); $db->free($resql);
} else { } else {
dol_print_error($db); dol_print_error($db);
} }

View File

@ -215,7 +215,8 @@ if ($id > 0 || $ref) {
$result = $acc->fetch($object->fk_bank_account); $result = $acc->fetch($object->fk_bank_account);
} else { // For backward compatibility } else { // For backward compatibility
$acc = new Account($db); $acc = new Account($db);
$result = $acc->fetch(($object->type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT)); $fk_bank_account = ($object->type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT);
$result = $acc->fetch($fk_bank_account);
} }
print '<tr><td class="titlefieldcreate">'; print '<tr><td class="titlefieldcreate">';

View File

@ -92,6 +92,7 @@ class BonPrelevement extends CommonObject
public $user_credit; public $user_credit;
public $type; public $type;
public $fk_bank_account; // The bank the receipt is generated for
const STATUS_DRAFT = 0; const STATUS_DRAFT = 0;
const STATUS_TRANSFERED = 1; const STATUS_TRANSFERED = 1;
@ -299,6 +300,7 @@ class BonPrelevement extends CommonObject
$sql .= ", p.date_credit as date_credit"; $sql .= ", p.date_credit as date_credit";
$sql .= ", p.fk_user_credit"; $sql .= ", p.fk_user_credit";
$sql .= ", p.type"; $sql .= ", p.type";
$sql .= ", p.fk_bank_account";
$sql .= ", p.statut as status"; $sql .= ", p.statut as status";
$sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p";
$sql .= " WHERE p.entity IN (".getEntity('invoice').")"; $sql .= " WHERE p.entity IN (".getEntity('invoice').")";
@ -328,6 +330,7 @@ class BonPrelevement extends CommonObject
$this->user_credit = $obj->fk_user_credit; $this->user_credit = $obj->fk_user_credit;
$this->type = $obj->type; $this->type = $obj->type;
$this->fk_bank_account = $obj->fk_bank_account;
$this->status = $obj->status; $this->status = $obj->status;
$this->statut = $obj->status; // For backward compatibility $this->statut = $obj->status; // For backward compatibility
@ -384,7 +387,11 @@ class BonPrelevement extends CommonObject
$message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour')); $message = $langs->trans("InfoCreditMessage", $this->ref, dol_print_date($date, 'dayhour'));
// Add payment of withdrawal into bank // Add payment of withdrawal into bank
$bankaccount = ($this->type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT); $fk_bank_account = $this->fk_bank_account;
if (empty($fk_bank_account)) {
$fk_bank_account = ($this->type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT);
}
$facs = array(); $facs = array();
$amounts = array(); $amounts = array();
$amountsperthirdparty = array(); $amountsperthirdparty = array();
@ -455,7 +462,7 @@ class BonPrelevement extends CommonObject
$modeforaddpayment = 'payment'; $modeforaddpayment = 'payment';
} }
$result = $paiement->addPaymentToBank($user, $modeforaddpayment, '(WithdrawalPayment)', $bankaccount, '', ''); $result = $paiement->addPaymentToBank($user, $modeforaddpayment, '(WithdrawalPayment)', $fk_bank_account, '', '');
if ($result < 0) { if ($result < 0) {
$error++; $error++;
$this->error = $paiement->error; $this->error = $paiement->error;
@ -750,9 +757,10 @@ class BonPrelevement extends CommonObject
* @param int $notrigger Disable triggers * @param int $notrigger Disable triggers
* @param string $type 'direct-debit' or 'bank-transfer' * @param string $type 'direct-debit' or 'bank-transfer'
* @param int $did ID of an existing payment request. If $did is defined, no entry * @param int $did ID of an existing payment request. If $did is defined, no entry
* @param int $fk_bank_account Bank account ID the receipt is generated for. Will use the ID into the setup of module Direct Debit or Credit Transfer if 0.
* @return int <0 if KO, No of invoice included into file if OK * @return int <0 if KO, No of invoice included into file if OK
*/ */
public function create($banque = 0, $agence = 0, $mode = 'real', $format = 'ALL', $executiondate = '', $notrigger = 0, $type = 'direct-debit', $did = 0) public function create($banque = 0, $agence = 0, $mode = 'real', $format = 'ALL', $executiondate = '', $notrigger = 0, $type = 'direct-debit', $did = 0, $fk_bank_account = 0)
{ {
// phpcs:enable // phpcs:enable
global $conf, $langs, $user; global $conf, $langs, $user;
@ -762,6 +770,7 @@ class BonPrelevement extends CommonObject
require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"; require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php";
require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php"; require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php";
// Check params
if ($type != 'bank-transfer') { if ($type != 'bank-transfer') {
if (empty($format)) { if (empty($format)) {
$this->error = 'ErrorBadParametersForDirectDebitFileCreate'; $this->error = 'ErrorBadParametersForDirectDebitFileCreate';
@ -769,6 +778,11 @@ class BonPrelevement extends CommonObject
} }
} }
// Clean params
if (empty($fk_bank_account)) {
$fk_bank_account = ($type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT);
}
$error = 0; $error = 0;
$datetimeprev = dol_now('gmt'); $datetimeprev = dol_now('gmt');
@ -969,12 +983,13 @@ class BonPrelevement extends CommonObject
// Create withdraw order in database // Create withdraw order in database
$sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons ("; $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons (";
$sql .= "ref, entity, datec, type"; $sql .= "ref, entity, datec, type, fk_bank_account";
$sql .= ") VALUES ("; $sql .= ") VALUES (";
$sql .= "'".$this->db->escape($ref)."'"; $sql .= "'".$this->db->escape($ref)."'";
$sql .= ", ".((int) $conf->entity); $sql .= ", ".((int) $conf->entity);
$sql .= ", '".$this->db->idate($now)."'"; $sql .= ", '".$this->db->idate($now)."'";
$sql .= ", '".($type == 'bank-transfer' ? 'bank-transfer' : 'debit-order')."'"; $sql .= ", '".($type == 'bank-transfer' ? 'bank-transfer' : 'debit-order')."'";
$sql .= ", ".((int) $fk_bank_account);
$sql .= ")"; $sql .= ")";
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
@ -1055,12 +1070,8 @@ class BonPrelevement extends CommonObject
$this->date_echeance = $datetimeprev; $this->date_echeance = $datetimeprev;
$this->reference_remise = $ref; $this->reference_remise = $ref;
$id = $conf->global->PRELEVEMENT_ID_BANKACCOUNT;
if ($type == 'bank-transfer') {
$id = $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT;
}
$account = new Account($this->db); $account = new Account($this->db);
if ($account->fetch($id) > 0) { if ($account->fetch($fk_bank_account) > 0) {
$this->emetteur_code_banque = $account->code_banque; $this->emetteur_code_banque = $account->code_banque;
$this->emetteur_code_guichet = $account->code_guichet; $this->emetteur_code_guichet = $account->code_guichet;
$this->emetteur_numero_compte = $account->number; $this->emetteur_numero_compte = $account->number;
@ -1382,16 +1393,22 @@ class BonPrelevement extends CommonObject
* File is generated with name this->filename * File is generated with name this->filename
* *
* @param string $format FRST, RCUR or ALL * @param string $format FRST, RCUR or ALL
* @param string $executiondate Date to execute transfer * @param int $executiondate Timestamp date to execute transfer
* @param string $type 'direct-debit' or 'bank-transfer' * @param string $type 'direct-debit' or 'bank-transfer'
* @param int $fk_bank_account Bank account ID the receipt is generated for. Will use the ID into the setup of module Direct Debit or Credit Transfer if 0.
* @return int >=0 if OK, <0 if KO * @return int >=0 if OK, <0 if KO
*/ */
public function generate($format = 'ALL', $executiondate = '', $type = 'direct-debit') public function generate($format = 'ALL', $executiondate = 0, $type = 'direct-debit', $fk_bank_account = 0)
{ {
global $conf, $langs, $mysoc; global $conf, $langs, $mysoc;
//TODO: Optimize code to read lines in a single function //TODO: Optimize code to read lines in a single function
// Clean params
if (empty($fk_bank_account)) {
$fk_bank_account = ($type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT);
}
$result = 0; $result = 0;
dol_syslog(get_class($this)."::generate build file=".$this->filename." type=".$type); dol_syslog(get_class($this)."::generate build file=".$this->filename." type=".$type);
@ -1486,7 +1503,7 @@ class BonPrelevement extends CommonObject
// Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf // Define $fileEmetteurSection. Start of bloc PmtInf. Will contains all $nbtotalDrctDbtTxInf
if ($result != -2) { if ($result != -2) {
$fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type); $fileEmetteurSection .= $this->EnregEmetteurSEPA($conf, $date_actu, $nbtotalDrctDbtTxInf, $this->total, $CrLf, $format, $type, $fk_bank_account);
} }
/** /**
@ -2048,24 +2065,29 @@ class BonPrelevement extends CommonObject
* @param string $CrLf End of line character * @param string $CrLf End of line character
* @param string $format FRST or RCUR or ALL * @param string $format FRST or RCUR or ALL
* @param string $type 'direct-debit' or 'bank-transfer' * @param string $type 'direct-debit' or 'bank-transfer'
* @param int $fk_bank_account Bank account ID the receipt is generated for. Will use the ID into the setup of module Direct Debit or Credit Transfer if 0.
* @return string String with SEPA Sender * @return string String with SEPA Sender
* @see EnregEmetteur() * @see EnregEmetteur()
*/ */
public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST', $type = 'direct-debit') public function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf = '\n', $format = 'FRST', $type = 'direct-debit', $fk_bank_account = 0)
{ {
// phpcs:enable // phpcs:enable
// SEPA INITIALISATION // SEPA INITIALISATION
global $conf; global $conf;
// Clean parameters
$dateTime_YMD = dol_print_date($ladate, '%Y%m%d'); $dateTime_YMD = dol_print_date($ladate, '%Y%m%d');
$dateTime_ETAD = dol_print_date($ladate, '%Y-%m-%d'); $dateTime_ETAD = dol_print_date($ladate, '%Y-%m-%d');
$dateTime_YMDHMS = dol_print_date($ladate, '%Y-%m-%dT%H:%M:%S'); $dateTime_YMDHMS = dol_print_date($ladate, '%Y-%m-%dT%H:%M:%S');
// Clean params
if (empty($fk_bank_account)) {
$fk_bank_account = ($type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT);
}
// Get data of bank account // Get data of bank account
//$id = $configuration->global->PRELEVEMENT_ID_BANKACCOUNT;
$id = ($type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT);
$account = new Account($this->db); $account = new Account($this->db);
if ($account->fetch($id) > 0) { if ($account->fetch($fk_bank_account) > 0) {
$this->emetteur_code_banque = $account->code_banque; $this->emetteur_code_banque = $account->code_banque;
$this->emetteur_code_guichet = $account->code_guichet; $this->emetteur_code_guichet = $account->code_guichet;
$this->emetteur_numero_compte = $account->number; $this->emetteur_numero_compte = $account->number;
@ -2081,8 +2103,7 @@ class BonPrelevement extends CommonObject
// Get pending payments // Get pending payments
$sql = "SELECT rowid, ref"; $sql = "SELECT rowid, ref";
$sql .= " FROM"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as pb";
$sql .= " ".MAIN_DB_PREFIX."prelevement_bons as pb";
$sql .= " WHERE pb.rowid = ".((int) $this->id); $sql .= " WHERE pb.rowid = ".((int) $this->id);
$resql = $this->db->query($sql); $resql = $this->db->query($sql);
@ -2296,7 +2317,7 @@ class BonPrelevement extends CommonObject
/** /**
* Return status label of object * Return status label of object
* *
* @param int $mode 0=Label, 1=Picto + label, 2=Picto, 3=Label + Picto * @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
* @return string Label * @return string Label
*/ */
public function getLibStatut($mode = 0) public function getLibStatut($mode = 0)

View File

@ -900,7 +900,7 @@ abstract class CommonInvoice extends CommonObject
dol_syslog(get_class($this)."::makeStripeSepaRequest start", LOG_DEBUG); dol_syslog(get_class($this)."::makeStripeSepaRequest start", LOG_DEBUG);
if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) { if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) {
// Get the default payment mode for BAN payment // Get the default payment mode for BAN payment of the third party
require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
$bac = new CompanyBankAccount($this->db); // table societe_rib $bac = new CompanyBankAccount($this->db); // table societe_rib
$result = $bac->fetch(0, $this->socid, 1, 'ban'); $result = $bac->fetch(0, $this->socid, 1, 'ban');
@ -974,13 +974,22 @@ abstract class CommonInvoice extends CommonObject
$amountstripe = $amountstripe * 100; $amountstripe = $amountstripe * 100;
} }
$fk_bank_account = getDolGlobalInt('STRIPE_BANK_ACCOUNT_FOR_PAYMENTS');
if (!($fk_bank_account > 0)) {
$error++;
$errorforinvoice++;
dol_syslog("Error no bank account defined for Stripe payments", LOG_ERR);
$this->errors[] = "Error bank account for Stripe payments not defined into Stripe module";
}
$this->db->begin(); $this->db->begin();
// Create a prelevement_bon // Create a prelevement_bon
$bon = new BonPrelevement($this->db); $bon = new BonPrelevement($this->db);
if (!$error) {
if (empty($obj->fk_prelevement_bons)) { if (empty($obj->fk_prelevement_bons)) {
// This create record into llx_prelevment_bons and update link with llx_prelevement_demande // This create record into llx_prelevment_bons and update link with llx_prelevement_demande
$nbinvoices = $bon->create(0, 0, 'real', 'ALL', '', 0, 'direct-debit', $did); $nbinvoices = $bon->create(0, 0, 'real', 'ALL', '', 0, 'direct-debit', $did, $fk_bank_account);
if ($nbinvoices <= 0) { if ($nbinvoices <= 0) {
$error++; $error++;
$errorforinvoice++; $errorforinvoice++;
@ -1007,8 +1016,10 @@ abstract class CommonInvoice extends CommonObject
dol_syslog("Error Line already part of a bank payment order", LOG_ERR); dol_syslog("Error Line already part of a bank payment order", LOG_ERR);
$this->errors[] = "The line is already included into a bank payment order. Delete the bank payment order first."; $this->errors[] = "The line is already included into a bank payment order. Delete the bank payment order first.";
} }
}
if (!$error && $amountstripe > 0) { if (!$error) {
if ($amountstripe > 0) {
try { try {
//var_dump($companypaymentmode); //var_dump($companypaymentmode);
dol_syslog("We will try to pay with companypaymentmodeid=" . $companypaymentmode->id . " stripe_card_ref=" . $companypaymentmode->stripe_card_ref . " mode=" . $companypaymentmode->status, LOG_DEBUG); dol_syslog("We will try to pay with companypaymentmodeid=" . $companypaymentmode->id . " stripe_card_ref=" . $companypaymentmode->stripe_card_ref . " mode=" . $companypaymentmode->status, LOG_DEBUG);
@ -1264,6 +1275,7 @@ abstract class CommonInvoice extends CommonObject
dol_syslog("Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?", LOG_WARNING); dol_syslog("Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?", LOG_WARNING);
$this->errors[] = "Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?"; $this->errors[] = "Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?";
} }
}
// Set status of the order to "Transferred" with method 'api' // Set status of the order to "Transferred" with method 'api'
if (!$error && !$errorforinvoice) { if (!$error && !$errorforinvoice) {