diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index 884d19a221b..782e16ec71b 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -325,7 +325,7 @@ if ($object->id > 0) { $sql .= " WHERE fk_facture = ".((int) $object->id); } $sql .= " AND pfd.traite = 0"; - $sql .= " AND pfd.ext_payment_id IS NULL"; + $sql .= " AND pfd.type = 'ban'"; $sql .= " ORDER BY pfd.date_demande DESC"; $resql = $db->query($sql); @@ -700,7 +700,7 @@ if ($object->id > 0) { $sql .= " WHERE fk_facture = ".((int) $object->id); } $sql .= " AND pfd.traite = 0"; - $sql .= " AND pfd.ext_payment_id IS NULL"; + $sql .= " AND pfd.type = 'ban'"; $resql = $db->query($sql); if ($resql) { @@ -817,7 +817,8 @@ if ($object->id > 0) { print ''; $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande,"; - $sql .= " pfd.date_traite as date_traite, pfd.amount,"; + $sql .= " pfd.date_traite as date_traite, pfd.amount, pfd.fk_prelevement_bons,"; + $sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as 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 .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; @@ -828,7 +829,7 @@ if ($object->id > 0) { $sql .= " WHERE fk_facture = ".((int) $object->id); } $sql .= " AND pfd.traite = 0"; - $sql .= " AND pfd.ext_payment_id IS NULL"; + $sql .= " AND pfd.type = 'ban'"; $sql .= " ORDER BY pfd.date_demande DESC"; $resql = $db->query($sql); @@ -868,19 +869,36 @@ if ($object->id > 0) { print ''.$langs->trans("OrderWaiting").''; // Link to make payment now - print ''; + print ''; + if ($obj->fk_prelevement_bons > 0) { + $withdrawreceipt = new BonPrelevement($db); + $withdrawreceipt->id = $obj->fk_prelevement_bons; + $withdrawreceipt->ref = $obj->ref; + $withdrawreceipt->date_trans = $db->jdate($obj->date_trans); + $withdrawreceipt->date_credit = $db->jdate($obj->date_credit); + $withdrawreceipt->date_creation = $db->jdate($obj->datec); + $withdrawreceipt->statut = $obj->status; + $withdrawreceipt->status = $obj->status; + //$withdrawreceipt->credite = $db->jdate($obj->credite); + + print $withdrawreceipt->getNomUrl(1); + } + if (!empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) { $langs->load("stripe"); + if ($obj->fk_prelevement_bons > 0) { + print '   '; + } print 'rowid.'&id='.$object->id.'&type='.urlencode($type).'">'.img_picto('', 'stripe', 'class="pictofixedwidth"').$langs->trans("RequestDirectDebitWithStripe").''; } print ''; // - print '-'; + print '-'; // Actions print ''; - print ''; + print ''; print img_delete(); print ''; @@ -897,7 +915,7 @@ if ($object->id > 0) { // Past requests $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande, pfd.date_traite, pfd.fk_prelevement_bons, pfd.amount,"; - $sql .= " pb.ref,"; + $sql .= " pb.ref, pb.date_trans, pb.method_trans, pb.credite, pb.date_credit, pb.datec, pb.statut as 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 .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on pfd.fk_user_demande = u.rowid"; @@ -908,7 +926,7 @@ if ($object->id > 0) { $sql .= " WHERE fk_facture = ".((int) $object->id); } $sql .= " AND pfd.traite = 1"; - $sql .= " AND pfd.ext_payment_id IS NULL"; + $sql .= " AND pfd.type = 'ban'"; $sql .= " ORDER BY pfd.date_demande DESC"; $result = $db->query($sql); @@ -944,7 +962,7 @@ if ($object->id > 0) { print ''.price($obj->amount).''; // Date process - print ''.dol_print_date($db->jdate($obj->date_traite), 'day')."\n"; + print ''.dol_print_date($db->jdate($obj->date_traite), 'dayhour', 'tzuserrel')."\n"; // Link to payment request done print ''; @@ -952,6 +970,13 @@ if ($object->id > 0) { $withdrawreceipt = new BonPrelevement($db); $withdrawreceipt->id = $obj->fk_prelevement_bons; $withdrawreceipt->ref = $obj->ref; + $withdrawreceipt->date_trans = $db->jdate($obj->date_trans); + $withdrawreceipt->date_credit = $db->jdate($obj->date_credit); + $withdrawreceipt->date_creation = $db->jdate($obj->datec); + $withdrawreceipt->statut = $obj->status; + $withdrawreceipt->status = $obj->status; + //$withdrawreceipt->credite = $db->jdate($obj->credite); + print $withdrawreceipt->getNomUrl(1); } print "\n"; diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 0f5546e5e46..70836cb50cf 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -128,9 +128,7 @@ class BonPrelevement extends CommonObject $this->factures = array(); - $this->methodes_trans = array(); - - $this->methodes_trans[0] = "Internet"; + $this->methodes_trans = array(0 => 'Internet', 2 => 'Email', 3 => 'Api'); $this->fetched = 0; } @@ -509,7 +507,7 @@ class BonPrelevement extends CommonObject * * @param User $user id of user * @param int $date date of action - * @param string $method method of transmision to bank + * @param string $method method of transmision to bank (0=Internet, 1=Api...) * @return int >0 if OK, <0 if KO */ public function set_infotrans($user, $date, $method) @@ -737,7 +735,11 @@ class BonPrelevement extends CommonObject // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Create a direct debit order or a credit transfer order + * Create a BAN payment order: + * - Select waiting requests from prelevement_demande (or use $did if provided) + * - Check BAN values + * - Then create a direct debit order or a credit transfer order + * - Link the order with the prelevement_demande lines * TODO delete params banque and agence when not necessary * * @param int $banque dolibarr mysoc bank @@ -747,7 +749,7 @@ class BonPrelevement extends CommonObject * @param string $executiondate Date to execute the transfer * @param int $notrigger Disable triggers * @param string $type 'direct-debit' or 'bank-transfer' - * @param int $did ID of payment request + * @param int $did ID of an existing payment request. If $did is defined, no entry * @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) @@ -755,7 +757,7 @@ class BonPrelevement extends CommonObject // phpcs:enable global $conf, $langs, $user; - dol_syslog(__METHOD__."::Bank=".$banque." Office=".$agence." mode=".$mode." format=".$format, LOG_DEBUG); + dol_syslog(__METHOD__." Bank=".$banque." Office=".$agence." mode=".$mode." format=".$format, LOG_DEBUG); require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"; require_once DOL_DOCUMENT_ROOT."/societe/class/societe.class.php"; @@ -815,7 +817,7 @@ class BonPrelevement extends CommonObject if ($did > 0) { $sql .= " AND pfd.rowid = ".((int) $did); } - dol_syslog(__METHOD__."::Read invoices,", LOG_DEBUG); + dol_syslog(__METHOD__." Read invoices,", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -827,17 +829,17 @@ class BonPrelevement extends CommonObject $factures[$i] = $row; // All fields if ($row[7] == 0) { $error++; - dol_syslog(__METHOD__."::Read invoices error Found a null invoice", LOG_ERR); + dol_syslog(__METHOD__." Read invoices error Found a null invoice", LOG_ERR); $this->invoice_in_error[$row[0]] = "Error for invoice id ".$row[0].", found a null amount"; break; } $i++; } $this->db->free($resql); - dol_syslog(__METHOD__."::Read invoices, ".$i." invoices to withdraw", LOG_DEBUG); + dol_syslog(__METHOD__." Read invoices, ".$i." invoices to withdraw", LOG_DEBUG); } else { $error++; - dol_syslog(__METHOD__."::Read invoices error ".$this->db->error(), LOG_ERR); + dol_syslog(__METHOD__." Read invoices error ".$this->db->error(), LOG_ERR); } } @@ -847,7 +849,7 @@ class BonPrelevement extends CommonObject // Check BAN $i = 0; - dol_syslog(__METHOD__."::Check BAN", LOG_DEBUG); + dol_syslog(__METHOD__." Check BAN", LOG_DEBUG); if (count($factures) > 0) { foreach ($factures as $key => $fac) { @@ -878,19 +880,19 @@ class BonPrelevement extends CommonObject $i++; //dol_syslog(__METHOD__."::RIB is ok", LOG_DEBUG); } else { - dol_syslog(__METHOD__."::Check BAN Error on default bank number IBAN/BIC for thirdparty reported by verif() ".$tmpinvoice->socid." ".$soc->name, LOG_WARNING); + dol_syslog(__METHOD__." Check BAN Error on default bank number IBAN/BIC for thirdparty reported by verif() ".$tmpinvoice->socid." ".$soc->name, LOG_WARNING); $this->invoice_in_error[$fac[0]] = "Error on default bank number IBAN/BIC for invoice ".$tmpinvoice->getNomUrl(0)." for thirdparty ".$soc->getNomUrl(0); $this->thirdparty_in_error[$soc->id] = "Error on default bank number IBAN/BIC for invoice ".$tmpinvoice->getNomUrl(0)." for thirdparty ".$soc->getNomUrl(0); } } else { - dol_syslog(__METHOD__."::Check BAN Failed to read company", LOG_WARNING); + dol_syslog(__METHOD__." Check BAN Failed to read company", LOG_WARNING); } } else { - dol_syslog(__METHOD__."::Check BAN Failed to read invoice", LOG_WARNING); + dol_syslog(__METHOD__." Check BAN Failed to read invoice", LOG_WARNING); } } } else { - dol_syslog(__METHOD__."::Check BAN No invoice to process", LOG_WARNING); + dol_syslog(__METHOD__." Check BAN No invoice to process", LOG_WARNING); } } @@ -934,13 +936,14 @@ class BonPrelevement extends CommonObject if (!$error) { $ref = substr($year, -2).$month; + // Get next free nuber for the ref of bon $sql = "SELECT substring(ref from char_length(ref) - 1)"; // To extract "YYMMXX" from "TYYMMXX" $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons"; $sql .= " WHERE ref LIKE '_".$this->db->escape($ref)."%'"; $sql .= " AND entity = ".((int) $conf->entity); $sql .= " ORDER BY ref DESC LIMIT 1"; - dol_syslog(get_class($this)."::create", LOG_DEBUG); + dol_syslog(get_class($this)." get next free number", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -964,7 +967,7 @@ class BonPrelevement extends CommonObject $this->filename = $dir.'/'.$ref.'.xml'; - // Create withdraw receipt in database + // Create withdraw order in database $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_bons ("; $sql .= "ref, entity, datec, type"; $sql .= ") VALUES ("; @@ -981,11 +984,11 @@ class BonPrelevement extends CommonObject $this->ref = $ref; } else { $error++; - dol_syslog(__METHOD__."::Create withdraw receipt ".$this->db->lasterror(), LOG_ERR); + dol_syslog(__METHOD__." Create withdraw receipt ".$this->db->lasterror(), LOG_ERR); } } else { $error++; - dol_syslog(__METHOD__."::Get last withdraw receipt ".$this->db->lasterror(), LOG_ERR); + dol_syslog(__METHOD__." Get last withdraw receipt ".$this->db->lasterror(), LOG_ERR); } } @@ -996,9 +999,7 @@ class BonPrelevement extends CommonObject $fact = new FactureFournisseur($this->db); } - /* - * Create withdrawal receipt in database - */ + // Add lines for the bon if (count($factures_prev) > 0) { foreach ($factures_prev as $fac) { // Add a link in database for each invoice // Fetch invoice @@ -1009,7 +1010,7 @@ class BonPrelevement extends CommonObject } /* - * Add standing order. This add record into llx_prelevement_lignes + * Add standing order. This add record into llx_prelevement_lignes and llx_prelevement * * $fac[0] : invoice_id * $fac[1] : ??? @@ -1037,7 +1038,7 @@ class BonPrelevement extends CommonObject if (!$resql) { $error++; $this->errors[] = $this->db->lasterror(); - dol_syslog(__METHOD__."::Update Error=".$this->db->lasterror(), LOG_ERR); + dol_syslog(__METHOD__." Update Error=".$this->db->lasterror(), LOG_ERR); } } } @@ -1048,7 +1049,7 @@ class BonPrelevement extends CommonObject * Create file of type='direct-debit' for direct debit order or type='bank-transfer' for credit transfer into a XML file */ - dol_syslog(__METHOD__."::Init direct debit or credit transfer file for ".count($factures_prev)." invoices", LOG_DEBUG); + dol_syslog(__METHOD__." Init direct debit or credit transfer file for ".count($factures_prev)." invoices", LOG_DEBUG); if (count($factures_prev) > 0) { $this->date_echeance = $datetimeprev; @@ -1085,7 +1086,7 @@ class BonPrelevement extends CommonObject $error++; } } - dol_syslog(__METHOD__."::End withdraw receipt, file ".$this->filename, LOG_DEBUG); + dol_syslog(__METHOD__." Bank order file has been generated under filename ".$this->filename, LOG_DEBUG); } //var_dump($this->total);exit; @@ -1101,7 +1102,7 @@ class BonPrelevement extends CommonObject $resql = $this->db->query($sql); if (!$resql) { $error++; - dol_syslog(__METHOD__."::Error update total: ".$this->db->error(), LOG_ERR); + dol_syslog(__METHOD__." Error update total: ".$this->db->error(), LOG_ERR); } } @@ -1226,12 +1227,15 @@ class BonPrelevement extends CommonObject $labeltoshow = 'PaymentByBankTransfer'; } - $label = ''.$langs->trans($labeltoshow).''; + $label = img_picto('', $this->picto).' '.$langs->trans($labeltoshow).' '.$this->getLibStatut(5); $label .= '
'; $label .= ''.$langs->trans('Ref').': '.$this->ref; - if (isset($this->statut)) { - $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + if (isset($this->date_trans)) { + $label .= '
'.$langs->trans("TransData").": ".dol_print_date($this->date_trans, 'dayhour', 'tzuserrel'); } + /*if (isset($this->date_credit)) { + $label .= '
'.$langs->trans("TransData").": ".dol_print_date($this->date_credit, 'dayhour', 'tzuserrel'); + }*/ $url = DOL_URL_ROOT.'/compta/prelevement/card.php?id='.$this->id; if (!empty($this->type) && $this->type == 'bank-transfer') { diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 9786ad65168..677b7c1017a 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -789,7 +789,7 @@ abstract class CommonInvoice extends CommonObject } else { $sql .= " WHERE fk_facture = ".((int) $this->id); } - $sql .= " AND ext_payment_id IS NULL"; // To exclude record done for some online payments + $sql .= " AND type = 'ban'"; // To exclude record done for some online payments $sql .= " AND traite = 0"; dol_syslog(get_class($this)."::demande_prelevement", LOG_DEBUG); @@ -819,7 +819,7 @@ abstract class CommonInvoice extends CommonObject } else { $sql .= 'fk_facture, '; } - $sql .= ' amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib, sourcetype, entity)'; + $sql .= ' amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib, sourcetype, type, entity)'; $sql .= " VALUES (".((int) $this->id); $sql .= ", ".((float) price2num($amount)); $sql .= ", '".$this->db->idate($now)."'"; @@ -829,6 +829,7 @@ abstract class CommonInvoice extends CommonObject $sql .= ", '".$this->db->escape($bac->number)."'"; $sql .= ", '".$this->db->escape($bac->cle_rib)."'"; $sql .= ", '".$this->db->escape($sourcetype)."'"; + $sql .= ", 'ban'"; $sql .= ", ".((int) $conf->entity); $sql .= ")"; @@ -876,11 +877,11 @@ abstract class CommonInvoice extends CommonObject /** - * Create a withdrawal request, from a prelevement_demande, to Stripe for a direct debit order or a credit transfer order. - * Use the remain to pay excluding all existing open direct debit requests. + * Create a payment order for a prelevement_demande + * Then send the payment order to Stripe (for a direct debit order or a credit transfer order). * * @param User $fuser User asking the direct debit transfer - * @param int $did ID of payment request + * @param int $did ID of unitary payment request to pay * @param string $type 'direct-debit' or 'bank-transfer' * @param string $sourcetype Source ('facture' or 'supplier_invoice') * @return int <0 if KO, >0 if OK @@ -896,11 +897,12 @@ abstract class CommonInvoice extends CommonObject $error = 0; - dol_syslog(get_class($this)."::makeStripeSepaRequest 0", LOG_DEBUG); + dol_syslog(get_class($this)."::makeStripeSepaRequest start", LOG_DEBUG); if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) { + // Get the default payment mode for BAN payment require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php'; - $bac = new CompanyBankAccount($this->db); + $bac = new CompanyBankAccount($this->db); // table societe_rib $result = $bac->fetch(0, $this->socid, 1, 'ban'); if ($result <= 0 || empty($bac->id)) { $this->error = $langs->trans("ThirdpartyHasNoDefaultBanAccount"); @@ -909,13 +911,14 @@ abstract class CommonInvoice extends CommonObject return -1; } - $sql = "SELECT rowid, date_demande, amount, fk_facture, fk_facture_fourn"; + // Load the request to process + $sql = "SELECT rowid, date_demande, amount, fk_facture, fk_facture_fourn, fk_prelevement_bons"; $sql .= " FROM ".$this->db->prefix()."prelevement_demande"; $sql .= " WHERE rowid = ".((int) $did); $sql .= " AND fk_facture = ".((int) $this->id); // Add a protection to not pay another invoice than current one $sql .= " AND traite = 0"; // Add a protection to not process twice - dol_syslog(get_class($this)."::makeStripeSepaRequest 1", LOG_DEBUG); + dol_syslog(get_class($this)."::makeStripeSepaRequest load requests to process", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { $obj = $this->db->fetch_object($resql); @@ -924,30 +927,16 @@ abstract class CommonInvoice extends CommonObject return -2; } - // + // amount to pay $amount = $obj->amount; - $now = dol_now(); - - $totalpaye = $this->getSommePaiement(); - $totalcreditnotes = $this->getSumCreditNotesUsed(); - $totaldeposits = $this->getSumDepositsUsed(); - //print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits; - - // We can also use bcadd to avoid pb with floating points - // For example print 239.2 - 229.3 - 9.9; does not return 0. - //$resteapayer=bcadd($this->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); - //$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); - $amounttocheck = price2num($this->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); - - // TODO We can compare $amount and $amounttocheck - if (is_numeric($amount) && $amount != 0) { require_once DOL_DOCUMENT_ROOT.'/societe/class/companypaymentmode.class.php'; - $companypaymentmode = new CompanyPaymentMode($this->db); + $companypaymentmode = new CompanyPaymentMode($this->db); // table societe_rib $companypaymentmode->fetch($bac->id); // Start code for Stripe + // TODO This must come from a parameter ? or the method may not work as expected when used from a batch ? $service = 'StripeTest'; $servicestatus = 0; if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'alpha')) { @@ -955,26 +944,27 @@ abstract class CommonInvoice extends CommonObject $servicestatus = 1; } - dol_syslog("makeStripeSepaRequest amount = ".$amount." service=" . $service . " servicestatus=" . $servicestatus . " thirdparty_id=" . $this->socid . " companypaymentmode=" . $companypaymentmode->id); + dol_syslog("makeStripeSepaRequest amount = ".$amount." service=" . $service . " servicestatus=" . $servicestatus . " thirdparty_id=" . $this->socid." did=".$did); $this->stripechargedone = 0; $this->stripechargeerror = 0; + $now = dol_now(); $currency = $conf->currency; global $stripearrayofkeysbyenv; - global $savstripearrayofkeysbyenv; $errorforinvoice = 0; // We reset the $errorforinvoice at each invoice loop $this->fetch_thirdparty(); - dol_syslog("--- Process invoice thirdparty_id=" . $this->id . ", thirdparty_name=" . $this->thirdparty->name . " id=" . $this->id . ", ref=" . $this->ref . ", datef=" . dol_print_date($this->date, 'dayhourlog'), LOG_DEBUG); + dol_syslog("--- Process payment request thirdparty_id=" . $this->thirdparty->id . ", thirdparty_name=" . $this->thirdparty->name . " ban id=" . $bac->id, LOG_DEBUG); - $alreadypayed = $this->getSommePaiement(); - $amount_credit_notes_included = $this->getSumCreditNotesUsed(); - $amounttopay = $this->total_ttc - $alreadypayed - $amount_credit_notes_included; + //$alreadypayed = $this->getSommePaiement(); + //$amount_credit_notes_included = $this->getSumCreditNotesUsed(); + //$amounttopay = $this->total_ttc - $alreadypayed - $amount_credit_notes_included; + $amounttopay = $amount; // Correct the amount according to unit of currency // See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support @@ -984,7 +974,41 @@ abstract class CommonInvoice extends CommonObject $amountstripe = $amountstripe * 100; } - if ($amountstripe > 0) { + $this->db->begin(); + + // Create a prelevement_bon + $bon = new BonPrelevement($this->db); + if (empty($obj->fk_prelevement_bons)) { + // 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); + if ($nbinvoices <= 0) { + $error++; + $errorforinvoice++; + dol_syslog("Error on BonPrelevement creation", LOG_ERR); + $this->errors[] = "Error on BonPrelevement creation"; + } + /* + if (!$error) { + // Update the direct debit payment request of the processed request to save the id of the prelevement_bon + $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_demande SET"; + $sql .= " fk_prelevement_bons = ".((int) $bon->id); + $sql .= " WHERE rowid = ".((int) $did); + + $result = $this->db->query($sql); + if ($result < 0) { + $error++; + $this->errors[] = "Error on updateing fk_prelevement_bons to ".$bon->id; + } + } + */ + } else { + $error++; + $errorforinvoice++; + 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."; + } + + if (!$error && $amountstripe > 0) { try { //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); @@ -996,94 +1020,26 @@ abstract class CommonInvoice extends CommonObject // So it inits or erases the $stripearrayofkeysbyenv $stripe = new Stripe($this->db); - if (empty($savstripearrayofkeysbyenv)) { - $savstripearrayofkeysbyenv = $stripearrayofkeysbyenv; - } dol_syslog("makeStripeSepaRequest Current Stripe environment is " . $stripearrayofkeysbyenv[$servicestatus]['publishable_key']); - dol_syslog("makeStripeSepaRequest Current Saved Stripe environment is " . $savstripearrayofkeysbyenv[$servicestatus]['publishable_key']); - $foundalternativestripeaccount = ''; - - // Force stripe to another value (by default this value is empty) - if (!empty($thirdparty->array_options['options_stripeaccount'])) { - dol_syslog("makeStripeSepaRequest The thirdparty id=" . $thirdparty->id . " has a dedicated Stripe Account, so we switch to it."); - - $tmparray = explode('@', $thirdparty->array_options['options_stripeaccount']); - if (!empty($tmparray[1])) { - $tmparray2 = explode(':', $tmparray[1]); - if (!empty($tmparray2[3])) { - $stripearrayofkeysbyenv = [ - 0 => [ - "publishable_key" => $tmparray2[0], - "secret_key" => $tmparray2[1] - ], - 1 => [ - "publishable_key" => $tmparray2[2], - "secret_key" => $tmparray2[3] - ] - ]; - - $stripearrayofkeys = $stripearrayofkeysbyenv[$servicestatus]; - \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']); - - $foundalternativestripeaccount = $tmparray[0]; // Store the customer id - - dol_syslog("We use now customer=" . $foundalternativestripeaccount . " publishable_key=" . $stripearrayofkeys['publishable_key'], LOG_DEBUG); - } - } - - if (!$foundalternativestripeaccount) { - $stripearrayofkeysbyenv = $savstripearrayofkeysbyenv; - - $stripearrayofkeys = $savstripearrayofkeysbyenv[$servicestatus]; - \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']); - dol_syslog("We found a bad value for Stripe Account for thirdparty id=" . $thirdparty->id . ", so we ignore it and keep using the global one, so " . $stripearrayofkeys['publishable_key'], LOG_WARNING); - } - } else { - $stripearrayofkeysbyenv = $savstripearrayofkeysbyenv; - - $stripearrayofkeys = $savstripearrayofkeysbyenv[$servicestatus]; - \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']); - dol_syslog("The thirdparty id=" . $thirdparty->id . " has no dedicated Stripe Account, so we use global one, so " . json_encode($stripearrayofkeys), LOG_DEBUG); - } + $stripearrayofkeys = $stripearrayofkeysbyenv[$servicestatus]; + \Stripe\Stripe::setApiKey($stripearrayofkeys['secret_key']); dol_syslog("makeStripeSepaRequest get stripe connet account", LOG_DEBUG); $stripeacc = $stripe->getStripeAccount($service, $this->socid); // Get Stripe OAuth connect account if it exists (no network access here) dol_syslog("makeStripeSepaRequest get stripe connect account return " . json_encode($stripeacc), LOG_DEBUG); - if ($foundalternativestripeaccount) { - if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage - $customer = \Stripe\Customer::retrieve(['id' => "$foundalternativestripeaccount", 'expand[]' => 'sources']); - } else { - $customer = \Stripe\Customer::retrieve(['id' => "$foundalternativestripeaccount", 'expand[]' => 'sources'], ["stripe_account" => $stripeacc]); - } - } else { - $customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 0); - if (empty($customer) && !empty($stripe->error)) { - $this->errors[] = $stripe->error; - } - /*if (!empty($customer) && empty($customer->sources)) { - $customer = null; - $this->errors[] = '\Stripe\Customer::retrieve did not returned the sources'; - }*/ + $customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 0); + if (empty($customer) && !empty($stripe->error)) { + $this->errors[] = $stripe->error; } // $nbhoursbetweentries = (empty($conf->global->SELLYOURSAAS_NBHOURSBETWEENTRIES) ? 49 : $conf->global->SELLYOURSAAS_NBHOURSBETWEENTRIES); // Must have more that 48 hours + 1 between each try (so 1 try every 3 daily batch) // $nbdaysbeforeendoftries = (empty($conf->global->SELLYOURSAAS_NBDAYSBEFOREENDOFTRIES) ? 35 : $conf->global->SELLYOURSAAS_NBDAYSBEFOREENDOFTRIES); - $labeltouse = ''; $postactionmessages = []; if ($resultthirdparty > 0 && !empty($customer)) { - if (!$error && !empty($this->array_options['options_delayautopayment']) && $this->array_options['options_delayautopayment'] > $now && empty($calledinmyaccountcontext)) { - $errmsg = 'Payment try was canceled (invoice qualified by the automatic payment was delayed after the ' . dol_print_date($this->array_options['options_delayautopayment'], 'day') . ')'; - dol_syslog($errmsg, LOG_DEBUG); - - $error++; - $errorforinvoice++; - $this->errors[] = $errmsg; - } - if (!$error) { // Payment was not canceled $sepaMode = false; $stripecard = null; @@ -1096,8 +1052,8 @@ abstract class CommonInvoice extends CommonObject } if ($stripecard) { // Can be src_... (for sepa) or pm_... (new card mode). Note that card_... (old card mode) should not happen here. - $FULLTAG = 'INV=' . $this->id . '-CUS=' . $thirdparty->id; - $description = 'Stripe payment from makeStripeSepaRequest: ' . $FULLTAG . ' ref=' . $this->ref; + $FULLTAG = 'DID='.$did.'-INV=' . $this->id . '-CUS=' . $thirdparty->id; + $description = 'Stripe payment from makeStripeSepaRequest: ' . $FULLTAG . ' did='.$did.' ref=' . $this->ref; $stripefailurecode = ''; $stripefailuremessage = ''; @@ -1107,7 +1063,7 @@ abstract class CommonInvoice extends CommonObject dol_syslog("* Create payment on SEPA " . $stripecard->id . ", amounttopay=" . $amounttopay . ", amountstripe=" . $amountstripe . ", FULLTAG=" . $FULLTAG, LOG_DEBUG); // Create payment intent and charge payment (confirmnow = true) - $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $this, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1); + $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $this, $customer->id, $stripeacc, $servicestatus, 0, 'automatic', true, $stripecard->id, 1, 1, $did); $charge = new stdClass(); @@ -1200,17 +1156,6 @@ abstract class CommonInvoice extends CommonObject $object = $this; - // Send emails - $labeltouse = 'InvoicePaymentSuccess'; - $sendemailtocustomer = 1; - - if (empty($charge) || $charge->status == 'failed') { - $labeltouse = 'InvoicePaymentFailure'; - if ($noemailtocustomeriferror) { - $sendemailtocustomer = 0; - } // $noemailtocustomeriferror is set when error already reported on myaccount screen - } - // Track an event if (empty($charge) || $charge->status == 'failed') { $actioncode = 'PAYMENT_STRIPE_KO'; @@ -1227,12 +1172,6 @@ abstract class CommonInvoice extends CommonObject dol_syslog("No direct debit payment method found for this stripe customer " . $customer->id, LOG_WARNING); $this->errors[] = 'Failed to get direct debit payment method for stripe customer = ' . $customer->id; - $labeltouse = 'InvoicePaymentFailure'; - $sendemailtocustomer = 1; - if ($noemailtocustomeriferror) { - $sendemailtocustomer = 0; - } // $noemailtocustomeriferror is set when error already reported on myaccount screen - $description = 'Failed to find or use the payment mode - no credit card defined for the customer account'; $stripefailurecode = 'BADPAYMENTMODE'; $stripefailuremessage = 'Failed to find or use the payment mode - no credit card defined for the customer account'; @@ -1244,10 +1183,7 @@ abstract class CommonInvoice extends CommonObject $extraparams = ''; } } else { - // If error because payment was canceled for a logical reason, we do nothing (no email and no event added) - $labeltouse = ''; - $sendemailtocustomer = 0; - + // If error because payment was canceled for a logical reason, we do nothing (no event added) $description = ''; $stripefailurecode = ''; $stripefailuremessage = ''; @@ -1268,12 +1204,6 @@ abstract class CommonInvoice extends CommonObject $error++; $errorforinvoice++; - $labeltouse = 'InvoicePaymentFailure'; - $sendemailtocustomer = 1; - if ($noemailtocustomeriferror) { - $sendemailtocustomer = 0; - } // $noemailtocustomeriferror is set when error already reported on myaccount screen - $description = 'Failed to find or use your payment mode (no payment mode for this customer id)'; $stripefailurecode = 'BADPAYMENTMODE'; $stripefailuremessage = 'Failed to find or use your payment mode (no payment mode for this customer id)'; @@ -1285,121 +1215,8 @@ abstract class CommonInvoice extends CommonObject $extraparams = ''; } - /* - // Send email + create action after - if ($sendemailtocustomer && $labeltouse) { - dol_syslog("* Send email with result of payment - " . $labeltouse); - - // Set output language - $outputlangs = new Translate('', $conf); - $outputlangs->setDefaultLang(empty($object->thirdparty->default_lang) ? $mysoc->default_lang : $object->thirdparty->default_lang); - $outputlangs->loadLangs(["main", "members", "bills"]); - - // Get email content from templae - $arraydefaultmessage = null; - - include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; - $formmail = new FormMail($this->db); - - if (!empty($labeltouse)) { - $arraydefaultmessage = $formmail->getEMailTemplate($this->db, 'facture_send', $user, $outputlangs, 0, 1, $labeltouse); - } - - if (!empty($labeltouse) && is_object($arraydefaultmessage) && $arraydefaultmessage->id > 0) { - $subject = $arraydefaultmessage->topic; - $msg = $arraydefaultmessage->content; - } - - $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object); - - //$substitutionarray['__SELLYOURSAAS_PAYMENT_ERROR_DESC__'] = $stripefailurecode . ' ' . $stripefailuremessage; - - complete_substitutions_array($substitutionarray, $outputlangs, $object); - - // Set the property ->ref_customer with ref_customer of contract so __REF_CLIENT__ will be replaced in email content - // Search contract linked to invoice - $foundcontract = null; - $this->fetchObjectLinked(); - if (is_array($this->linkedObjects['contrat']) && count($this->linkedObjects['contrat']) > 0) { - //dol_sort_array($object->linkedObjects['facture'], 'date'); - foreach ($this->linkedObjects['contrat'] as $idcontract => $contract) { - $substitutionarray['__CONTRACT_REF__'] = $contract->ref_customer; - $substitutionarray['__REFCLIENT__'] = $contract->ref_customer; // For backward compatibility - $substitutionarray['__REF_CLIENT__'] = $contract->ref_customer; - $foundcontract = $contract; - break; - } - } - - dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__=' . $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__']); - - //erics - erreur de réécriture de l'url de téléchargement direct de la facture ... le lien de base est le bon - //on cherche donc d'ou vien le pb ... - //$urlforsellyoursaasaccount = getRootUrlForAccount($foundcontract); - // if ($urlforsellyoursaasaccount) { - // $tmpforurl = preg_replace('/.*document.php/', '', $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__']); - // if ($tmpforurl) { - // dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__ cas 1, urlforsellyoursaasaccount=' . $urlforsellyoursaasaccount); - // // $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $urlforsellyoursaasaccount . '/source/document.php' . $tmpforurl; - // } else { - // dol_syslog('__DIRECTDOWNLOAD_URL_INVOICE__ cas 2, urlforsellyoursaasaccount=' . $urlforsellyoursaasaccount); - // // $substitutionarray['__DIRECTDOWNLOAD_URL_INVOICE__'] = $urlforsellyoursaasaccount; - // } - // } - - $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); - $texttosend = make_substitutions($msg, $substitutionarray, $outputlangs); - - // Attach a file ? - $file = ''; - $listofpaths = []; - $listofnames = []; - $listofmimes = []; - if (is_object($invoice)) { - $invoicediroutput = $conf->facture->dir_output; - //erics - choix du PDF a joindre aux mails - $fileparams = dol_most_recent_file($invoicediroutput . '/' . $this->ref, preg_quote($this->ref, '/') . '[^\-]+*.pdf'); - $file = $fileparams['fullname']; - //$file = $invoicediroutput . '/' . $this->ref . '/' . $this->ref . '.pdf'; - // $file = ''; // Disable attachment of invoice in emails - - if ($file) { - $listofpaths = [$file]; - $listofnames = [basename($file)]; - $listofmimes = [dol_mimetype($file)]; - } - } - $from = "";//$conf->global->SELLYOURSAAS_NOREPLY_EMAIL; - - $trackid = 'inv' . $this->id; - $moreinheader = 'X-Dolibarr-Info: makeStripeSepaRequest' . "\r\n"; - - // Send email (substitutionarray must be done just before this) - include_once DOL_DOCUMENT_ROOT . '/core/class/CMailFile.class.php'; - $mailfile = new CMailFile($subjecttosend, $this->thirdparty->email, $from, $texttosend, $listofpaths, $listofmimes, $listofnames, '', '', 0, -1, '', '', $trackid, $moreinheader); - if ($mailfile->sendfile()) { - $result = 1; - } else { - $this->error = $langs->trans("ErrorFailedToSendMail", $from, $this->thirdparty->email) . '. ' . $mailfile->error; - $result = -1; - } - - if ($result < 0) { - $errmsg = $this->error; - $postactionmessages[] = $errmsg; - $ispostactionok = -1; - } else { - if ($file) { - $postactionmessages[] = 'Email sent to thirdparty (to ' . $this->thirdparty->email . ' with invoice document attached: ' . $file . ', language = ' . $outputlangs->defaultlang . ')'; - } else { - $postactionmessages[] = 'Email sent to thirdparty (to ' . $this->thirdparty->email . ' without any attached document, language = ' . $outputlangs->defaultlang . ')'; - } - } - } - */ - if ($description) { - dol_syslog("* Record event for payment result - " . $description); + dol_syslog("* Record event for credit transfer or direct debit request result - " . $description); require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; // Insert record of payment (success or error) @@ -1448,18 +1265,9 @@ abstract class CommonInvoice extends CommonObject $this->errors[] = "Remain to pay is null for the invoice " . $this->id . " " . $this->ref . ". Why is the invoice not classified 'Paid' ?"; } - // TODO Create a prelevement_bon and set its status to sent instead of this - $bon = new BonPrelevement($this->db); - $nbinvoices = $bon->create(0, 0, 'real', 'ALL', '', 0, 'direct-debit', $did); - if ($nbinvoices <= 0) { - $error++; - $errorforinvoice++; - dol_syslog("Error on BonPrelevement creation", LOG_ERR); - $this->errors[] = "Error on BonPrelevement creation"; - } - - if (!$errorforinvoice) { - $result = $bon->set_infotrans($user, $now, 'internet'); + // Set status of the order to "Transferred" with method 'api' + if (!$error && !$errorforinvoice) { + $result = $bon->set_infotrans($user, $now, 3); if ($result < 0) { $error++; $errorforinvoice++; @@ -1468,19 +1276,14 @@ abstract class CommonInvoice extends CommonObject } } - if (!$errorforinvoice) { - $idtransferfile = $bon->id; + if (!$error && !$errorforinvoice) { // Update the direct debit payment request of the processed invoice to save the id of the prelevement_bon $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_demande SET"; - $sql .= " traite = 1,"; // TODO Remove this - $sql .= " date_traite = '".$this->db->idate(dol_now())."',"; // TODO Remove this - if ($idtransferfile > 0) { - $sql .= " fk_prelevement_bons = ".((int) $idtransferfile); - } + $sql .= " ext_payment_id = '".$this->db->escape($paymentintent->id)."',"; + $sql .= " ext_payment_site = '".$this->db->escape($service)."'"; $sql .= " WHERE rowid = ".((int) $did); - - dol_syslog(get_class($this)."::makeStripeSepaRequest", LOG_DEBUG); + dol_syslog(get_class($this)."::makeStripeSepaRequest update to save stripe paymentintent ids", LOG_DEBUG); $resql = $this->db->query($sql); if (!$resql) { $this->error = $this->db->lasterror(); @@ -1488,19 +1291,26 @@ abstract class CommonInvoice extends CommonObject $error++; } } + + if (!$error && !$errorforinvoice) { + $this->db->commit(); + } else { + $this->db->rollback(); + } } else { $this->error = 'WithdrawRequestErrorNilAmount'; dol_syslog(get_class($this).'::makeStripeSepaRequest WithdrawRequestErrorNilAmount'); $error++; } + /* if (!$error) { - // Force payment mode of invoice to withdraw + // Force payment mode of the invoice to withdraw $payment_mode_id = dol_getIdFromCode($this->db, ($type == 'bank-transfer' ? 'VIR' : 'PRE'), 'c_paiement', 'code', 'id', 1); if ($payment_mode_id > 0) { $result = $this->setPaymentMethods($payment_mode_id); } - } + }*/ if ($error) { return -1; diff --git a/htdocs/install/mysql/migration/17.0.0-18.0.0.sql b/htdocs/install/mysql/migration/17.0.0-18.0.0.sql index 522940b62ed..1e5c82672cc 100644 --- a/htdocs/install/mysql/migration/17.0.0-18.0.0.sql +++ b/htdocs/install/mysql/migration/17.0.0-18.0.0.sql @@ -84,3 +84,5 @@ ALTER TABLE llx_supplier_proposal ADD INDEX idx_supplier_proposal_fk_account(fk_ ALTER TABLE llx_ecm_files ADD COLUMN share_pass varchar(32) after share; +ALTER TABLE llx_prelevement_demande ADD COLUMN type varchar(12) DEFAULT ''; +UPDATE llx_prelevement_demande SET type = 'ban' WHERE ext_payment_id IS NULL AND type = ''; diff --git a/htdocs/install/mysql/tables/llx_prelevement_demande.sql b/htdocs/install/mysql/tables/llx_prelevement_demande.sql index b0b1b87f77f..2229b5cc203 100644 --- a/htdocs/install/mysql/tables/llx_prelevement_demande.sql +++ b/htdocs/install/mysql/tables/llx_prelevement_demande.sql @@ -36,6 +36,8 @@ create table llx_prelevement_demande code_guichet varchar(6), number varchar(255), cle_rib varchar(5), + + type varchar(12) DEFAULT '', ext_payment_id varchar(255), ext_payment_site varchar(128) )ENGINE=innodb; diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 81a3d03328a..a194e88627b 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -196,7 +196,6 @@ if ($event->type == 'payout.created') { return -1; } } elseif ($event->type == 'payout.paid') { - global $conf; $error = 0; $result = dolibarr_set_const($db, $service."_NEXTPAYOUT", null, 'chaine', 0, '', $conf->entity); if ($result) { @@ -298,6 +297,8 @@ if ($event->type == 'payout.created') { $db->query($sql); $db->commit(); } elseif ($event->type == 'payment_intent.succeeded') { // Called when making payment with PaymentIntent method ($conf->global->STRIPE_USE_NEW_CHECKOUT is on). + dol_syslog("object = ".var_export($event->data, true)); + // TODO: create fees // TODO: Redirect to paymentok.php diff --git a/htdocs/stripe/class/stripe.class.php b/htdocs/stripe/class/stripe.class.php index 5c49868b8c8..207bbca63b3 100644 --- a/htdocs/stripe/class/stripe.class.php +++ b/htdocs/stripe/class/stripe.class.php @@ -341,9 +341,10 @@ class Stripe extends CommonObject * @param string $payment_method 'pm_....' (if known) * @param string $off_session If we use an already known payment method to pay when customer is not available during the checkout flow. * @param string $noidempotency_key Do not use the idempotency_key when creating the PaymentIntent + * @param int $did ID of an existing line into llx_prelevement_demande (Dolibarr intent). If provided, no new line will be created. * @return \Stripe\PaymentIntent|null Stripe PaymentIntent or null if not found and failed to create */ - public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false, $payment_method = null, $off_session = 0, $noidempotency_key = 1) + public function getPaymentIntent($amount, $currency_code, $tag, $description = '', $object = null, $customer = null, $key = null, $status = 0, $usethirdpartyemailforreceiptemail = 0, $mode = 'automatic', $confirmnow = false, $payment_method = null, $off_session = 0, $noidempotency_key = 1, $did = 0) { global $conf, $user; @@ -530,29 +531,50 @@ class Stripe extends CommonObject // Store the payment intent if (is_object($object)) { $paymentintentalreadyexists = 0; - // Check that payment intent $paymentintent->id is not already recorded. - $sql = "SELECT pi.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pi"; - $sql .= " WHERE pi.entity IN (".getEntity('societe').")"; - $sql .= " AND pi.ext_payment_site = '".$this->db->escape($service)."'"; - $sql .= " AND pi.ext_payment_id = '".$this->db->escape($paymentintent->id)."'"; - dol_syslog(get_class($this)."::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) { - $num = $this->db->num_rows($resql); - if ($num) { - $obj = $this->db->fetch_object($resql); - if ($obj) { - $paymentintentalreadyexists++; - } + if ($did > 0) { + // If a payment request line provided, we do not need to recreate one, we just update it + dol_syslog(get_class($this)."::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG); + + $sql = "UPDATE ".MAIN_DB_PREFIX."prelevement_demande SET"; + $sql .= " ext_payment_site = '".$this->db->escape($service)."',"; + $sql .= " ext_payment_id = '".$this->db->escape($paymentintent->id)."'"; + $sql .= " WHERE rowid = ".((int) $did); + + $resql = $this->db->query($sql); + if ($resql) { + $paymentintentalreadyexists++; + } else { + $error++; + dol_print_error($this->db); } } else { - dol_print_error($this->db); + // Check that payment intent $paymentintent->id is not already recorded. + dol_syslog(get_class($this)."::getPaymentIntent search if payment intent already in prelevement_demande", LOG_DEBUG); + + $sql = "SELECT pi.rowid"; + $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pi"; + $sql .= " WHERE pi.entity IN (".getEntity('societe').")"; + $sql .= " AND pi.ext_payment_site = '".$this->db->escape($service)."'"; + $sql .= " AND pi.ext_payment_id = '".$this->db->escape($paymentintent->id)."'"; + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + if ($num) { + $obj = $this->db->fetch_object($resql); + if ($obj) { + $paymentintentalreadyexists++; + } + } + } else { + $error++; + dol_print_error($this->db); + } } // If not, we create it. - if (!$paymentintentalreadyexists) { + if (!$error && !$paymentintentalreadyexists) { $now = dol_now(); $sql = "INSERT INTO ".MAIN_DB_PREFIX."prelevement_demande (date_demande, fk_user_demande, ext_payment_id, fk_facture, sourcetype, entity, ext_payment_site, amount)"; $sql .= " VALUES ('".$this->db->idate($now)."', ".((int) $user->id).", '".$this->db->escape($paymentintent->id)."', ".((int) $object->id).", '".$this->db->escape($object->element)."', ".((int) $conf->entity).", '".$this->db->escape($service)."', ".((float) $amount).")";