26 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
27 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
107 public $totaldeposits;
108 public $totalcreditnotes;
111 public $sumpayed_multicurrency;
113 public $sumdeposit_multicurrency;
114 public $sumcreditnote;
115 public $sumcreditnote_multicurrency;
133 $remaintopay =
price2num($this->total_ttc - $alreadypaid,
'MT');
134 if ($this->statut == self::STATUS_CLOSED && $this->close_code ==
'discount_vat') {
149 $table =
'paiement_facture';
150 $field =
'fk_facture';
151 if ($this->element ==
'facture_fourn' || $this->element ==
'invoice_supplier') {
152 $table =
'paiementfourn_facturefourn';
153 $field =
'fk_facturefourn';
156 $sql =
"SELECT sum(amount) as amount, sum(multicurrency_amount) as multicurrency_amount";
157 $sql .=
" FROM ".$this->db->prefix().$table;
158 $sql .=
" WHERE ".$field.
" = ".((int) $this->
id);
160 dol_syslog(get_class($this).
"::getSommePaiement", LOG_DEBUG);
162 $resql = $this->db->query(
$sql);
164 $obj = $this->db->fetch_object($resql);
166 $this->db->free($resql);
169 if ($multicurrency < 0) {
170 $this->sumpayed = $obj->amount;
171 $this->sumpayed_multicurrency = $obj->multicurrency_amount;
172 return array(
'alreadypaid'=>(
float) $obj->amount,
'alreadypaid_multicurrency'=>(
float) $obj->multicurrency_amount);
173 } elseif ($multicurrency) {
174 $this->sumpayed_multicurrency = $obj->multicurrency_amount;
175 return (
float) $obj->multicurrency_amount;
177 $this->sumpayed = $obj->amount;
178 return (
float) $obj->amount;
184 $this->error = $this->db->lasterror();
204 require_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
207 $result = $discountstatic->getSumDepositsUsed($this, $multicurrency);
210 if ($multicurrency) {
211 $this->sumdeposit_multicurrency = $result;
213 $this->sumdeposit = $result;
218 $this->error = $discountstatic->error;
231 require_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
234 $result = $discountstatic->getSumCreditNotesUsed($this, $multicurrency);
236 if ($multicurrency) {
237 $this->sumcreditnote_multicurrency = $result;
239 $this->sumcreditnote = $result;
244 $this->error = $discountstatic->error;
257 require_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
260 $result = $discountstatic->getSumFromThisCreditNotesNotUsed($this, $multicurrency);
264 $this->error = $discountstatic->error;
278 $sql =
"SELECT rowid";
279 $sql .=
" FROM ".$this->db->prefix().$this->table_element;
280 $sql .=
" WHERE fk_facture_source = ".((int) $this->
id);
281 $sql .=
" AND type = 2";
282 $resql = $this->db->query(
$sql);
284 $num = $this->db->num_rows($resql);
287 $row = $this->db->fetch_row($resql);
288 $idarray[] = $row[0];
305 $sql =
"SELECT rowid";
306 $sql .=
" FROM ".$this->db->prefix().$this->table_element;
307 $sql .=
" WHERE fk_facture_source = ".((int) $this->
id);
308 $sql .=
" AND type < 2";
309 if ($option ==
'validated') {
310 $sql .=
' AND fk_statut = 1';
317 $sql .=
" ORDER BY fk_statut DESC";
319 $resql = $this->db->query(
$sql);
321 $obj = $this->db->fetch_object($resql);
344 $table =
'paiement_facture';
345 $table2 =
'paiement';
346 $field =
'fk_facture';
347 $field2 =
'fk_paiement';
348 $field3 =
', p.ref_ext';
349 $field4 =
', p.fk_bank';
350 $sharedentity =
'facture';
351 if ($this->element ==
'facture_fourn' || $this->element ==
'invoice_supplier') {
352 $table =
'paiementfourn_facturefourn';
353 $table2 =
'paiementfourn';
354 $field =
'fk_facturefourn';
355 $field2 =
'fk_paiementfourn';
357 $sharedentity =
'facture_fourn';
360 $sql =
"SELECT p.ref, pf.amount, pf.multicurrency_amount, p.fk_paiement, p.datep, p.num_paiement as num, t.code".$field3 . $field4;
361 $sql .=
" FROM ".$this->db->prefix().$table.
" as pf, ".$this->db->prefix().$table2.
" as p, ".$this->db->prefix().
"c_paiement as t";
362 $sql .=
" WHERE pf.".$field.
" = ".((int) $this->
id);
363 $sql .=
" AND pf.".$field2.
" = p.rowid";
364 $sql .=
' AND p.fk_paiement = t.id';
365 $sql .=
' AND p.entity IN ('.getEntity($sharedentity).
')';
367 $sql .=
" AND t.code='PRE'";
370 dol_syslog(get_class($this).
"::getListOfPayments", LOG_DEBUG);
371 $resql = $this->db->query(
$sql);
373 $num = $this->db->num_rows($resql);
376 $obj = $this->db->fetch_object($resql);
377 $tmp = array(
'amount'=>$obj->amount,
'type'=>$obj->code,
'date'=>$obj->datep,
'num'=>$obj->num,
'ref'=>$obj->ref);
378 if (!empty($field3)) {
379 $tmp[
'ref_ext'] = $obj->ref_ext;
381 if (!empty($field4)) {
382 $tmp[
'fk_bank_line'] = $obj->fk_bank;
387 $this->db->free($resql);
391 if ($this->element ==
'facture' || $this->element ==
'invoice') {
392 $sql =
"SELECT rc.amount_ttc as amount, rc.multicurrency_amount_ttc as multicurrency_amount, rc.datec as date, f.ref as ref, rc.description as type";
393 $sql .=
' FROM '.$this->db->prefix().
'societe_remise_except as rc, '.$this->db->prefix().
'facture as f';
394 $sql .=
' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = '.((int) $this->
id);
395 $sql .=
' AND (f.type = 2 OR f.type = 0 OR f.type = 3)';
396 } elseif ($this->element ==
'facture_fourn' || $this->element ==
'invoice_supplier') {
397 $sql =
"SELECT rc.amount_ttc as amount, rc.multicurrency_amount_ttc as multicurrency_amount, rc.datec as date, f.ref as ref, rc.description as type";
398 $sql .=
' FROM '.$this->db->prefix().
'societe_remise_except as rc, '.$this->db->prefix().
'facture_fourn as f';
399 $sql .=
' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = '.((int) $this->
id);
400 $sql .=
' AND (f.type = 2 OR f.type = 0 OR f.type = 3)';
404 $resql = $this->db->query(
$sql);
406 $num = $this->db->num_rows($resql);
409 $obj = $this->db->fetch_object($resql);
410 if ($multicurrency) {
411 $retarray[] = array(
'amount'=>$obj->multicurrency_amount,
'type'=>$obj->type,
'date'=>$obj->date,
'num'=>
'0',
'ref'=>$obj->ref);
413 $retarray[] = array(
'amount'=>$obj->amount,
'type'=>$obj->type,
'date'=>$obj->date,
'num'=>
'',
'ref'=>$obj->ref);
418 $this->error = $this->db->lasterror();
422 $this->db->free($resql);
427 $this->error = $this->db->lasterror();
454 $tmppart = substr($this->
ref, 1, 4);
456 if ($this->statut == self::STATUS_DRAFT && $tmppart ===
'PROV') {
460 if (!empty($conf->global->INVOICE_CAN_NEVER_BE_REMOVED)) {
465 if ($tmppart !==
'PROV') {
467 if ($ventilExportCompta != 0) {
472 if ($this->element !=
'invoice_supplier') {
473 if (empty($this->thirdparty)) {
476 $maxref = $this->getNextNumRef($this->thirdparty,
'last');
480 if (empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED) && $maxref !=
'' && $maxref != $this->ref) {
487 if ($this->situation_cycle_ref && method_exists($this,
'is_last_in_cycle')) {
488 $last = $this->is_last_in_cycle();
497 if (empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED) && $this->getSommePaiement() > 0) {
511 $alreadydispatched = 0;
513 $type =
'customer_invoice';
514 if ($this->element ==
'invoice_supplier') {
515 $type =
'supplier_invoice';
518 $sql =
" SELECT COUNT(ab.rowid) as nb FROM ".$this->db->prefix().
"accounting_bookkeeping as ab WHERE ab.doc_type='".$this->db->escape($type).
"' AND ab.fk_doc = ".((int) $this->
id);
519 $resql = $this->db->query(
$sql);
521 $obj = $this->db->fetch_object($resql);
523 $alreadydispatched = $obj->nb;
526 $this->error = $this->db->lasterror();
530 if ($alreadydispatched) {
547 $labellong =
"Unknown";
549 $labellong =
"InvoiceStandard";
550 $labelshort =
"InvoiceStandardShort";
552 $labellong =
"InvoiceReplacement";
553 $labelshort =
"InvoiceReplacementShort";
555 $labellong =
"InvoiceAvoir";
556 $labelshort =
"CreditNote";
558 $labellong =
"InvoiceDeposit";
559 $labelshort =
"Deposit";
561 $labellong =
"InvoiceProForma";
562 $labelshort =
"ProForma";
564 $labellong =
"InvoiceSituation";
565 $labelshort =
"Situation";
570 $out .=
'<span class="badgeneutral" title="'.dol_escape_htmltag($langs->trans($labellong)).
'">';
572 $out .= $langs->trans($withbadge == 2 ? $labelshort : $labellong);
588 return $this->
LibStatut($this->paye, $this->statut, $mode, $alreadypaid, $this->
type);
602 public function LibStatut($paye, $status, $mode = 0, $alreadypaid = -1, $type = -1)
605 global $langs, $hookmanager;
606 $langs->load(
'bills');
612 $statusType =
'status0';
616 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusDraft');
617 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusDraft');
618 } elseif (($status == 3 || $status == 2) && $alreadypaid <= 0) {
620 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusCanceled');
621 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusCanceled');
623 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusClosedUnpaid');
624 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusClosedUnpaid');
626 $statusType =
'status5';
627 } elseif (($status == 3 || $status == 2) && $alreadypaid > 0) {
628 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusClosedPaidPartially');
629 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusClosedPaidPartially');
630 $statusType =
'status9';
631 } elseif ($alreadypaid == 0) {
632 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusNotPaid');
633 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusNotPaid');
634 $statusType =
'status1';
636 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusStarted');
637 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusStarted');
638 $statusType =
'status3';
641 $statusType =
'status6';
643 if ($type == self::TYPE_CREDIT_NOTE) {
644 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusPaidBackOrConverted');
645 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusPaidBackOrConverted');
646 } elseif ($type == self::TYPE_DEPOSIT) {
647 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusConverted');
648 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusConverted');
650 $labelStatus = $langs->transnoentitiesnoconv(
'BillStatusPaid');
651 $labelStatusShort = $langs->transnoentitiesnoconv(
'Bill'.$prefix.
'StatusPaid');
659 'alreadypaid' => $alreadypaid,
663 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
666 return $hookmanager->resPrint;
671 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode);
685 if (!$cond_reglement) {
686 $cond_reglement = $this->cond_reglement_code;
688 if (!$cond_reglement) {
689 $cond_reglement = $this->cond_reglement_id;
691 if (!$cond_reglement) {
699 $sqltemp =
"SELECT c.type_cdr, c.nbjour, c.decalage";
700 $sqltemp .=
" FROM ".$this->db->prefix().
"c_payment_term as c";
701 if (is_numeric($cond_reglement)) {
702 $sqltemp .=
" WHERE c.rowid=".((int) $cond_reglement);
704 $sqltemp .=
" WHERE c.entity IN (".getEntity(
'c_payment_term').
")";
705 $sqltemp .=
" AND c.code = '".$this->db->escape($cond_reglement).
"'";
708 dol_syslog(get_class($this).
'::calculate_date_lim_reglement', LOG_DEBUG);
709 $resqltemp = $this->db->query($sqltemp);
711 if ($this->db->num_rows($resqltemp)) {
712 $obj = $this->db->fetch_object($resqltemp);
713 $cdr_nbjour = $obj->nbjour;
714 $cdr_type = $obj->type_cdr;
715 $cdr_decalage = $obj->decalage;
718 $this->error = $this->db->error();
721 $this->db->free($resqltemp);
726 if ($cdr_type == 0) {
727 $datelim = $this->date + ($cdr_nbjour * 3600 * 24);
729 $datelim += ($cdr_decalage * 3600 * 24);
730 } elseif ($cdr_type == 1) {
732 $datelim = $this->date + ($cdr_nbjour * 3600 * 24);
734 $mois = date(
'm', $datelim);
735 $annee = date(
'Y', $datelim);
743 $datelim =
dol_mktime(12, 0, 0, $mois, 1, $annee);
744 $datelim -= (3600 * 24);
746 $datelim += ($cdr_decalage * 3600 * 24);
747 } elseif ($cdr_type == 2 && !empty($cdr_decalage)) {
749 include_once DOL_DOCUMENT_ROOT.
'/core/lib/date.lib.php';
750 $datelim = $this->date + ($cdr_nbjour * 3600 * 24);
752 $date_piece =
dol_mktime(0, 0, 0, date(
'm', $datelim), date(
'd', $datelim), date(
'Y', $datelim));
753 $date_lim_current =
dol_mktime(0, 0, 0, date(
'm', $datelim), $cdr_decalage, date(
'Y', $datelim));
756 $diff = $date_piece - $date_lim_current;
759 $datelim = $date_lim_current;
761 $datelim = $date_lim_next;
764 return 'Bad value for type_cdr in database for record cond_reglement = '.$cond_reglement;
788 dol_syslog(get_class($this).
"::demande_prelevement", LOG_DEBUG);
790 if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) {
791 require_once DOL_DOCUMENT_ROOT.
'/societe/class/companybankaccount.class.php';
793 $bac->fetch(0, $this->socid);
795 $sql =
"SELECT count(*)";
796 $sql .=
" FROM ".$this->db->prefix().
"prelevement_demande";
797 if ($type ==
'bank-transfer') {
798 $sql .=
" WHERE fk_facture_fourn = ".((int) $this->
id);
800 $sql .=
" WHERE fk_facture = ".((int) $this->
id);
802 $sql .=
" AND type = 'ban'";
803 $sql .=
" AND traite = 0";
805 dol_syslog(get_class($this).
"::demande_prelevement", LOG_DEBUG);
806 $resql = $this->db->query(
$sql);
808 $row = $this->db->fetch_row($resql);
821 if (empty($amount)) {
822 $amount =
price2num($this->total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits,
'MT');
825 if (is_numeric($amount) && $amount != 0) {
826 $sql =
'INSERT INTO '.$this->db->prefix().
'prelevement_demande(';
827 if ($type ==
'bank-transfer') {
828 $sql .=
'fk_facture_fourn, ';
830 $sql .=
'fk_facture, ';
832 $sql .=
' amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib, sourcetype, type, entity)';
833 $sql .=
" VALUES (".((int) $this->
id);
835 $sql .=
", '".$this->db->idate($now).
"'";
836 $sql .=
", ".((int) $fuser->id);
837 $sql .=
", '".$this->db->escape($bac->code_banque).
"'";
838 $sql .=
", '".$this->db->escape($bac->code_guichet).
"'";
839 $sql .=
", '".$this->db->escape($bac->number).
"'";
840 $sql .=
", '".$this->db->escape($bac->cle_rib).
"'";
841 $sql .=
", '".$this->db->escape($sourcetype).
"'";
843 $sql .=
", ".((int) $conf->entity);
846 dol_syslog(get_class($this).
"::demande_prelevement", LOG_DEBUG);
847 $resql = $this->db->query(
$sql);
849 $this->error = $this->db->lasterror();
850 dol_syslog(get_class($this).
'::demandeprelevement Erreur');
854 $this->error =
'WithdrawRequestErrorNilAmount';
855 dol_syslog(get_class($this).
'::demandeprelevement WithdrawRequestErrorNilAmount');
861 $payment_mode_id =
dol_getIdFromCode($this->db, ($type ==
'bank-transfer' ?
'VIR' :
'PRE'),
'c_paiement',
'code',
'id', 1);
862 if ($payment_mode_id > 0) {
872 $this->error =
"A request already exists";
873 dol_syslog(get_class($this).
'::demandeprelevement Impossible de creer une demande, demande deja en cours');
877 $this->error = $this->db->error();
878 dol_syslog(get_class($this).
'::demandeprelevement Erreur -2');
882 $this->error =
"Status of invoice does not allow this";
883 dol_syslog(get_class($this).
"::demandeprelevement ".$this->error.
" $this->statut, $this->paye, $this->mode_reglement_id");
917 global $conf, $user, $langs;
919 if ($type !=
'bank-transfer' && $type !=
'credit-transfer' && empty($conf->global->STRIPE_SEPA_DIRECT_DEBIT)) {
922 if ($type !=
'direct-debit' && empty($conf->global->STRIPE_SEPA_CREDIT_TRANSFER)) {
928 dol_syslog(get_class($this).
"::makeStripeSepaRequest start", LOG_DEBUG);
930 if ($this->statut > self::STATUS_DRAFT && $this->paye == 0) {
932 require_once DOL_DOCUMENT_ROOT.
'/societe/class/companybankaccount.class.php';
934 $result = $bac->fetch(0, $this->socid, 1,
'ban');
935 if ($result <= 0 || empty($bac->id)) {
936 $this->error = $langs->trans(
"ThirdpartyHasNoDefaultBanAccount");
937 $this->errors[] = $this->error;
938 dol_syslog(get_class($this).
"::makeStripeSepaRequest ".$this->error);
943 $sql =
"SELECT rowid, date_demande, amount, fk_facture, fk_facture_fourn, fk_prelevement_bons";
944 $sql .=
" FROM ".$this->db->prefix().
"prelevement_demande";
945 $sql .=
" WHERE rowid = ".((int) $did);
946 if ($type !=
'bank-transfer' && $type !=
'credit-transfer') {
947 $sql .=
" AND fk_facture = ".((int) $this->
id);
949 if ($type !=
'direct-debit') {
950 $sql .=
" AND fk_facture_fourn = ".((int) $this->
id);
952 $sql .=
" AND traite = 0";
954 dol_syslog(get_class($this).
"::makeStripeSepaRequest load requests to process", LOG_DEBUG);
955 $resql = $this->db->query(
$sql);
957 $obj = $this->db->fetch_object($resql);
964 $amount = $obj->amount;
966 if (is_numeric($amount) && $amount != 0) {
967 require_once DOL_DOCUMENT_ROOT.
'/societe/class/companypaymentmode.class.php';
969 $companypaymentmode->fetch($bac->id);
973 $service =
'StripeTest';
975 if (!empty($conf->global->STRIPE_LIVE) && !
GETPOST(
'forcesandbox',
'alpha')) {
976 $service =
'StripeLive';
980 dol_syslog(
"makeStripeSepaRequest amount = ".$amount.
" service=" . $service .
" servicestatus=" . $servicestatus .
" thirdparty_id=" . $this->socid.
" did=".$did);
982 $this->stripechargedone = 0;
983 $this->stripechargeerror = 0;
987 $currency = $conf->currency;
989 global $stripearrayofkeysbyenv;
991 $errorforinvoice = 0;
995 dol_syslog(
"--- Process payment request thirdparty_id=" . $this->thirdparty->id .
", thirdparty_name=" . $this->thirdparty->name .
" ban id=" . $bac->id, LOG_DEBUG);
1000 $amounttopay = $amount;
1004 $arrayzerounitcurrency = [
'BIF',
'CLP',
'DJF',
'GNF',
'JPY',
'KMF',
'KRW',
'MGA',
'PYG',
'RWF',
'VND',
'VUV',
'XAF',
'XOF',
'XPF'];
1005 $amountstripe = $amounttopay;
1006 if (!in_array($currency, $arrayzerounitcurrency)) {
1007 $amountstripe = $amountstripe * 100;
1010 $fk_bank_account =
getDolGlobalInt(
'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS');
1011 if (!($fk_bank_account > 0)) {
1014 dol_syslog(
"Error no bank account defined for Stripe payments", LOG_ERR);
1015 $this->errors[] =
"Error bank account for Stripe payments not defined into Stripe module";
1021 require_once DOL_DOCUMENT_ROOT.
'/compta/prelevement/class/bonprelevement.class.php';
1024 if (empty($obj->fk_prelevement_bons)) {
1026 $nbinvoices = $bon->create(0, 0,
'real',
'ALL',
'', 0, $type, $did, $fk_bank_account);
1027 if ($nbinvoices <= 0) {
1030 dol_syslog(
"Error on BonPrelevement creation", LOG_ERR);
1031 $this->errors[] =
"Error on BonPrelevement creation";
1050 dol_syslog(
"Error Line already part of a bank payment order", LOG_ERR);
1051 $this->errors[] =
"The line is already included into a bank payment order. Delete the bank payment order first.";
1056 if ($amountstripe > 0) {
1059 dol_syslog(
"We will try to pay with companypaymentmodeid=" . $companypaymentmode->id .
" stripe_card_ref=" . $companypaymentmode->stripe_card_ref .
" mode=" . $companypaymentmode->status, LOG_DEBUG);
1061 $thirdparty =
new Societe($this->db);
1062 $resultthirdparty = $thirdparty->fetch($this->socid);
1064 include_once DOL_DOCUMENT_ROOT .
'/stripe/class/stripe.class.php';
1066 $stripe =
new Stripe($this->db);
1068 dol_syslog(
"makeStripeSepaRequest Current Stripe environment is " . $stripearrayofkeysbyenv[$servicestatus][
'publishable_key']);
1070 $stripearrayofkeys = $stripearrayofkeysbyenv[$servicestatus];
1071 \Stripe\Stripe::setApiKey($stripearrayofkeys[
'secret_key']);
1074 dol_syslog(
"makeStripeSepaRequest get stripe connet account", LOG_DEBUG);
1075 $stripeacc = $stripe->getStripeAccount($service, $this->socid);
1076 dol_syslog(
"makeStripeSepaRequest get stripe connect account return " . json_encode($stripeacc), LOG_DEBUG);
1078 $customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 0);
1079 if (empty($customer) && !empty($stripe->error)) {
1080 $this->errors[] = $stripe->error;
1085 $postactionmessages = [];
1087 if ($resultthirdparty > 0 && !empty($customer)) {
1090 if ($companypaymentmode->type ==
'ban') {
1094 $stripecard = $stripe->sepaStripe($customer, $companypaymentmode, $stripeacc, $servicestatus, 0);
1097 $this->error =
'The payment mode type is not "ban"';
1101 $FULLTAG =
'DID='.$did.
'-INV=' . $this->
id .
'-CUS=' . $thirdparty->id;
1102 $description =
'Stripe payment from makeStripeSepaRequest: ' . $FULLTAG .
' did='.$did.
' ref=' . $this->ref;
1104 $stripefailurecode =
'';
1105 $stripefailuremessage =
'';
1106 $stripefailuredeclinecode =
'';
1109 dol_syslog(
"* Create payment on SEPA " . $stripecard->id .
", amounttopay=" . $amounttopay .
", amountstripe=" . $amountstripe .
", FULLTAG=" . $FULLTAG, LOG_DEBUG);
1112 $paymentintent = $stripe->getPaymentIntent($amounttopay, $currency, $FULLTAG, $description, $this, $customer->id, $stripeacc, $servicestatus, 0,
'automatic',
true, $stripecard->id, 1, 1, $did);
1114 $charge =
new stdClass();
1116 if ($paymentintent->status ===
'succeeded' || $paymentintent->status ===
'processing') {
1117 $charge->status =
'ok';
1118 $charge->id = $paymentintent->id;
1119 $charge->customer = $customer->id;
1120 } elseif ($paymentintent->status ===
'requires_action') {
1122 dol_syslog(var_export($paymentintent,
true), LOG_DEBUG);
1124 $charge->status =
'failed';
1125 $charge->customer = $customer->id;
1126 $charge->failure_code = $stripe->code;
1127 $charge->failure_message = $stripe->error;
1128 $charge->failure_declinecode = $stripe->declinecode;
1129 $stripefailurecode = $stripe->code;
1130 $stripefailuremessage =
'Action required. Contact the support at ';
1131 $stripefailuredeclinecode = $stripe->declinecode;
1133 dol_syslog(var_export($paymentintent,
true), LOG_DEBUG);
1135 $charge->status =
'failed';
1136 $charge->customer = $customer->id;
1137 $charge->failure_code = $stripe->code;
1138 $charge->failure_message = $stripe->error;
1139 $charge->failure_declinecode = $stripe->declinecode;
1140 $stripefailurecode = $stripe->code;
1141 $stripefailuremessage = $stripe->error;
1142 $stripefailuredeclinecode = $stripe->declinecode;
1150 if (empty($charge) || $charge->status ==
'failed') {
1151 dol_syslog(
'Failed to charge payment mode ' . $stripecard->id .
' stripefailurecode=' . $stripefailurecode .
' stripefailuremessage=' . $stripefailuremessage .
' stripefailuredeclinecode=' . $stripefailuredeclinecode, LOG_WARNING);
1154 $this->stripechargeerror++;
1158 $errmsg = $langs->trans(
"FailedToChargeCard");
1159 if (!empty($charge)) {
1160 if ($stripefailuredeclinecode ==
'authentication_required') {
1161 $errauthenticationmessage = $langs->trans(
"ErrSCAAuthentication");
1162 $errmsg = $errauthenticationmessage;
1163 } elseif (in_array($stripefailuredeclinecode, [
'insufficient_funds',
'generic_decline'])) {
1164 $errmsg .=
': ' . $charge->failure_code;
1165 $errmsg .= ($charge->failure_message ?
' - ' :
'') .
' ' . $charge->failure_message;
1166 if (empty($stripefailurecode)) {
1167 $stripefailurecode = $charge->failure_code;
1169 if (empty($stripefailuremessage)) {
1170 $stripefailuremessage = $charge->failure_message;
1173 $errmsg .=
': failure_code=' . $charge->failure_code;
1174 $errmsg .= ($charge->failure_message ?
' - ' :
'') .
' failure_message=' . $charge->failure_message;
1175 if (empty($stripefailurecode)) {
1176 $stripefailurecode = $charge->failure_code;
1178 if (empty($stripefailuremessage)) {
1179 $stripefailuremessage = $charge->failure_message;
1183 $errmsg .=
': ' . $stripefailurecode .
' - ' . $stripefailuremessage;
1184 $errmsg .= ($stripefailuredeclinecode ?
' - ' . $stripefailuredeclinecode :
'');
1187 $description =
'Stripe payment ERROR from makeStripeSepaRequest: ' . $FULLTAG;
1188 $postactionmessages[] = $errmsg .
' (' . $stripearrayofkeys[
'publishable_key'] .
')';
1189 $this->errors[] = $errmsg;
1191 dol_syslog(
'Successfuly request '.$type.
' '.$stripecard->id);
1193 $postactionmessages[] =
'Success to request '.$type.
' (' . $charge->id .
' with ' . $stripearrayofkeys[
'publishable_key'] .
')';
1197 $this->stripechargedone++;
1200 $description =
'Stripe payment request OK (' . $charge->id .
') from makeStripeSepaRequest: ' . $FULLTAG;
1206 if (empty($charge) || $charge->status ==
'failed') {
1207 $actioncode =
'PAYMENT_STRIPE_KO';
1208 $extraparams = $stripefailurecode;
1209 $extraparams .= (($extraparams && $stripefailuremessage) ?
' - ' :
'') . $stripefailuremessage;
1210 $extraparams .= (($extraparams && $stripefailuredeclinecode) ?
' - ' :
'') . $stripefailuredeclinecode;
1212 $actioncode =
'PAYMENT_STRIPE_OK';
1218 dol_syslog(
"No ban payment method found for this stripe customer " . $customer->id, LOG_WARNING);
1219 $this->errors[] =
'Failed to get direct debit payment method for stripe customer = ' . $customer->id;
1221 $description =
'Failed to find or use the payment mode - no ban defined for the thirdparty account';
1222 $stripefailurecode =
'BADPAYMENTMODE';
1223 $stripefailuremessage =
'Failed to find or use the payment mode - no ban defined for the thirdparty account';
1224 $postactionmessages[] = $description .
' (' . $stripearrayofkeys[
'publishable_key'] .
')';
1228 $actioncode =
'PAYMENT_STRIPE_KO';
1234 $stripefailurecode =
'';
1235 $stripefailuremessage =
'';
1243 if ($resultthirdparty <= 0) {
1244 dol_syslog(
'SellYourSaasUtils Failed to load customer for thirdparty_id = ' . $thirdparty->id, LOG_WARNING);
1245 $this->errors[] =
'Failed to load Stripe account for thirdparty_id = ' . $thirdparty->id;
1247 dol_syslog(
'SellYourSaasUtils Failed to get Stripe customer id for thirdparty_id = ' . $thirdparty->id .
" in mode " . $servicestatus .
" in Stripe env " . $stripearrayofkeysbyenv[$servicestatus][
'publishable_key'], LOG_WARNING);
1248 $this->errors[] =
'Failed to get Stripe account id for thirdparty_id = ' . $thirdparty->id .
" in mode " . $servicestatus .
" in Stripe env " . $stripearrayofkeysbyenv[$servicestatus][
'publishable_key'];
1253 $description =
'Failed to find or use your payment mode (no payment mode for this customer id)';
1254 $stripefailurecode =
'BADPAYMENTMODE';
1255 $stripefailuremessage =
'Failed to find or use your payment mode (no payment mode for this customer id)';
1256 $postactionmessages = [];
1260 $actioncode =
'PAYMENT_STRIPE_KO';
1265 dol_syslog(
"* Record event for credit transfer or direct debit request result - " . $description);
1266 require_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
1271 $actioncomm->type_code =
'AC_OTH_AUTO';
1272 $actioncomm->code =
'AC_' . $actioncode;
1273 $actioncomm->label = $description;
1274 $actioncomm->note_private = join(
",\n", $postactionmessages);
1275 $actioncomm->fk_project = $this->fk_project;
1276 $actioncomm->datep = $now;
1277 $actioncomm->datef = $now;
1278 $actioncomm->percentage = -1;
1279 $actioncomm->socid = $thirdparty->id;
1280 $actioncomm->contactid = 0;
1281 $actioncomm->authorid = $user->id;
1282 $actioncomm->userownerid = $user->id;
1292 $actioncomm->fk_element = $this->id;
1293 $actioncomm->elementtype = $this->element;
1294 $actioncomm->extraparams =
dol_trunc($extraparams, 250);
1296 $actioncomm->create($user);
1300 $this->postactionmessages = $postactionmessages;
1304 dol_syslog(
'Error ' . $e->getMessage(), LOG_ERR);
1305 $this->errors[] =
'Error ' . $e->getMessage();
1310 dol_syslog(
"Remain to pay is null for the invoice " . $this->
id .
" " . $this->
ref .
". Why is the invoice not classified 'Paid' ?", LOG_WARNING);
1311 $this->errors[] =
"Remain to pay is null for the invoice " . $this->
id .
" " . $this->ref .
". Why is the invoice not classified 'Paid' ?";
1316 if (!$error && !$errorforinvoice) {
1317 $result = $bon->set_infotrans($user, $now, 3);
1321 dol_syslog(
"Error on BonPrelevement creation", LOG_ERR);
1322 $this->errors[] =
"Error on BonPrelevement creation";
1326 if (!$error && !$errorforinvoice) {
1328 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"prelevement_demande SET";
1329 $sql .=
" ext_payment_id = '".$this->db->escape($paymentintent->id).
"',";
1330 $sql .=
" ext_payment_site = '".$this->db->escape($service).
"'";
1331 $sql .=
" WHERE rowid = ".((int) $did);
1333 dol_syslog(get_class($this).
"::makeStripeSepaRequest update to save stripe paymentintent ids", LOG_DEBUG);
1334 $resql = $this->db->query(
$sql);
1336 $this->error = $this->db->lasterror();
1337 dol_syslog(get_class($this).
'::makeStripeSepaRequest Erreur');
1342 if (!$error && !$errorforinvoice) {
1343 $this->db->commit();
1345 $this->db->rollback();
1348 $this->error =
'WithdrawRequestErrorNilAmount';
1349 dol_syslog(get_class($this).
'::makeStripeSepaRequest WithdrawRequestErrorNilAmount');
1367 $this->error = $this->db->error();
1368 dol_syslog(get_class($this).
'::makeStripeSepaRequest Erreur -2');
1372 $this->error =
"Status of invoice does not allow this";
1373 dol_syslog(get_class($this).
"::makeStripeSepaRequest ".$this->error.
" $this->statut, $this->paye, $this->mode_reglement_id");
1389 $sql =
'DELETE FROM '.$this->db->prefix().
'prelevement_demande';
1390 $sql .=
' WHERE rowid = '.((int) $did);
1391 $sql .=
' AND traite = 0';
1392 if ($this->db->query(
$sql)) {
1395 $this->error = $this->db->lasterror();
1396 dol_syslog(get_class($this).
'::demande_prelevement_delete Error '.$this->error);
1409 global $conf, $mysoc;
1412 $tmplang->setDefaultLang(
'en_US');
1413 $tmplang->load(
"main");
1418 $pricewithtaxstring =
price2num($this->total_ttc, 2, 1);
1419 $pricetaxstring =
price2num($this->total_tva, 2, 1);
1446 $s = pack(
'C1', 1).pack(
'C1', strlen($mysoc->name)).$mysoc->name;
1447 $s .= pack(
'C1', 2).pack(
'C1', strlen($mysoc->tva_intra)).$mysoc->tva_intra;
1448 $s .= pack(
'C1', 3).pack(
'C1', strlen($datestring)).$datestring;
1449 $s .= pack(
'C1', 4).pack(
'C1', strlen($pricewithtaxstring)).$pricewithtaxstring;
1450 $s .= pack(
'C1', 5).pack(
'C1', strlen($pricetaxstring)).$pricetaxstring;
1456 $s = base64_encode($s);
1469 global $conf, $mysoc;
1472 $tmplang->setDefaultLang(
'en_US');
1473 $tmplang->load(
"main");
1475 $pricewithtaxstring =
price2num($this->total_ttc, 2, 1);
1476 $pricetaxstring =
price2num($this->total_tva, 2, 1);
1478 $complementaryinfo =
'';
1492 $complementaryinfo =
'//S1/10/'.str_replace(
'/',
'', $this->
ref).
'/11/'.$datestring;
1493 if ($this->ref_client) {
1494 $complementaryinfo .=
'/20/'.$this->ref_client;
1496 if ($this->thirdparty->tva_intra) {
1497 $complementaryinfo .=
'/30/'.$this->thirdparty->tva_intra;
1500 include_once DOL_DOCUMENT_ROOT.
'/compta/bank/class/account.class.php';
1501 $bankaccount =
new Account($this->db);
1509 if ($this->fk_account > 0) {
1511 $bankaccount->fetch($this->fk_account);
1512 $s .= $bankaccount->iban.
"\n";
1516 if ($bankaccount->id > 0 &&
getDolGlobalString(
'PDF_SWISS_QRCODE_USE_OWNER_OF_ACCOUNT_AS_CREDITOR')) {
1520 $s .=
dol_trunc($bankaccount->proprio, 70,
'right',
'UTF-8', 1).
"\n";
1521 $addresslinearray = explode(
"\n", $bankaccount->owner_address);
1522 $s .=
dol_trunc(empty($addresslinearray[1]) ?
'' : $addresslinearray[1], 70,
'right',
'UTF-8', 1).
"\n";
1523 $s .=
dol_trunc(empty($addresslinearray[2]) ?
'' : $addresslinearray[2], 70,
'right',
'UTF-8', 1).
"\n";
1529 $s .=
dol_trunc($mysoc->name, 70,
'right',
'UTF-8', 1).
"\n";
1530 $addresslinearray = explode(
"\n", $mysoc->address);
1531 $s .=
dol_trunc(empty($addresslinearray[1]) ?
'' : $addresslinearray[1], 70,
'right',
'UTF-8', 1).
"\n";
1532 $s .=
dol_trunc(empty($addresslinearray[2]) ?
'' : $addresslinearray[2], 70,
'right',
'UTF-8', 1).
"\n";
1533 $s .=
dol_trunc($mysoc->zip, 16,
'right',
'UTF-8', 1).
"\n";
1534 $s .=
dol_trunc($mysoc->town, 35,
'right',
'UTF-8', 1).
"\n";
1535 $s .=
dol_trunc($mysoc->country_code, 2,
'right',
'UTF-8', 1).
"\n";
1546 $s .=
price($pricewithtaxstring, 0,
'none', 0, 0, 2).
"\n";
1547 $s .= ($this->multicurrency_code ? $this->multicurrency_code : $conf->currency).
"\n";
1550 $s .=
dol_trunc($this->thirdparty->name, 70,
'right',
'UTF-8', 1).
"\n";
1551 $addresslinearray = explode(
"\n", $this->thirdparty->address);
1552 $s .=
dol_trunc(empty($addresslinearray[1]) ?
'' : $addresslinearray[1], 70,
'right',
'UTF-8', 1).
"\n";
1553 $s .=
dol_trunc(empty($addresslinearray[2]) ?
'' : $addresslinearray[2], 70,
'right',
'UTF-8', 1).
"\n";
1554 $s .=
dol_trunc($this->thirdparty->zip, 16,
'right',
'UTF-8', 1).
"\n";
1555 $s .=
dol_trunc($this->thirdparty->town, 35,
'right',
'UTF-8', 1).
"\n";
1556 $s .=
dol_trunc($this->thirdparty->country_code, 2,
'right',
'UTF-8', 1).
"\n";
1561 if ($complementaryinfo) {
1562 $s .= $complementaryinfo.
"\n";
1568 if ($complementaryinfo) {
1569 $s .= $complementaryinfo.
"\n";
1579 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobjectline.class.php';
1607 public $product_type = 0;
1613 public $product_ref;
1619 public $product_label;
1625 public $product_desc;
1656 public $vat_src_code;
1668 public $localtax1_tx;
1674 public $localtax2_tx;
1680 public $localtax1_type;
1686 public $localtax2_type;
1692 public $remise_percent;
1717 public $total_localtax1;
1723 public $total_localtax2;
1731 public $date_start_fill;
1732 public $date_end_fill;
1734 public $buy_price_ht;
1747 public $info_bits = 0;
1749 public $special_code = 0;
1751 public $fk_multicurrency;
1752 public $multicurrency_code;
1753 public $multicurrency_subprice;
1754 public $multicurrency_total_ht;
1755 public $multicurrency_total_tva;
1756 public $multicurrency_total_ttc;
1758 public $fk_user_author;
1759 public $fk_user_modif;
1761 public $fk_accounting_account;
Class to manage bank accounts.
Class to manage agenda events (actions)
Class to manage withdrawal receipts.
Superclass for invoices classes.
const TYPE_CREDIT_NOTE
Credit note invoice.
demande_prelevement($fuser, $amount=0, $type='direct-debit', $sourcetype='facture')
Create a withdrawal request for a direct debit order or a credit transfer order.
const STATUS_CLOSED
Classified paid.
getSumCreditNotesUsed($multicurrency=0)
Return amount (with tax) of all credit notes invoices + excess received used by invoice.
getRemainToPay($multicurrency=0)
Return remain amount to pay.
buildZATCAQRString()
Build string for ZATCA QR Code (Arabi Saudia)
makeStripeCardRequest($fuser, $id, $sourcetype='facture')
Create a payment with Stripe card Must take amount using Stripe and record an event into llx_actionco...
makeStripeSepaRequest($fuser, $did, $type='direct-debit', $sourcetype='facture')
Create a direct debit order into prelevement_bons then Send the payment order to Stripe (for a direct...
const TYPE_STANDARD
Standard invoice.
demande_prelevement_delete($fuser, $did)
Remove a direct debit request or a credit transfer request.
getVentilExportCompta()
Return if an invoice was dispatched into bookkeeping.
const TYPE_PROFORMA
Proforma invoice.
buildSwitzerlandQRString()
Build string for QR-Bill (Switzerland)
const STATUS_VALIDATED
Validated (need to be paid)
const TYPE_SITUATION
Situation invoice.
getSumDepositsUsed($multicurrency=0)
Return amount (with tax) of all deposits invoices used by invoice.
getSommePaiement($multicurrency=0)
Return amount of payments already done.
const TYPE_DEPOSIT
Deposit invoice.
LibStatut($paye, $status, $mode=0, $alreadypaid=-1, $type=-1)
Return label of a status.
const STATUS_ABANDONED
Classified abandoned and no payment done.
calculate_date_lim_reglement($cond_reglement=0)
Returns an invoice payment deadline based on the invoice settlement conditions and billing date.
const TYPE_REPLACEMENT
Replacement invoice.
getSumFromThisCreditNotesNotUsed($multicurrency=0)
Return amount (with tax) of all converted amount for this credit note.
getListIdAvoirFromInvoice()
Returns array of credit note ids from the invoice.
const STATUS_DRAFT
Draft status.
getIdReplacingInvoice($option='')
Returns the id of the invoice that replaces it.
getLibType($withbadge=0)
Return label of type of invoice.
is_erasable()
Return if an invoice can be deleted Rule is: If invoice is draft and has a temporary ref -> yes (1) I...
getListOfPayments($filtertype='')
Return list of payments.
getLibStatut($mode=0, $alreadypaid=-1)
Return label of object status.
Parent class of all other business classes for details of elements (invoices, contracts,...
$label
Custom label of line.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
setPaymentMethods($id)
Change the payments methods.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage bank accounts description of third parties.
Class for CompanyPaymentMode.
Class to manage absolute discounts.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
trait CommonIncoterm
Superclass for incoterm classes.
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
dol_time_plus_duree($time, $duration_value, $duration_unit, $ruleforendofmonth=0)
Add a delay to a date.
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed informations (by default a local PHP server timestamp) Re...
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type