2012-07-11 18:13:41 +02:00
< ? php
2024-11-11 17:38:41 +01:00
/* Copyright ( C ) 2012 Regis Houssin < regis . houssin @ inodbox . com >
* Copyright ( C ) 2012 Cédric Salvador < csalvador @ gpcsolutions . fr >
* Copyright ( C ) 2012 - 2014 Raphaël Doursenaud < rdoursenaud @ gpcsolutions . fr >
2023-10-18 02:33:14 +02:00
* Copyright ( C ) 2023 Nick Fragoulis
2025-01-27 21:22:52 +01:00
* Copyright ( C ) 2024 - 2025 Frédéric France < frederic . france @ free . fr >
2025-02-01 15:53:36 +01:00
* Copyright ( C ) 2024 - 2025 MDW < mdeweerd @ users . noreply . github . com >
2024-11-11 17:38:41 +01:00
* Copyright ( C ) 2024 Alexandre Spangaro < alexandre @ inovea - conseil . com >
2012-07-11 18:13:41 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
2013-01-16 15:36:08 +01:00
* the Free Software Foundation ; either version 3 of the License , or
2012-07-11 18:13:41 +02:00
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2012-07-11 18:13:41 +02:00
*/
/**
* \file htdocs / core / class / commoninvoice . class . php
* \ingroup core
2024-10-13 16:45:42 +02:00
* \brief File of the superclass of invoice classes ( customer and supplier )
2012-07-11 18:13:41 +02:00
*/
2020-04-10 10:59:32 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php' ;
2020-09-16 02:50:18 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonincoterm.class.php' ;
2012-07-11 18:13:41 +02:00
/**
2024-10-13 16:45:42 +02:00
* Superclass for invoice classes
2012-07-11 18:13:41 +02:00
*/
abstract class CommonInvoice extends CommonObject
{
2020-09-16 02:50:18 +02:00
use CommonIncoterm ;
2023-11-24 10:10:24 +01:00
/**
* @ var string Label used as ref for template invoices
*/
public $title ;
2023-04-26 11:41:02 +02:00
/**
* @ var int Type of invoice ( See TYPE_XXX constants )
*/
public $type = self :: TYPE_STANDARD ;
/**
* @ var int Sub type of invoice ( A subtype code coming from llx_invoice_subtype table . May be used by some countries like Greece )
*/
public $subtype ;
2023-12-11 18:22:35 +01:00
/**
* @ var int Thirdparty ID
2024-10-13 16:45:42 +02:00
* @ deprecated Use $socid
2023-12-11 18:22:35 +01:00
* @ see $socid
*/
public $fk_soc ;
2023-09-10 17:30:00 +02:00
/**
* @ var int Thirdparty ID
*/
public $socid ;
2024-10-13 16:45:42 +02:00
/**
* @ var int < 0 , 1 >
*/
2023-09-22 09:07:04 +02:00
public $paye ;
2023-09-10 17:30:00 +02:00
/**
* Invoice date ( date )
*
2024-10-13 16:45:42 +02:00
* @ var int
2023-09-10 17:30:00 +02:00
*/
public $date ;
2024-01-18 23:28:42 +01:00
/**
* @ var int Deadline for payment
*/
2023-12-11 18:22:35 +01:00
public $date_lim_reglement ;
2024-10-13 16:45:42 +02:00
/**
* @ var int
*/
2023-09-10 17:30:00 +02:00
public $cond_reglement_id ; // Id in llx_c_paiement
2024-10-13 16:45:42 +02:00
/**
* @ var string | int Code in llx_c_paiement
*/
2023-09-10 17:30:00 +02:00
public $cond_reglement_code ; // Code in llx_c_paiement
2024-10-13 16:45:42 +02:00
/**
* @ var string
*/
2023-09-10 17:30:00 +02:00
public $cond_reglement_label ;
2024-10-13 16:45:42 +02:00
/**
* @ var string Code in llx_c_paiement
*/
public $cond_reglement_doc ;
2023-09-10 17:30:00 +02:00
2024-10-13 16:45:42 +02:00
/**
* @ var int
*/
2023-09-10 17:30:00 +02:00
public $mode_reglement_id ;
2024-10-13 16:45:42 +02:00
/**
* @ var string Code in llx_c_paiement
*/
public $mode_reglement_code ;
2023-09-10 17:30:00 +02:00
2023-11-06 16:00:24 +01:00
/**
* @ var string
*/
public $mode_reglement ;
/**
2024-10-13 16:45:42 +02:00
* @ var float
2023-11-06 16:00:24 +01:00
*/
public $revenuestamp ;
2024-10-13 16:45:42 +02:00
/**
* @ var float
*/
2023-09-10 17:30:00 +02:00
public $totalpaid ; // duplicate with sumpayed
2024-10-13 16:45:42 +02:00
/**
* @ var int | float
*/
2023-09-10 17:30:00 +02:00
public $totaldeposits ; // duplicate with sumdeposit
2024-10-13 16:45:42 +02:00
/**
* @ var int | float
*/
2023-09-10 17:30:00 +02:00
public $totalcreditnotes ; // duplicate with sumcreditnote
2024-10-13 16:45:42 +02:00
/**
* @ var int | float
*/
2023-09-10 17:30:00 +02:00
public $sumpayed ;
2024-10-13 16:45:42 +02:00
/**
* @ var int | float
*/
2023-09-10 17:30:00 +02:00
public $sumpayed_multicurrency ;
2024-10-13 16:45:42 +02:00
/**
* @ var int | float
*/
2023-09-10 17:30:00 +02:00
public $sumdeposit ;
2024-10-13 16:45:42 +02:00
/**
* @ var int | float
*/
2023-09-10 17:30:00 +02:00
public $sumdeposit_multicurrency ;
2024-10-13 16:45:42 +02:00
/**
* @ var int | float
*/
2023-09-10 17:30:00 +02:00
public $sumcreditnote ;
2024-10-13 16:45:42 +02:00
/**
* @ var int | float
*/
2023-09-10 17:30:00 +02:00
public $sumcreditnote_multicurrency ;
2024-10-13 16:45:42 +02:00
/**
2024-12-30 16:50:22 +01:00
* @ var int | float | string May be used for status
2024-10-13 16:45:42 +02:00
*/
2023-09-10 17:30:00 +02:00
public $remaintopay ;
2024-12-30 16:50:22 +01:00
/**
* @ var int May be used for status
*/
public $nbofopendirectdebitorcredittransfer ;
2023-09-10 17:30:00 +02:00
2025-01-19 13:18:36 +01:00
/**
2025-01-19 13:30:09 +01:00
* @ var int [] return of getListIdAvoirFromInvoice ()
2025-01-19 13:18:36 +01:00
*/
2025-01-20 06:53:03 +01:00
public $creditnote_ids ;
2025-01-19 13:18:36 +01:00
2023-11-07 17:58:35 +01:00
/**
* @ var int
*/
public $stripechargedone ;
/**
* @ var int
*/
public $stripechargeerror ;
/**
* Payment description
* @ var string
*/
public $description ;
/**
* @ var string
* @ deprecated
* @ see $ref_customer
*/
public $ref_client ;
/**
* @ var int Situation cycle reference number
*/
public $situation_cycle_ref ;
2023-09-10 17:30:00 +02:00
/**
* ! Closing after partial payment : discount_vat , badsupplier , abandon
* ! Closing when no payment : replaced , abandoned
* @ var string Close code
*/
public $close_code ;
/**
* ! Comment if paid without full payment
* @ var string Close note
*/
public $close_note ;
2023-11-19 00:52:16 +01:00
/**
2024-01-31 21:12:21 +01:00
* ! Populated by payment modules like Stripe
* @ var string [] Messages returned by an online payment module
2023-11-19 00:52:16 +01:00
*/
public $postactionmessages ;
2020-10-27 19:46:07 +01:00
/**
* Standard invoice
*/
const TYPE_STANDARD = 0 ;
/**
* Replacement invoice
*/
const TYPE_REPLACEMENT = 1 ;
/**
* Credit note invoice
*/
const TYPE_CREDIT_NOTE = 2 ;
/**
* Deposit invoice
*/
const TYPE_DEPOSIT = 3 ;
/**
* Proforma invoice .
2024-08-07 01:20:43 +02:00
* @ deprecated Remove this . A " proforma invoice " is an order with a look of invoice , not an invoice !
2020-10-27 19:46:07 +01:00
*/
const TYPE_PROFORMA = 4 ;
/**
* Situation invoice
*/
const TYPE_SITUATION = 5 ;
2015-01-20 17:55:20 +01:00
2015-04-03 05:18:47 +02:00
/**
2018-10-04 09:33:30 +02:00
* Draft status
2015-04-03 05:18:47 +02:00
*/
const STATUS_DRAFT = 0 ;
/**
* Validated ( need to be paid )
*/
const STATUS_VALIDATED = 1 ;
/**
* Classified paid .
* If paid partially , $this -> close_code can be :
* - CLOSECODE_DISCOUNTVAT
* - CLOSECODE_BADDEBT
2024-01-13 19:48:20 +01:00
* If paid completely , this -> close_code will be null
2015-04-03 05:18:47 +02:00
*/
const STATUS_CLOSED = 2 ;
/**
* Classified abandoned and no payment done .
* $this -> close_code can be :
* - CLOSECODE_BADDEBT
* - CLOSECODE_ABANDONED
* - CLOSECODE_REPLACED
*/
const STATUS_ABANDONED = 3 ;
2017-06-09 09:25:15 +02:00
2022-04-07 19:16:50 +02:00
2017-02-17 00:19:28 +01:00
/**
2017-05-05 17:27:16 +02:00
* Return remain amount to pay . Property -> id and -> total_ttc must be set .
* This does not include open direct debit requests .
2017-02-17 00:19:28 +01:00
*
* @ param int $multicurrency Return multicurrency_amount instead of amount
2024-10-13 16:45:42 +02:00
* @ return float | string Remain of amount to pay
2017-02-17 00:19:28 +01:00
*/
2019-02-25 22:27:04 +01:00
public function getRemainToPay ( $multicurrency = 0 )
2017-02-17 00:19:28 +01:00
{
2020-10-27 19:46:07 +01:00
$alreadypaid = 0.0 ;
$alreadypaid += $this -> getSommePaiement ( $multicurrency );
$alreadypaid += $this -> getSumDepositsUsed ( $multicurrency );
$alreadypaid += $this -> getSumCreditNotesUsed ( $multicurrency );
$remaintopay = price2num ( $this -> total_ttc - $alreadypaid , 'MT' );
2024-09-28 11:10:57 +02:00
if ( $this -> status == self :: STATUS_CLOSED && $this -> close_code == 'discount_vat' ) { // If invoice closed with discount for anticipated payment
2020-10-27 19:46:07 +01:00
$remaintopay = 0.0 ;
}
return $remaintopay ;
2017-02-17 00:19:28 +01:00
}
2012-07-11 18:13:41 +02:00
/**
2020-01-01 18:43:46 +01:00
* Return amount of payments already done . This must include ONLY the record into the payment table .
2024-09-28 13:05:24 +02:00
* Payments done using discounts , credit notes , etc are not included .
2012-07-11 18:13:41 +02:00
*
2024-10-13 16:45:42 +02:00
* @ param int <- 1 , 1 > $multicurrency Return multicurrency_amount instead of amount . - 1 = Return both .
* @ return float | int | array { alreadypaid : float , alreadypaid_multicurrency : float } Amount of payment already done , < 0 and set -> error if KO
2023-10-26 13:31:20 +02:00
* @ see getSumDepositsUsed (), getSumCreditNotesUsed ()
2012-07-11 18:13:41 +02:00
*/
2019-02-25 22:27:04 +01:00
public function getSommePaiement ( $multicurrency = 0 )
2012-07-11 18:13:41 +02:00
{
2020-04-10 10:59:32 +02:00
$table = 'paiement_facture' ;
$field = 'fk_facture' ;
2021-02-23 22:03:23 +01:00
if ( $this -> element == 'facture_fourn' || $this -> element == 'invoice_supplier' ) {
2020-04-10 10:59:32 +02:00
$table = 'paiementfourn_facturefourn' ;
$field = 'fk_facturefourn' ;
2012-07-11 18:13:41 +02:00
}
2022-01-27 12:52:13 +01:00
$sql = " SELECT sum(amount) as amount, sum(multicurrency_amount) as multicurrency_amount " ;
$sql .= " FROM " . $this -> db -> prefix () . $table ;
2021-08-28 00:55:51 +02:00
$sql .= " WHERE " . $field . " = " . (( int ) $this -> id );
2012-07-11 18:13:41 +02:00
2014-06-12 11:31:53 +02:00
dol_syslog ( get_class ( $this ) . " ::getSommePaiement " , LOG_DEBUG );
2022-09-15 03:08:33 +02:00
2020-04-10 10:59:32 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2012-07-11 18:13:41 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2022-04-07 19:16:50 +02:00
2012-07-11 18:13:41 +02:00
$this -> db -> free ( $resql );
2022-09-15 03:08:33 +02:00
if ( $obj ) {
2023-02-13 21:08:53 +01:00
if ( $multicurrency < 0 ) {
$this -> sumpayed = $obj -> amount ;
$this -> sumpayed_multicurrency = $obj -> multicurrency_amount ;
2024-03-13 00:29:19 +01:00
return array ( 'alreadypaid' => ( float ) $obj -> amount , 'alreadypaid_multicurrency' => ( float ) $obj -> multicurrency_amount );
2023-02-13 21:08:53 +01:00
} elseif ( $multicurrency ) {
2022-09-15 03:08:33 +02:00
$this -> sumpayed_multicurrency = $obj -> multicurrency_amount ;
return ( float ) $obj -> multicurrency_amount ;
} else {
$this -> sumpayed = $obj -> amount ;
return ( float ) $obj -> amount ;
}
2021-02-23 22:03:23 +01:00
} else {
2022-09-15 03:08:33 +02:00
return 0 ;
2021-02-23 22:03:23 +01:00
}
2020-05-21 15:05:19 +02:00
} else {
2020-04-10 10:59:32 +02:00
$this -> error = $this -> db -> lasterror ();
2012-07-11 18:13:41 +02:00
return - 1 ;
}
}
2017-06-09 09:25:15 +02:00
2017-01-23 20:54:52 +01:00
/**
2023-10-26 13:31:20 +02:00
* Return amount ( with tax ) of all deposits invoices used by invoice .
* Should always be empty , except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is on for sale invoices ( not recommended ),
* of FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS is on for purchase invoices ( not recommended ) .
2017-01-23 20:54:52 +01:00
*
2023-10-26 13:31:20 +02:00
* @ param int $multicurrency Return multicurrency_amount instead of amount
2023-12-06 15:46:39 +01:00
* @ return float Return integer < 0 and set -> error if KO , Sum of deposits amount otherwise
2023-10-26 13:31:20 +02:00
* @ see getSommePaiement (), getSumCreditNotesUsed ()
2017-01-23 20:54:52 +01:00
*/
2019-02-25 22:27:04 +01:00
public function getSumDepositsUsed ( $multicurrency = 0 )
2017-01-23 20:54:52 +01:00
{
2022-06-17 17:59:33 +02:00
/* if ( $this -> element == 'facture_fourn' || $this -> element == 'invoice_supplier' ) {
2022-10-12 11:52:33 +02:00
// FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS was never supported for purchase invoice, so we can return 0 with no need of SQL for this case.
2020-10-27 19:46:07 +01:00
return 0.0 ;
2022-06-17 17:59:33 +02:00
} */
2020-10-27 19:46:07 +01:00
require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php' ;
$discountstatic = new DiscountAbsolute ( $this -> db );
$result = $discountstatic -> getSumDepositsUsed ( $this , $multicurrency );
2021-12-16 12:33:45 +01:00
2020-10-27 19:46:07 +01:00
if ( $result >= 0 ) {
2022-04-07 19:16:50 +02:00
if ( $multicurrency ) {
$this -> sumdeposit_multicurrency = $result ;
} else {
$this -> sumdeposit = $result ;
}
2020-10-27 19:46:07 +01:00
return $result ;
} else {
$this -> error = $discountstatic -> error ;
return - 1 ;
}
2017-01-23 20:54:52 +01:00
}
2017-02-17 00:19:28 +01:00
2017-01-23 20:54:52 +01:00
/**
2023-10-26 13:31:20 +02:00
* Return amount ( with tax ) of all credit notes invoices + excess received used by invoice
2017-01-23 20:54:52 +01:00
*
2023-10-26 13:31:20 +02:00
* @ param int $multicurrency Return multicurrency_amount instead of amount
2023-12-06 15:46:39 +01:00
* @ return float Return integer < 0 and set -> error if KO , Sum of credit notes and deposits amount otherwise
2023-10-26 13:31:20 +02:00
* @ see getSommePaiement (), getSumDepositsUsed ()
2017-01-23 20:54:52 +01:00
*/
2019-02-25 22:27:04 +01:00
public function getSumCreditNotesUsed ( $multicurrency = 0 )
2017-01-23 20:54:52 +01:00
{
2020-10-27 19:46:07 +01:00
require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php' ;
$discountstatic = new DiscountAbsolute ( $this -> db );
$result = $discountstatic -> getSumCreditNotesUsed ( $this , $multicurrency );
if ( $result >= 0 ) {
2022-04-07 19:16:50 +02:00
if ( $multicurrency ) {
$this -> sumcreditnote_multicurrency = $result ;
} else {
$this -> sumcreditnote = $result ;
}
2020-10-27 19:46:07 +01:00
return $result ;
} else {
$this -> error = $discountstatic -> error ;
return - 1 ;
}
2017-01-23 20:54:52 +01:00
}
2017-06-09 09:25:15 +02:00
2019-04-12 10:16:13 +02:00
/**
* Return amount ( with tax ) of all converted amount for this credit note
*
* @ param int $multicurrency Return multicurrency_amount instead of amount
2023-12-06 15:46:39 +01:00
* @ return float Return integer < 0 if KO , Sum of credit notes and deposits amount otherwise
2019-04-12 10:16:13 +02:00
*/
2019-08-27 03:41:02 +02:00
public function getSumFromThisCreditNotesNotUsed ( $multicurrency = 0 )
2019-04-12 10:16:13 +02:00
{
2020-10-27 19:46:07 +01:00
require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php' ;
$discountstatic = new DiscountAbsolute ( $this -> db );
$result = $discountstatic -> getSumFromThisCreditNotesNotUsed ( $this , $multicurrency );
if ( $result >= 0 ) {
return $result ;
} else {
$this -> error = $discountstatic -> error ;
return - 1 ;
}
2017-01-23 20:54:52 +01:00
}
2017-06-09 09:25:15 +02:00
2012-07-11 18:13:41 +02:00
/**
2019-10-19 18:33:06 +02:00
* Returns array of credit note ids from the invoice
2012-07-11 18:13:41 +02:00
*
2024-10-13 16:45:42 +02:00
* @ return int [] Array of credit note ids
2012-07-11 18:13:41 +02:00
*/
2019-02-25 22:27:04 +01:00
public function getListIdAvoirFromInvoice ()
2012-07-11 18:13:41 +02:00
{
2020-04-10 10:59:32 +02:00
$idarray = array ();
2012-07-11 18:13:41 +02:00
2022-01-27 12:52:13 +01:00
$sql = " SELECT rowid " ;
2022-01-27 10:19:35 +01:00
$sql .= " FROM " . $this -> db -> prefix () . $this -> table_element ;
2021-09-30 15:59:47 +02:00
$sql .= " WHERE fk_facture_source = " . (( int ) $this -> id );
2022-01-27 12:52:13 +01:00
$sql .= " AND type = 2 " ;
2020-04-10 10:59:32 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2012-07-11 18:13:41 +02:00
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num ) {
2012-07-11 18:13:41 +02:00
$row = $this -> db -> fetch_row ( $resql );
2020-04-10 10:59:32 +02:00
$idarray [] = $row [ 0 ];
2012-07-11 18:13:41 +02:00
$i ++ ;
}
2020-05-21 15:05:19 +02:00
} else {
2012-07-11 18:13:41 +02:00
dol_print_error ( $this -> db );
}
2025-01-20 06:53:03 +01:00
$this -> creditnote_ids = $idarray ;
2012-07-11 18:13:41 +02:00
return $idarray ;
}
/**
2019-10-19 18:33:06 +02:00
* Returns the id of the invoice that replaces it
2012-07-11 18:13:41 +02:00
*
2019-10-19 18:33:06 +02:00
* @ param string $option status filter ( '' , 'validated' , ... )
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 si KO , 0 if no invoice replaces it , id of invoice otherwise
2012-07-11 18:13:41 +02:00
*/
2019-02-25 22:27:04 +01:00
public function getIdReplacingInvoice ( $option = '' )
2012-07-11 18:13:41 +02:00
{
2022-01-27 12:52:13 +01:00
$sql = " SELECT rowid " ;
2022-01-27 10:19:35 +01:00
$sql .= " FROM " . $this -> db -> prefix () . $this -> table_element ;
2021-09-30 15:59:47 +02:00
$sql .= " WHERE fk_facture_source = " . (( int ) $this -> id );
2022-01-27 12:52:13 +01:00
$sql .= " AND type < 2 " ;
2021-02-23 22:03:23 +01:00
if ( $option == 'validated' ) {
$sql .= ' AND fk_statut = 1' ;
}
2012-07-11 18:13:41 +02:00
// PROTECTION BAD DATA
2019-10-19 18:33:06 +02:00
// In case the database is corrupted and there is a valid replectement invoice
// and another no, priority is given to the valid one.
// Should not happen (unless concurrent access and 2 people have created a
// replacement invoice for the same invoice at the same time)
2022-01-27 12:52:13 +01:00
$sql .= " ORDER BY fk_statut DESC " ;
2012-07-11 18:13:41 +02:00
2020-04-10 10:59:32 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2012-07-11 18:13:41 +02:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-23 22:03:23 +01:00
if ( $obj ) {
2019-10-19 18:33:06 +02:00
// If there is any
2012-07-11 18:13:41 +02:00
return $obj -> rowid ;
2020-05-21 15:05:19 +02:00
} else {
2019-10-19 18:33:06 +02:00
// If no invoice replaces it
2012-07-11 18:13:41 +02:00
return 0 ;
}
2020-05-21 15:05:19 +02:00
} else {
2012-07-11 18:13:41 +02:00
return - 1 ;
}
}
2024-12-30 16:50:22 +01:00
/**
* Return list of open direct debit or credit transfer
*
2024-12-30 22:19:17 +01:00
* @ param 'bank-transfer' | 'direct-debit' $type 'bank-transfer' or 'direct-debit'
* @ return array < array { id : int , invoiceid : int , date : '' | int , amount : float } > Array with list of payments
2024-12-30 16:50:22 +01:00
*/
public function getListOfOpenDirectDebitOrCreditTransfer ( $type )
{
$listofopendirectdebitorcredittransfer = array ();
// TODO Add a cache to store array of open requests for each invoice ID
$sql = " SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande, pfd.date_traite as date_traite, pfd.amount " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " prelevement_demande as pfd " ;
if ( $type == 'bank-transfer' ) {
$sql .= " WHERE fk_facture_fourn = " . (( int ) $this -> id );
} else {
$sql .= " WHERE fk_facture = " . (( int ) $this -> id );
}
$sql .= " AND pfd.traite = 0 " ;
$sql .= " AND pfd.type = 'ban' " ;
$sql .= " ORDER BY pfd.date_demande DESC " ;
$resql = $this -> db -> query ( $sql );
2024-12-30 17:54:31 +01:00
$num = 0 ;
2024-12-30 16:50:22 +01:00
if ( $resql ) {
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num ) {
$obj = $this -> db -> fetch_object ( $resql );
if ( $obj ) {
$listofopendirectdebitorcredittransfer [] = array (
2024-12-30 22:19:17 +01:00
'id' => ( int ) $obj -> rowid ,
2024-12-30 16:50:22 +01:00
'invoiceid' => ( int ) $this -> id ,
'date' => $this -> db -> jdate ( $obj -> date_demande ),
2024-12-30 22:19:17 +01:00
'amount' => ( float ) $obj -> amount
2024-12-30 16:50:22 +01:00
);
}
$i ++ ;
}
} else {
$this -> error = $this -> db -> lasterror ();
}
$this -> nbofopendirectdebitorcredittransfer = $num ;
return $listofopendirectdebitorcredittransfer ;
}
2018-02-26 09:45:15 +01:00
/**
* Return list of payments
*
2024-03-17 14:24:07 +01:00
* @ see $error Empty string '' if no error .
*
2024-09-29 20:32:09 +02:00
* @ param string $filtertype 1 to filter on type of payment == 'PRE' for the payment lines
* @ param int $multicurrency Return multicurrency_amount instead of amount
* @ param int $mode 0 = payments + discount , 1 = payments only
2024-06-26 17:25:15 +02:00
* @ return array < array { amount : int | float , date : int , num : string , ref : string , ref_ext ? : string , fk_bank_line ? : int , type : string } > Array with list of payments
2018-02-26 09:45:15 +01:00
*/
2024-09-29 20:32:09 +02:00
public function getListOfPayments ( $filtertype = '' , $multicurrency = 0 , $mode = 0 )
2018-02-26 09:45:15 +01:00
{
2020-04-10 10:59:32 +02:00
$retarray = array ();
2024-09-29 20:32:09 +02:00
$this -> error = '' ; // By default no error, list can be empty.
2018-02-26 09:45:15 +01:00
2020-04-10 10:59:32 +02:00
$table = 'paiement_facture' ;
$table2 = 'paiement' ;
$field = 'fk_facture' ;
$field2 = 'fk_paiement' ;
2020-10-31 14:32:18 +01:00
$field3 = ', p.ref_ext' ;
2023-01-29 01:31:44 +01:00
$field4 = ', p.fk_bank' ; // Bank line id
2020-04-10 10:59:32 +02:00
$sharedentity = 'facture' ;
2021-02-23 22:03:23 +01:00
if ( $this -> element == 'facture_fourn' || $this -> element == 'invoice_supplier' ) {
2020-04-10 10:59:32 +02:00
$table = 'paiementfourn_facturefourn' ;
$table2 = 'paiementfourn' ;
$field = 'fk_facturefourn' ;
$field2 = 'fk_paiementfourn' ;
2020-10-31 14:32:18 +01:00
$field3 = '' ;
2020-04-10 10:59:32 +02:00
$sharedentity = 'facture_fourn' ;
2018-02-26 09:45:15 +01:00
}
2024-09-29 20:32:09 +02:00
// List of payments
if ( empty ( $mode ) || $mode == 1 ) {
$sql = " SELECT p.ref, pf.amount, pf.multicurrency_amount, p.fk_paiement, p.datep, p.num_paiement as num, t.code " . $field3 . $field4 ;
$sql .= " FROM " . $this -> db -> prefix () . $table . " as pf, " . $this -> db -> prefix () . $table2 . " as p, " . $this -> db -> prefix () . " c_paiement as t " ;
$sql .= " WHERE pf. " . $field . " = " . (( int ) $this -> id );
$sql .= " AND pf. " . $field2 . " = p.rowid " ;
$sql .= ' AND p.fk_paiement = t.id' ;
$sql .= ' AND p.entity IN (' . getEntity ( $sharedentity ) . ')' ;
if ( $filtertype ) {
$sql .= " AND t.code='PRE' " ;
}
2018-02-26 09:45:15 +01:00
2024-09-29 20:32:09 +02:00
dol_syslog ( get_class ( $this ) . " ::getListOfPayments filtertype= " . $filtertype . " multicurrency= " . $multicurrency . " mode= " . $mode , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num ) {
$obj = $this -> db -> fetch_object ( $resql );
if ( $multicurrency ) {
$tmp = array ( 'amount' => $obj -> multicurrency_amount , 'type' => $obj -> code , 'typeline' => 'payment' , 'date' => $obj -> datep , 'num' => $obj -> num , 'ref' => $obj -> ref );
} else {
$tmp = array ( 'amount' => $obj -> amount , 'type' => $obj -> code , 'typeline' => 'payment' , 'date' => $obj -> datep , 'num' => $obj -> num , 'ref' => $obj -> ref );
}
if ( ! empty ( $field3 )) {
$tmp [ 'ref_ext' ] = $obj -> ref_ext ;
}
if ( ! empty ( $field4 )) {
$tmp [ 'fk_bank_line' ] = $obj -> fk_bank ;
}
$retarray [] = $tmp ;
$i ++ ;
2023-01-29 01:31:44 +01:00
}
2024-09-29 20:32:09 +02:00
$this -> db -> free ( $resql );
} else {
$this -> error = $this -> db -> lasterror ();
dol_print_error ( $this -> db );
return array ();
2018-02-26 09:45:15 +01:00
}
2024-09-29 20:32:09 +02:00
}
2019-12-31 17:10:36 +01:00
2024-09-29 20:32:09 +02:00
// Look for credit notes and discounts and deposits
if ( empty ( $mode ) || $mode == 2 ) {
2019-12-31 17:07:56 +01:00
$sql = '' ;
2021-02-23 22:03:23 +01:00
if ( $this -> element == 'facture' || $this -> element == 'invoice' ) {
2021-09-30 15:59:47 +02:00
$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 " ;
2022-01-27 10:19:35 +01:00
$sql .= ' FROM ' . $this -> db -> prefix () . 'societe_remise_except as rc, ' . $this -> db -> prefix () . 'facture as f' ;
2021-08-27 23:36:06 +02:00
$sql .= ' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = ' . (( int ) $this -> id );
2020-04-10 10:59:32 +02:00
$sql .= ' AND (f.type = 2 OR f.type = 0 OR f.type = 3)' ; // Find discount coming from credit note or excess received or deposits (payments from deposits are always null except if FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is set)
2021-02-23 22:03:23 +01:00
} elseif ( $this -> element == 'facture_fourn' || $this -> element == 'invoice_supplier' ) {
2021-09-30 15:59:47 +02:00
$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 " ;
2022-01-27 10:19:35 +01:00
$sql .= ' FROM ' . $this -> db -> prefix () . 'societe_remise_except as rc, ' . $this -> db -> prefix () . 'facture_fourn as f' ;
2021-08-27 23:36:06 +02:00
$sql .= ' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = ' . (( int ) $this -> id );
2022-10-12 11:52:33 +02:00
$sql .= ' AND (f.type = 2 OR f.type = 0 OR f.type = 3)' ; // Find discount coming from credit note or excess received or deposits (payments from deposits are always null except if FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS is set)
2019-12-31 01:08:25 +01:00
}
2019-12-31 01:13:42 +01:00
2019-12-31 17:06:30 +01:00
if ( $sql ) {
2020-04-10 10:59:32 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2019-12-31 17:06:30 +01:00
$num = $this -> db -> num_rows ( $resql );
2020-04-10 10:59:32 +02:00
$i = 0 ;
2021-02-23 22:03:23 +01:00
while ( $i < $num ) {
2019-12-31 17:06:30 +01:00
$obj = $this -> db -> fetch_object ( $resql );
2019-12-31 17:07:07 +01:00
if ( $multicurrency ) {
2024-09-29 20:16:41 +02:00
$retarray [] = array ( 'amount' => $obj -> multicurrency_amount , 'type' => $obj -> type , 'typeline' => 'discount' , 'date' => $obj -> date , 'num' => '0' , 'ref' => $obj -> ref );
2020-05-21 15:05:19 +02:00
} else {
2024-09-29 20:16:41 +02:00
$retarray [] = array ( 'amount' => $obj -> amount , 'type' => $obj -> type , 'typeline' => 'discount' , 'date' => $obj -> date , 'num' => '' , 'ref' => $obj -> ref );
2019-12-31 17:06:30 +01:00
}
$i ++ ;
}
2020-05-21 15:05:19 +02:00
} else {
2019-12-31 17:06:30 +01:00
$this -> error = $this -> db -> lasterror ();
dol_print_error ( $this -> db );
return array ();
2019-12-31 01:08:25 +01:00
}
$this -> db -> free ( $resql );
2024-09-29 20:32:09 +02:00
} else {
$this -> error = $this -> db -> lasterror ();
dol_print_error ( $this -> db );
return array ();
2019-12-31 01:08:25 +01:00
}
2018-02-26 09:45:15 +01:00
}
2024-09-29 20:32:09 +02:00
return $retarray ;
2018-02-26 09:45:15 +01:00
}
2020-10-27 19:46:07 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2017-12-05 10:01:30 +01:00
/**
* Return if an invoice can be deleted
* Rule is :
2018-10-29 14:41:00 +01:00
* If invoice is draft and has a temporary ref -> yes ( 1 )
2017-12-05 10:01:30 +01:00
* If hidden option INVOICE_CAN_NEVER_BE_REMOVED is on -> no ( 0 )
* If invoice is dispatched in bookkeeping -> no ( - 1 )
* If invoice has a definitive ref , is not last and INVOICE_CAN_ALWAYS_BE_REMOVED off -> no ( - 2 )
* If invoice not last in a cycle -> no ( - 3 )
* If there is payment -> no ( - 4 )
2018-10-29 14:41:00 +01:00
* Otherwise -> yes ( 2 )
2017-12-05 10:01:30 +01:00
*
2023-12-06 15:46:39 +01:00
* @ return int Return integer <= 0 if no , > 0 if yes
2017-12-05 10:01:30 +01:00
*/
2020-10-27 19:46:07 +01:00
public function is_erasable ()
{
// phpcs:enable
2017-12-05 10:01:30 +01:00
// We check if invoice is a temporary number (PROVxxxx)
$tmppart = substr ( $this -> ref , 1 , 4 );
2024-09-28 11:10:57 +02:00
if ( $this -> status == self :: STATUS_DRAFT && $tmppart === 'PROV' ) { // If draft invoice and ref not yet defined
2017-12-05 10:01:30 +01:00
return 1 ;
}
2023-11-27 11:24:19 +01:00
if ( getDolGlobalString ( 'INVOICE_CAN_NEVER_BE_REMOVED' )) {
2021-02-23 22:03:23 +01:00
return 0 ;
}
2017-12-05 10:01:30 +01:00
// If not a draft invoice and not temporary invoice
2021-02-23 22:03:23 +01:00
if ( $tmppart !== 'PROV' ) {
2017-12-05 10:01:30 +01:00
$ventilExportCompta = $this -> getVentilExportCompta ();
2021-02-23 22:03:23 +01:00
if ( $ventilExportCompta != 0 ) {
return - 1 ;
}
2017-12-05 10:01:30 +01:00
// Get last number of validated invoice
2021-02-23 22:03:23 +01:00
if ( $this -> element != 'invoice_supplier' ) {
if ( empty ( $this -> thirdparty )) {
$this -> fetch_thirdparty (); // We need to have this->thirdparty defined, in case of numbering rule use tags that depend on thirdparty (like {t} tag).
}
2019-01-27 11:55:16 +01:00
$maxref = $this -> getNextNumRef ( $this -> thirdparty , 'last' );
2017-12-05 10:01:30 +01:00
// If there is no invoice into the reset range and not already dispatched, we can delete
// If invoice to delete is last one and not already dispatched, we can delete
2023-11-27 11:24:19 +01:00
if ( ! getDolGlobalString ( 'INVOICE_CAN_ALWAYS_BE_REMOVED' ) && $maxref != '' && $maxref != $this -> ref ) {
2021-02-23 22:03:23 +01:00
return - 2 ;
}
2017-12-05 10:01:30 +01:00
// TODO If there is payment in bookkeeping, check payment is not dispatched in accounting
// ...
2021-02-23 22:03:23 +01:00
if ( $this -> situation_cycle_ref && method_exists ( $this , 'is_last_in_cycle' )) {
2017-12-05 10:01:30 +01:00
$last = $this -> is_last_in_cycle ();
2021-02-23 22:03:23 +01:00
if ( ! $last ) {
return - 3 ;
}
2017-12-05 10:01:30 +01:00
}
}
}
// Test if there is at least one payment. If yes, refuse to delete.
2023-11-27 11:24:19 +01:00
if ( ! getDolGlobalString ( 'INVOICE_CAN_ALWAYS_BE_REMOVED' ) && $this -> getSommePaiement () > 0 ) {
2021-02-23 22:03:23 +01:00
return - 4 ;
}
2017-12-05 10:01:30 +01:00
2018-10-29 14:41:00 +01:00
return 2 ;
2017-12-05 10:01:30 +01:00
}
/**
2024-09-29 15:23:24 +02:00
* Return if an invoice was transferred into accountnancy .
* This is true if at least on line was transferred into table accounting_bookkeeping
2017-12-05 10:01:30 +01:00
*
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if KO , 0 = no , 1 = yes
2017-12-05 10:01:30 +01:00
*/
2018-01-22 03:07:11 +01:00
public function getVentilExportCompta ()
2017-12-05 10:01:30 +01:00
{
$alreadydispatched = 0 ;
$type = 'customer_invoice' ;
2021-02-23 22:03:23 +01:00
if ( $this -> element == 'invoice_supplier' ) {
$type = 'supplier_invoice' ;
}
2017-12-05 10:01:30 +01:00
2024-09-29 15:23:24 +02:00
$sql = " SELECT COUNT(ab.rowid) as nb FROM " . $this -> db -> prefix () . " accounting_bookkeeping as ab " ;
$sql .= " WHERE ab.doc_type=' " . $this -> db -> escape ( $type ) . " ' AND ab.fk_doc = " . (( int ) $this -> id );
2017-12-05 10:01:30 +01:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2017-12-05 10:01:30 +01:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-23 22:03:23 +01:00
if ( $obj ) {
2017-12-05 10:01:30 +01:00
$alreadydispatched = $obj -> nb ;
}
2020-05-21 15:05:19 +02:00
} else {
2017-12-05 10:01:30 +01:00
$this -> error = $this -> db -> lasterror ();
return - 1 ;
}
2021-02-23 22:03:23 +01:00
if ( $alreadydispatched ) {
2017-12-05 10:01:30 +01:00
return 1 ;
}
return 0 ;
}
2023-08-24 14:55:23 +02:00
/**
* Return next reference of invoice not already used ( or last reference )
*
* @ param Societe $soc Thirdparty object
* @ param string $mode 'next' for next value or 'last' for last value
* @ return string free ref or last ref
*/
public function getNextNumRef ( $soc , $mode = 'next' )
{
// TODO Must be implemented into main class
return '' ;
}
2017-12-05 10:01:30 +01:00
2012-07-11 18:13:41 +02:00
/**
2016-09-29 10:38:15 +02:00
* Return label of type of invoice
2012-07-11 18:13:41 +02:00
*
2022-09-15 03:08:33 +02:00
* @ param int $withbadge 1 = Add span for badge css , 2 = Add span and show short label
* @ return string Label of type of invoice
2012-07-11 18:13:41 +02:00
*/
2022-09-15 03:08:33 +02:00
public function getLibType ( $withbadge = 0 )
2012-07-11 18:13:41 +02:00
{
global $langs ;
2022-09-15 03:08:33 +02:00
$labellong = " Unknown " ;
2024-10-13 16:45:42 +02:00
$labelshort = " Unknown " ;
2021-02-23 22:03:23 +01:00
if ( $this -> type == CommonInvoice :: TYPE_STANDARD ) {
2022-09-15 03:08:33 +02:00
$labellong = " InvoiceStandard " ;
$labelshort = " InvoiceStandardShort " ;
2021-02-23 22:03:23 +01:00
} elseif ( $this -> type == CommonInvoice :: TYPE_REPLACEMENT ) {
2022-09-15 03:08:33 +02:00
$labellong = " InvoiceReplacement " ;
$labelshort = " InvoiceReplacementShort " ;
2021-02-23 22:03:23 +01:00
} elseif ( $this -> type == CommonInvoice :: TYPE_CREDIT_NOTE ) {
2022-09-15 03:08:33 +02:00
$labellong = " InvoiceAvoir " ;
$labelshort = " CreditNote " ;
2021-02-23 22:03:23 +01:00
} elseif ( $this -> type == CommonInvoice :: TYPE_DEPOSIT ) {
2022-09-15 03:08:33 +02:00
$labellong = " InvoiceDeposit " ;
$labelshort = " Deposit " ;
2024-08-07 01:20:43 +02:00
} elseif ( $this -> type == CommonInvoice :: TYPE_PROFORMA ) { // @phan-suppress-current-line PhanDeprecatedClassConstant
2022-09-15 03:08:33 +02:00
$labellong = " InvoiceProForma " ; // Not used.
$labelshort = " ProForma " ;
2021-02-23 22:03:23 +01:00
} elseif ( $this -> type == CommonInvoice :: TYPE_SITUATION ) {
2022-09-15 03:08:33 +02:00
$labellong = " InvoiceSituation " ;
$labelshort = " Situation " ;
}
$out = '' ;
if ( $withbadge ) {
$out .= '<span class="badgeneutral" title="' . dol_escape_htmltag ( $langs -> trans ( $labellong )) . '">' ;
}
$out .= $langs -> trans ( $withbadge == 2 ? $labelshort : $labellong );
if ( $withbadge ) {
$out .= '</span>' ;
2021-02-23 22:03:23 +01:00
}
2022-09-15 03:08:33 +02:00
return $out ;
2012-07-11 18:13:41 +02:00
}
2023-10-18 02:33:14 +02:00
/**
* Return label of invoice subtype
*
* @ param string $table table of invoice
2023-11-14 02:42:02 +01:00
* @ return string | int Label of invoice subtype or - 1 if error
2023-10-18 02:33:14 +02:00
*/
public function getSubtypeLabel ( $table = '' )
{
2023-11-14 14:43:54 +01:00
$subtypeLabel = '' ;
2023-10-18 02:33:14 +02:00
if ( $table === 'facture' || $table === 'facture_fourn' ) {
2023-11-19 00:52:16 +01:00
$sql = " SELECT s.label FROM " . $this -> db -> prefix () . $table . " AS f " ;
$sql .= " INNER JOIN " . $this -> db -> prefix () . " c_invoice_subtype AS s ON f.subtype = s.rowid " ;
2023-10-18 02:33:14 +02:00
$sql .= " WHERE f.ref = ' " . $this -> db -> escape ( $this -> ref ) . " ' " ;
2023-11-12 22:08:46 +01:00
} elseif ( $table === 'facture_rec' || $table === 'facture_fourn_rec' ) {
2023-11-19 00:52:16 +01:00
$sql = " SELECT s.label FROM " . $this -> db -> prefix () . $table . " AS f " ;
$sql .= " INNER JOIN " . $this -> db -> prefix () . " c_invoice_subtype AS s ON f.subtype = s.rowid " ;
$sql .= " WHERE f.titre = ' " . $this -> db -> escape ( $this -> title ) . " ' " ;
2023-11-14 14:43:54 +01:00
} else {
return - 1 ;
}
2023-11-12 22:08:46 +01:00
2023-11-14 14:43:54 +01:00
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
while ( $obj = $this -> db -> fetch_object ( $resql )) {
$subtypeLabel = $obj -> label ;
2023-10-18 02:33:14 +02:00
}
2023-11-14 14:43:54 +01:00
} else {
dol_print_error ( $this -> db );
return - 1 ;
2023-10-18 02:33:14 +02:00
}
2023-11-14 02:42:02 +01:00
2023-11-14 14:43:54 +01:00
return $subtypeLabel ;
2023-10-18 02:33:14 +02:00
}
/**
* Retrieve a list of invoice subtype labels or codes .
*
2024-10-13 16:45:42 +02:00
* @ param int < 0 , 1 > $mode 0 = Return id + label , 1 = Return code + id
* @ return array < int , string >| array < string , int > Array of subtypes
2023-10-18 02:33:14 +02:00
*/
2023-10-18 03:33:36 +02:00
public function getArrayOfInvoiceSubtypes ( $mode = 0 )
2023-10-18 02:33:14 +02:00
{
2023-10-18 03:33:36 +02:00
global $mysoc ;
2023-10-18 02:33:14 +02:00
$effs = array ();
$sql = " SELECT rowid, code, label as label " ;
$sql .= " FROM " . MAIN_DB_PREFIX . 'c_invoice_subtype' ;
2023-10-18 03:33:36 +02:00
$sql .= " WHERE active = 1 AND fk_country = " . (( int ) $mysoc -> country_id ) . " AND entity IN( " . getEntity ( 'c_invoice_subtype' ) . " ) " ;
2023-10-18 02:33:14 +02:00
$sql .= " ORDER by rowid, code " ;
2024-04-08 12:02:31 +02:00
2023-10-18 03:33:36 +02:00
dol_syslog ( get_class ( $this ) . '::getArrayOfInvoiceSubtypes' , LOG_DEBUG );
2023-10-18 02:33:14 +02:00
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num ) {
$objp = $this -> db -> fetch_object ( $resql );
if ( ! $mode ) {
$key = $objp -> rowid ;
$effs [ $key ] = $objp -> label ;
} else {
$key = $objp -> code ;
$effs [ $key ] = $objp -> rowid ;
}
$i ++ ;
}
$this -> db -> free ( $resql );
}
return $effs ;
}
2012-07-11 18:13:41 +02:00
/**
* Return label of object status
*
2025-01-27 21:22:52 +01:00
* @ 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
* @ param int | float $alreadypaid 0 = No payment already done , > 0 = Some payments were already done ( we recommend to put here float amount paid if you have it , 1 otherwise )
* @ return string Label of status
2012-07-11 18:13:41 +02:00
*/
2019-02-25 22:27:04 +01:00
public function getLibStatut ( $mode = 0 , $alreadypaid = - 1 )
2012-07-11 18:13:41 +02:00
{
2024-12-30 16:50:22 +01:00
return $this -> LibStatut ( $this -> paye , $this -> status , $mode , $alreadypaid , $this -> type , $this -> nbofopendirectdebitorcredittransfer );
2012-07-11 18:13:41 +02:00
}
2020-10-27 19:46:07 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2012-07-11 18:13:41 +02:00
/**
2017-11-25 11:10:52 +01:00
* Return label of a status
2012-07-11 18:13:41 +02:00
*
2024-12-30 17:51:53 +01:00
* @ param int $paye Status field paye ( or $recur )
* @ param int $status Id status
* @ param int < 0 , 6 > $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
2025-01-27 21:22:52 +01:00
* @ param int | float $alreadypaid 0 = No payment already done , > 0 = Some payments were already done ( we recommend to put here float amount paid if you have it , - 1 otherwise )
2024-12-30 17:51:53 +01:00
* @ param int $type Type invoice . If - 1 , we use $this -> type
* @ param int $nbofopendirectdebitorcredittransfer Nb of open direct debit or credit transfer
* @ return string Label of status
2012-07-11 18:13:41 +02:00
*/
2024-12-30 16:50:22 +01:00
public function LibStatut ( $paye , $status , $mode = 0 , $alreadypaid = - 1 , $type = - 1 , $nbofopendirectdebitorcredittransfer = 0 )
2012-07-11 18:13:41 +02:00
{
2020-10-27 19:46:07 +01:00
// phpcs:enable
2022-11-08 16:21:32 +01:00
global $langs , $hookmanager ;
2012-07-11 18:13:41 +02:00
$langs -> load ( 'bills' );
2021-02-23 22:03:23 +01:00
if ( $type == - 1 ) {
$type = $this -> type ;
}
2020-11-06 11:52:48 +01:00
2020-04-10 10:59:32 +02:00
$statusType = 'status0' ;
$prefix = 'Short' ;
if ( ! $paye ) {
2020-10-27 19:46:07 +01:00
if ( $status == 0 ) {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusDraft' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusDraft' );
} elseif (( $status == 3 || $status == 2 ) && $alreadypaid <= 0 ) {
2022-08-13 12:03:41 +02:00
if ( $status == 3 ) {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusCanceled' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusCanceled' );
} else {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusClosedUnpaid' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusClosedUnpaid' );
}
2020-10-27 19:46:07 +01:00
$statusType = 'status5' ;
} elseif (( $status == 3 || $status == 2 ) && $alreadypaid > 0 ) {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusClosedPaidPartially' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusClosedPaidPartially' );
$statusType = 'status9' ;
2024-12-30 16:50:22 +01:00
} elseif ( $alreadypaid == 0 && $nbofopendirectdebitorcredittransfer == 0 ) {
2020-10-27 19:46:07 +01:00
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusNotPaid' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusNotPaid' );
$statusType = 'status1' ;
} else {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusStarted' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusStarted' );
$statusType = 'status3' ;
}
2020-05-21 15:05:19 +02:00
} else {
2020-10-27 19:46:07 +01:00
$statusType = 'status6' ;
if ( $type == self :: TYPE_CREDIT_NOTE ) {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusPaidBackOrConverted' ); // credit note
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusPaidBackOrConverted' ); // credit note
} elseif ( $type == self :: TYPE_DEPOSIT ) {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusConverted' ); // deposit invoice
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusConverted' ); // deposit invoice
} else {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusPaid' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusPaid' );
}
2012-07-11 18:13:41 +02:00
}
2019-03-15 23:00:50 +01:00
2022-11-08 16:24:05 +01:00
$parameters = array (
'status' => $status ,
'mode' => $mode ,
'paye' => $paye ,
'alreadypaid' => $alreadypaid ,
'type' => $type
);
$reshook = $hookmanager -> executeHooks ( 'LibStatut' , $parameters , $this ); // Note that $action and $object may have been modified by hook
if ( $reshook > 0 ) {
2022-11-08 16:21:32 +01:00
return $hookmanager -> resPrint ;
}
2019-11-01 12:52:03 +01:00
return dolGetStatus ( $labelStatus , $labelStatusShort , '' , $statusType , $mode );
2012-07-11 18:13:41 +02:00
}
2014-06-14 12:53:02 +02:00
2020-10-27 19:46:07 +01:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2014-06-14 12:53:02 +02:00
/**
2019-10-19 18:33:06 +02:00
* Returns an invoice payment deadline based on the invoice settlement
* conditions and billing date .
2014-06-14 12:53:02 +02:00
*
2024-01-31 21:12:21 +01:00
* @ param int $cond_reglement Condition of payment ( code or id ) to use . If 0 , we use current condition .
* @ return int | string Date limit of payment if OK , < 0 or string if KO
2014-06-14 12:53:02 +02:00
*/
2020-10-27 19:46:07 +01:00
public function calculate_date_lim_reglement ( $cond_reglement = 0 )
2014-06-14 12:53:02 +02:00
{
2020-10-27 19:46:07 +01:00
// phpcs:enable
2021-02-23 22:03:23 +01:00
if ( ! $cond_reglement ) {
$cond_reglement = $this -> cond_reglement_code ;
}
if ( ! $cond_reglement ) {
$cond_reglement = $this -> cond_reglement_id ;
}
2023-02-21 12:14:34 +01:00
if ( ! $cond_reglement ) {
return $this -> date ;
}
2014-06-14 12:53:02 +02:00
2020-04-10 10:59:32 +02:00
$cdr_nbjour = 0 ;
2020-10-27 19:46:07 +01:00
$cdr_type = 0 ;
$cdr_decalage = 0 ;
2014-06-14 12:53:02 +02:00
2022-01-27 12:52:13 +01:00
$sqltemp = " SELECT c.type_cdr, c.nbjour, c.decalage " ;
$sqltemp .= " FROM " . $this -> db -> prefix () . " c_payment_term as c " ;
2021-02-23 22:03:23 +01:00
if ( is_numeric ( $cond_reglement )) {
2021-04-24 20:18:11 +02:00
$sqltemp .= " WHERE c.rowid= " . (( int ) $cond_reglement );
2021-02-23 22:03:23 +01:00
} else {
2020-04-10 10:59:32 +02:00
$sqltemp .= " WHERE c.entity IN ( " . getEntity ( 'c_payment_term' ) . " ) " ;
2021-04-24 20:18:11 +02:00
$sqltemp .= " AND c.code = ' " . $this -> db -> escape ( $cond_reglement ) . " ' " ;
2018-03-07 17:32:57 +01:00
}
2014-06-14 12:53:02 +02:00
2014-07-02 21:29:07 +02:00
dol_syslog ( get_class ( $this ) . '::calculate_date_lim_reglement' , LOG_DEBUG );
2020-04-10 10:59:32 +02:00
$resqltemp = $this -> db -> query ( $sqltemp );
2021-02-23 22:03:23 +01:00
if ( $resqltemp ) {
if ( $this -> db -> num_rows ( $resqltemp )) {
2014-06-14 12:53:02 +02:00
$obj = $this -> db -> fetch_object ( $resqltemp );
$cdr_nbjour = $obj -> nbjour ;
2016-10-04 15:45:23 +02:00
$cdr_type = $obj -> type_cdr ;
2014-06-14 12:53:02 +02:00
$cdr_decalage = $obj -> decalage ;
}
2020-05-21 15:05:19 +02:00
} else {
2020-04-10 10:59:32 +02:00
$this -> error = $this -> db -> error ();
2014-06-14 12:53:02 +02:00
return - 1 ;
}
$this -> db -> free ( $resqltemp );
2024-01-13 19:48:20 +01:00
/* Definition de la date limit */
2014-06-14 12:53:02 +02:00
2019-10-19 18:33:06 +02:00
// 0 : adding the number of days
2021-02-23 22:03:23 +01:00
if ( $cdr_type == 0 ) {
2018-10-04 16:06:26 +02:00
$datelim = $this -> date + ( $cdr_nbjour * 3600 * 24 );
2014-06-14 12:53:02 +02:00
2018-10-04 16:06:26 +02:00
$datelim += ( $cdr_decalage * 3600 * 24 );
2021-03-01 20:37:16 +01:00
} elseif ( $cdr_type == 1 ) {
// 1 : application of the "end of the month" rule
2018-10-04 16:06:26 +02:00
$datelim = $this -> date + ( $cdr_nbjour * 3600 * 24 );
2020-04-10 10:59:32 +02:00
$mois = date ( 'm' , $datelim );
$annee = date ( 'Y' , $datelim );
2021-02-23 22:03:23 +01:00
if ( $mois == 12 ) {
2014-06-14 12:53:02 +02:00
$mois = 1 ;
$annee += 1 ;
2020-05-21 15:05:19 +02:00
} else {
2014-06-14 12:53:02 +02:00
$mois += 1 ;
}
2019-10-19 18:33:06 +02:00
// We move at the beginning of the next month, and we take a day off
2020-04-10 10:59:32 +02:00
$datelim = dol_mktime ( 12 , 0 , 0 , $mois , 1 , $annee );
2014-06-14 12:53:02 +02:00
$datelim -= ( 3600 * 24 );
2018-10-04 16:06:26 +02:00
$datelim += ( $cdr_decalage * 3600 * 24 );
2021-03-01 20:37:16 +01:00
} elseif ( $cdr_type == 2 && ! empty ( $cdr_decalage )) {
// 2 : application of the rule, the N of the current or next month
2020-10-27 19:46:07 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php' ;
2018-10-04 16:06:26 +02:00
$datelim = $this -> date + ( $cdr_nbjour * 3600 * 24 );
2017-06-09 09:25:15 +02:00
2024-08-16 20:13:02 +02:00
$date_piece = dol_mktime ( 0 , 0 , 0 , ( int ) date ( 'm' , $datelim ), ( int ) date ( 'd' , $datelim ), ( int ) date ( 'Y' , $datelim )); // Sans les heures minutes et secondes
$date_lim_current = dol_mktime ( 0 , 0 , 0 , ( int ) date ( 'm' , $datelim ), ( int ) $cdr_decalage , ( int ) date ( 'Y' , $datelim )); // Sans les heures minutes et secondes
$date_lim_next = dol_time_plus_duree (( int ) $date_lim_current , 1 , 'm' ); // Add 1 month
2017-06-09 09:25:15 +02:00
2016-10-04 15:45:23 +02:00
$diff = $date_piece - $date_lim_current ;
2017-06-09 09:25:15 +02:00
2021-02-23 22:03:23 +01:00
if ( $diff < 0 ) {
$datelim = $date_lim_current ;
} else {
$datelim = $date_lim_next ;
}
2020-06-27 02:00:42 +02:00
} else {
return 'Bad value for type_cdr in database for record cond_reglement = ' . $cond_reglement ;
}
2014-06-14 12:53:02 +02:00
return $datelim ;
}
2020-06-24 19:59:06 +02:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Create a withdrawal request for a direct debit order or a credit transfer order .
* Use the remain to pay excluding all existing open direct debit requests .
*
2024-10-30 23:15:33 +01:00
* @ param User $fuser User asking the direct debit transfer
* @ param float $amount Amount we request direct debit for
* @ param string $type 'direct-debit' or 'bank-transfer'
* @ param string $sourcetype Source ( 'facture' or 'supplier_invoice' )
* @ param int $checkduplicateamongall 0 = Default ( check among open requests only to find if request already exists ) . 1 = Check also among requests completely processed and cancel if at least 1 request exists whatever is its status .
* @ param int $ribId If defined , will use this ID to get the RIB . Otherwise , the default RIB will be taken .
* @ return int Return integer < 0 if KO , 0 if a request already exists , > 0 if OK
2020-06-24 19:59:06 +02:00
*/
2024-10-30 23:15:33 +01:00
public function demande_prelevement ( User $fuser , float $amount = 0 , string $type = 'direct-debit' , string $sourcetype = 'facture' , int $checkduplicateamongall = 0 , int $ribId = 0 )
2020-06-24 19:59:06 +02:00
{
// phpcs:enable
global $conf ;
$error = 0 ;
dol_syslog ( get_class ( $this ) . " ::demande_prelevement " , LOG_DEBUG );
2023-08-10 12:57:31 +02:00
if ( $this -> status > self :: STATUS_DRAFT && $this -> paye == 0 ) {
2020-06-24 19:59:06 +02:00
require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php' ;
$bac = new CompanyBankAccount ( $this -> db );
2024-10-30 23:15:33 +01:00
$bac -> fetch ( $ribId , '' , $this -> socid );
2020-06-24 19:59:06 +02:00
2023-08-14 15:40:22 +02:00
$sql = " SELECT count(rowid) as nb " ;
2022-10-28 17:51:25 +02:00
$sql .= " FROM " . $this -> db -> prefix () . " prelevement_demande " ;
2020-06-24 19:59:06 +02:00
if ( $type == 'bank-transfer' ) {
2022-01-27 12:52:13 +01:00
$sql .= " WHERE fk_facture_fourn = " . (( int ) $this -> id );
2020-06-24 19:59:06 +02:00
} else {
2022-01-27 12:52:13 +01:00
$sql .= " WHERE fk_facture = " . (( int ) $this -> id );
2020-06-24 19:59:06 +02:00
}
2023-02-24 23:15:54 +01:00
$sql .= " AND type = 'ban' " ; // To exclude record done for some online payments
2023-08-14 15:40:22 +02:00
if ( empty ( $checkduplicateamongall )) {
$sql .= " AND traite = 0 " ;
}
2020-06-24 19:59:06 +02:00
dol_syslog ( get_class ( $this ) . " ::demande_prelevement " , LOG_DEBUG );
2023-08-14 15:40:22 +02:00
2020-06-24 19:59:06 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2023-08-14 15:40:22 +02:00
$obj = $this -> db -> fetch_object ( $resql );
if ( $obj && $obj -> nb == 0 ) { // If no request found yet
2020-06-24 19:59:06 +02:00
$now = dol_now ();
2022-05-22 17:09:08 +02:00
$totalpaid = $this -> getSommePaiement ();
2020-06-24 19:59:06 +02:00
$totalcreditnotes = $this -> getSumCreditNotesUsed ();
$totaldeposits = $this -> getSumDepositsUsed ();
2022-05-22 17:09:08 +02:00
//print "totalpaid=".$totalpaid." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits;
2020-06-24 19:59:06 +02:00
// We can also use bcadd to avoid pb with floating points
// For example print 239.2 - 229.3 - 9.9; does not return 0.
2022-05-22 17:09:08 +02:00
//$resteapayer=bcadd($this->total_ttc,$totalpaid,$conf->global->MAIN_MAX_DECIMALS_TOT);
2020-06-24 19:59:06 +02:00
//$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
2021-02-23 22:03:23 +01:00
if ( empty ( $amount )) {
2022-05-22 17:09:08 +02:00
$amount = price2num ( $this -> total_ttc - $totalpaid - $totalcreditnotes - $totaldeposits , 'MT' );
2021-02-23 22:03:23 +01:00
}
2020-06-24 19:59:06 +02:00
2021-02-23 22:03:23 +01:00
if ( is_numeric ( $amount ) && $amount != 0 ) {
2022-10-28 17:51:25 +02:00
$sql = 'INSERT INTO ' . $this -> db -> prefix () . 'prelevement_demande(' ;
2020-06-24 19:59:06 +02:00
if ( $type == 'bank-transfer' ) {
$sql .= 'fk_facture_fourn, ' ;
} else {
$sql .= 'fk_facture, ' ;
}
2024-10-30 23:15:33 +01:00
$sql .= ' amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib, sourcetype, type, entity' ;
if ( empty ( $bac -> id )) {
$sql .= ')' ;
} else {
$sql .= ', fk_societe_rib)' ;
}
2021-09-30 15:24:57 +02:00
$sql .= " VALUES ( " . (( int ) $this -> id );
2021-08-27 23:36:06 +02:00
$sql .= " , " . (( float ) price2num ( $amount ));
$sql .= " , ' " . $this -> db -> idate ( $now ) . " ' " ;
$sql .= " , " . (( int ) $fuser -> id );
$sql .= " , ' " . $this -> db -> escape ( $bac -> code_banque ) . " ' " ;
$sql .= " , ' " . $this -> db -> escape ( $bac -> code_guichet ) . " ' " ;
$sql .= " , ' " . $this -> db -> escape ( $bac -> number ) . " ' " ;
$sql .= " , ' " . $this -> db -> escape ( $bac -> cle_rib ) . " ' " ;
$sql .= " , ' " . $this -> db -> escape ( $sourcetype ) . " ' " ;
2023-02-24 23:15:54 +01:00
$sql .= " , 'ban' " ;
2021-08-27 23:36:06 +02:00
$sql .= " , " . (( int ) $conf -> entity );
2024-10-30 23:15:33 +01:00
if ( ! empty ( $bac -> id )) {
$sql .= " , ' " . $this -> db -> escape ( $bac -> id ) . " ' " ;
}
2020-06-24 19:59:06 +02:00
$sql .= " ) " ;
dol_syslog ( get_class ( $this ) . " ::demande_prelevement " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2020-06-27 02:00:42 +02:00
if ( ! $resql ) {
2020-06-24 19:59:06 +02:00
$this -> error = $this -> db -> lasterror ();
dol_syslog ( get_class ( $this ) . '::demandeprelevement Erreur' );
$error ++ ;
}
2020-06-27 02:00:42 +02:00
} else {
2020-06-24 19:59:06 +02:00
$this -> error = 'WithdrawRequestErrorNilAmount' ;
dol_syslog ( get_class ( $this ) . '::demandeprelevement WithdrawRequestErrorNilAmount' );
$error ++ ;
}
2020-06-27 02:00:42 +02:00
if ( ! $error ) {
2020-06-24 19:59:06 +02:00
// Force payment mode of invoice to withdraw
2020-11-04 11:15:41 +01:00
$payment_mode_id = dol_getIdFromCode ( $this -> db , ( $type == 'bank-transfer' ? 'VIR' : 'PRE' ), 'c_paiement' , 'code' , 'id' , 1 );
2020-06-27 02:00:42 +02:00
if ( $payment_mode_id > 0 ) {
2020-06-24 19:59:06 +02:00
$result = $this -> setPaymentMethods ( $payment_mode_id );
}
}
2021-02-23 22:03:23 +01:00
if ( $error ) {
return - 1 ;
}
2020-06-24 19:59:06 +02:00
return 1 ;
2020-06-27 02:00:42 +02:00
} else {
2020-06-24 19:59:06 +02:00
$this -> error = " A request already exists " ;
2023-08-10 12:57:31 +02:00
dol_syslog ( get_class ( $this ) . '::demandeprelevement Can t create a request to generate a direct debit, a request already exists.' );
2020-06-24 19:59:06 +02:00
return 0 ;
}
2020-06-27 02:00:42 +02:00
} else {
2020-06-24 19:59:06 +02:00
$this -> error = $this -> db -> error ();
2023-08-10 12:57:31 +02:00
dol_syslog ( get_class ( $this ) . '::demandeprelevement Error -2' );
2020-06-24 19:59:06 +02:00
return - 2 ;
}
2020-06-27 02:00:42 +02:00
} else {
2020-06-24 19:59:06 +02:00
$this -> error = " Status of invoice does not allow this " ;
2023-08-10 12:57:31 +02:00
dol_syslog ( get_class ( $this ) . " ::demandeprelevement " . $this -> error . " $this->status , $this->paye , $this->mode_reglement_id " );
2020-06-24 19:59:06 +02:00
return - 3 ;
}
}
2022-09-09 04:10:48 +02:00
2023-08-04 00:13:29 +02:00
/**
* Create a payment with Stripe card
* Must take amount using Stripe and record an event into llx_actioncomm
* Record bank payment
* Send email to customer ?
*
* @ param User $fuser User asking the direct debit transfer
* @ param int $id Invoice ID with remain to pay
* @ param string $sourcetype Source ( 'facture' or 'supplier_invoice' )
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2023-08-04 00:13:29 +02:00
*/
public function makeStripeCardRequest ( $fuser , $id , $sourcetype = 'facture' )
{
// TODO See in sellyoursaas
2023-12-01 23:15:10 +01:00
return 0 ;
2023-08-04 00:13:29 +02:00
}
2022-09-09 04:10:48 +02:00
/**
2023-08-24 01:37:04 +02:00
* Create a direct debit order into prelevement_bons for a given prelevement_request , then
* Send the payment order to the service ( for a direct debit order or a credit transfer order ) and record an event in llx_actioncomm .
2022-09-09 04:10:48 +02:00
*
* @ param User $fuser User asking the direct debit transfer
2023-02-24 23:15:54 +01:00
* @ param int $did ID of unitary payment request to pay
2022-09-09 04:10:48 +02:00
* @ param string $type 'direct-debit' or 'bank-transfer'
* @ param string $sourcetype Source ( 'facture' or 'supplier_invoice' )
2023-08-24 01:37:04 +02:00
* @ param string $service 'StripeTest' , 'StripeLive' , ...
2023-08-25 21:57:16 +02:00
* @ param string $forcestripe To force another stripe env : 'cus_account@pk_...:sk_...'
2023-12-01 19:51:32 +01:00
* @ return int Return integer < 0 if KO , > 0 if OK
2022-09-09 04:10:48 +02:00
*/
2023-08-24 01:37:04 +02:00
public function makeStripeSepaRequest ( $fuser , $did , $type = 'direct-debit' , $sourcetype = 'facture' , $service = '' , $forcestripe = '' )
2022-09-09 04:10:48 +02:00
{
2023-08-04 00:13:29 +02:00
global $conf , $user , $langs ;
2022-09-09 04:10:48 +02:00
2023-11-27 11:24:19 +01:00
if ( $type != 'bank-transfer' && $type != 'credit-transfer' && ! getDolGlobalString ( 'STRIPE_SEPA_DIRECT_DEBIT' )) {
2023-03-04 12:16:38 +01:00
return 0 ;
}
2023-11-27 11:24:19 +01:00
if ( $type != 'direct-debit' && ! getDolGlobalString ( 'STRIPE_SEPA_CREDIT_TRANSFER' )) {
2022-09-09 04:10:48 +02:00
return 0 ;
}
2023-08-24 01:37:04 +02:00
// Set a default value for service if not provided
if ( empty ( $service )) {
$service = 'StripeTest' ;
2023-11-27 11:24:19 +01:00
if ( getDolGlobalString ( 'STRIPE_LIVE' ) && ! GETPOST ( 'forcesandbox' , 'alpha' )) {
2023-08-24 01:37:04 +02:00
$service = 'StripeLive' ;
}
}
2022-09-09 04:10:48 +02:00
$error = 0 ;
2023-08-25 19:18:23 +02:00
dol_syslog ( get_class ( $this ) . " ::makeStripeSepaRequest start did= " . $did . " type= " . $type . " service= " . $service . " sourcetype= " . $sourcetype . " forcestripe= " . $forcestripe , LOG_DEBUG );
2022-09-09 04:10:48 +02:00
2023-08-10 12:57:31 +02:00
if ( $this -> status > self :: STATUS_DRAFT && $this -> paye == 0 ) {
2023-02-27 15:58:15 +01:00
// Get the default payment mode for BAN payment of the third party
2022-09-09 04:10:48 +02:00
require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php' ;
2024-04-24 21:53:40 +02:00
$bac = new CompanyBankAccount ( $this -> db ); // Table societe_rib
2024-04-27 12:45:50 +02:00
$result = $bac -> fetch ( 0 , '' , $this -> socid , 1 , 'ban' );
2022-10-13 05:31:36 +02:00
if ( $result <= 0 || empty ( $bac -> id )) {
$this -> error = $langs -> trans ( " ThirdpartyHasNoDefaultBanAccount " );
$this -> errors [] = $this -> error ;
dol_syslog ( get_class ( $this ) . " ::makeStripeSepaRequest " . $this -> error );
return - 1 ;
}
2022-09-09 04:10:48 +02:00
2023-08-10 12:57:31 +02:00
// Load the pending payment request to process (with rowid=$did)
2023-12-14 14:48:22 +01:00
$sql = " SELECT rowid, date_demande, amount, fk_facture, fk_facture_fourn, fk_salary, fk_prelevement_bons " ;
2022-10-28 17:51:25 +02:00
$sql .= " FROM " . $this -> db -> prefix () . " prelevement_demande " ;
2022-10-13 05:31:36 +02:00
$sql .= " WHERE rowid = " . (( int ) $did );
2023-03-08 03:16:59 +01:00
if ( $type != 'bank-transfer' && $type != 'credit-transfer' ) {
2023-12-14 14:48:22 +01:00
$sql .= " AND fk_facture = " . (( int ) $this -> id ); // Add a protection to not pay another invoice than current one
2023-03-04 12:16:38 +01:00
}
2023-03-08 03:16:59 +01:00
if ( $type != 'direct-debit' ) {
2024-03-03 18:55:30 +01:00
if ( $sourcetype == 'salary' ) {
2023-12-14 14:48:22 +01:00
$sql .= " AND fk_salary = " . (( int ) $this -> id ); // Add a protection to not pay another salary than current one
} else {
$sql .= " AND fk_facture_fourn = " . (( int ) $this -> id ); // Add a protection to not pay another invoice than current one
}
2023-03-04 12:16:38 +01:00
}
2023-08-03 23:00:39 +02:00
$sql .= " AND traite = 0 " ; // To not process payment request that were already converted into a direct debit or credit transfer order (Note: fk_prelevement_bons is also empty when traite = 0)
2022-09-09 04:10:48 +02:00
2023-02-24 23:15:54 +01:00
dol_syslog ( get_class ( $this ) . " ::makeStripeSepaRequest load requests to process " , LOG_DEBUG );
2022-09-09 04:10:48 +02:00
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
2022-10-13 05:31:36 +02:00
$obj = $this -> db -> fetch_object ( $resql );
if ( ! $obj ) {
dol_print_error ( $this -> db , 'CantFindRequestWithId' );
return - 2 ;
}
2022-09-09 04:10:48 +02:00
2023-02-24 23:15:54 +01:00
// amount to pay
2022-10-13 05:31:36 +02:00
$amount = $obj -> amount ;
2022-09-09 04:10:48 +02:00
2022-10-13 05:31:36 +02:00
if ( is_numeric ( $amount ) && $amount != 0 ) {
require_once DOL_DOCUMENT_ROOT . '/societe/class/companypaymentmode.class.php' ;
2023-02-24 23:15:54 +01:00
$companypaymentmode = new CompanyPaymentMode ( $this -> db ); // table societe_rib
2022-10-13 05:31:36 +02:00
$companypaymentmode -> fetch ( $bac -> id );
2022-09-09 04:10:48 +02:00
2022-10-13 05:31:36 +02:00
$this -> stripechargedone = 0 ;
$this -> stripechargeerror = 0 ;
2023-02-24 23:15:54 +01:00
2022-10-13 05:31:36 +02:00
$now = dol_now ();
2022-09-09 04:10:48 +02:00
2022-10-13 05:31:36 +02:00
$currency = $conf -> currency ;
2022-09-09 04:10:48 +02:00
2022-10-13 05:31:36 +02:00
$errorforinvoice = 0 ; // We reset the $errorforinvoice at each invoice loop
2022-09-09 04:10:48 +02:00
2022-10-13 05:31:36 +02:00
$this -> fetch_thirdparty ();
2022-09-09 04:10:48 +02:00
2024-01-18 00:42:43 +01:00
dol_syslog ( " makeStripeSepaRequest Process payment request amount= " . $amount . " thirdparty_id= " . $this -> thirdparty -> id . " , thirdparty_name= " . $this -> thirdparty -> name . " ban id= " . $bac -> id , LOG_DEBUG );
2022-09-09 04:10:48 +02:00
2023-02-24 23:15:54 +01:00
//$alreadypayed = $this->getSommePaiement();
//$amount_credit_notes_included = $this->getSumCreditNotesUsed();
//$amounttopay = $this->total_ttc - $alreadypayed - $amount_credit_notes_included;
$amounttopay = $amount ;
2022-09-09 04:10:48 +02:00
2022-10-13 05:31:36 +02:00
// Correct the amount according to unit of currency
// See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
$arrayzerounitcurrency = [ 'BIF' , 'CLP' , 'DJF' , 'GNF' , 'JPY' , 'KMF' , 'KRW' , 'MGA' , 'PYG' , 'RWF' , 'VND' , 'VUV' , 'XAF' , 'XOF' , 'XPF' ];
$amountstripe = $amounttopay ;
if ( ! in_array ( $currency , $arrayzerounitcurrency )) {
2024-08-07 02:53:45 +02:00
$amountstripe *= 100 ;
2022-10-13 05:31:36 +02:00
}
2022-09-09 04:10:48 +02:00
2023-03-04 12:16:38 +01:00
$fk_bank_account = getDolGlobalInt ( 'STRIPE_BANK_ACCOUNT_FOR_PAYMENTS' ); // Bank account used for SEPA direct debit or credit transfer. Must be the Stripe account in Dolibarr.
2023-02-27 15:58:15 +01:00
if ( ! ( $fk_bank_account > 0 )) {
$error ++ ;
$errorforinvoice ++ ;
2024-01-18 00:42:43 +01:00
dol_syslog ( " makeStripeSepaRequest Error no bank account defined for Stripe payments " , LOG_ERR );
2025-01-02 17:32:36 +01:00
$this -> error = " Error bank account for Stripe payments not defined into Stripe module " ;
$this -> errors [] = $this -> error ;
2023-02-27 15:58:15 +01:00
}
2023-02-24 23:15:54 +01:00
$this -> db -> begin ();
// Create a prelevement_bon
2023-05-12 11:20:25 +02:00
require_once DOL_DOCUMENT_ROOT . '/compta/prelevement/class/bonprelevement.class.php' ;
2023-02-24 23:15:54 +01:00
$bon = new BonPrelevement ( $this -> db );
2023-02-27 15:58:15 +01:00
if ( ! $error ) {
if ( empty ( $obj -> fk_prelevement_bons )) {
2023-08-10 12:57:31 +02:00
// This creates a record into llx_prelevement_bons and updates link with llx_prelevement_demande
2024-11-10 01:47:19 +01:00
$nbinvoices = $bon -> create ( 0 , 0 , 'real' , 'ALL' , 0 , 0 , $type , $did , $fk_bank_account );
2023-02-27 15:58:15 +01:00
if ( $nbinvoices <= 0 ) {
2023-02-24 23:15:54 +01:00
$error ++ ;
2023-02-27 15:58:15 +01:00
$errorforinvoice ++ ;
2024-01-18 00:42:43 +01:00
dol_syslog ( " makeStripeSepaRequest Error on BonPrelevement creation " , LOG_ERR );
2025-01-02 17:32:36 +01:00
$this -> error = " Error on BonPrelevement creation " ;
$this -> errors [] = $this -> error ;
2023-02-27 15:58:15 +01:00
}
/*
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 ++ ;
2025-01-02 17:32:36 +01:00
$this -> error = " Error on updating fk_prelevement_bons to " . $bon -> id ;
$this -> errors [] = $this -> error ;
2023-02-27 15:58:15 +01:00
}
2023-02-24 23:15:54 +01:00
}
2023-02-27 15:58:15 +01:00
*/
} else {
$error ++ ;
$errorforinvoice ++ ;
2024-01-18 00:42:43 +01:00
dol_syslog ( " makeStripeSepaRequest Error Line already part of a bank payment order " , LOG_ERR );
2025-01-02 17:32:36 +01:00
$this -> error = " The line is already included into a bank payment order. Delete the bank payment order first. " ;
$this -> errors [] = $this -> error ;
2023-02-24 23:15:54 +01:00
}
}
2024-10-13 16:45:42 +02:00
$paymentintent = null ;
2023-02-27 15:58:15 +01:00
if ( ! $error ) {
if ( $amountstripe > 0 ) {
try {
2023-08-24 01:37:04 +02:00
global $savstripearrayofkeysbyenv ;
global $stripearrayofkeysbyenv ;
$servicestatus = 0 ;
if ( $service == 'StripeLive' ) {
$servicestatus = 1 ;
}
2023-02-27 15:58:15 +01:00
//var_dump($companypaymentmode);
2024-01-18 00:42:43 +01:00
dol_syslog ( " makeStripeSepaRequest We will try to pay with companypaymentmodeid= " . $companypaymentmode -> id . " stripe_card_ref= " . $companypaymentmode -> stripe_card_ref . " mode= " . $companypaymentmode -> status , LOG_DEBUG );
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
$thirdparty = new Societe ( $this -> db );
$resultthirdparty = $thirdparty -> fetch ( $this -> socid );
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
include_once DOL_DOCUMENT_ROOT . '/stripe/class/stripe.class.php' ; // This include the include of htdocs/stripe/config.php
// So it inits or erases the $stripearrayofkeysbyenv
$stripe = new Stripe ( $this -> db );
2022-10-13 05:31:36 +02:00
2023-12-04 12:04:36 +01:00
if ( empty ( $savstripearrayofkeysbyenv )) {
$savstripearrayofkeysbyenv = $stripearrayofkeysbyenv ;
}
2023-02-27 15:58:15 +01:00
dol_syslog ( " makeStripeSepaRequest Current Stripe environment is " . $stripearrayofkeysbyenv [ $servicestatus ][ 'publishable_key' ]);
2023-08-24 01:37:04 +02:00
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 ( $forcestripe )) {
dol_syslog ( " makeStripeSepaRequest A dedicated stripe account was forced, so we switch to it. " );
$tmparray = explode ( '@' , $forcestripe );
if ( ! empty ( $tmparray [ 1 ])) {
$tmparray2 = explode ( ':' , $tmparray [ 1 ]);
2023-08-25 21:57:16 +02:00
if ( ! empty ( $tmparray2 [ 1 ])) {
$stripearrayofkeysbyenv [ $servicestatus ][ " publishable_key " ] = $tmparray2 [ 0 ];
$stripearrayofkeysbyenv [ $servicestatus ][ " secret_key " ] = $tmparray2 [ 1 ];
2023-08-24 01:37:04 +02:00
$stripearrayofkeys = $stripearrayofkeysbyenv [ $servicestatus ];
\Stripe\Stripe :: setApiKey ( $stripearrayofkeys [ 'secret_key' ]);
$foundalternativestripeaccount = $tmparray [ 0 ]; // Store the customer id
dol_syslog ( " makeStripeSepaRequest 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 ( " makeStripeSepaRequest 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 ( " makeStripeSepaRequest No dedicated Stripe Account requested, so we use global one, so " . $stripearrayofkeys [ 'publishable_key' ], LOG_DEBUG );
}
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
$stripeacc = $stripe -> getStripeAccount ( $service , $this -> socid ); // Get Stripe OAuth connect account if it exists (no network access here)
2022-09-09 04:10:48 +02:00
2023-08-24 01:37:04 +02:00
if ( $foundalternativestripeaccount ) {
if ( empty ( $stripeacc )) { // If the Stripe connect account not set, we use common API usage
2024-03-13 00:29:19 +01:00
$customer = \Stripe\Customer :: retrieve ( array ( 'id' => " $foundalternativestripeaccount " , 'expand[]' => 'sources' ));
2023-08-24 01:37:04 +02:00
} else {
2024-03-13 00:29:19 +01:00
$customer = \Stripe\Customer :: retrieve ( array ( 'id' => " $foundalternativestripeaccount " , 'expand[]' => 'sources' ), array ( " stripe_account " => $stripeacc ));
2023-08-24 01:37:04 +02:00
}
} else {
$customer = $stripe -> customerStripe ( $thirdparty , $stripeacc , $servicestatus , 0 );
if ( empty ( $customer ) && ! empty ( $stripe -> error )) {
2025-01-02 17:32:36 +01:00
$this -> error = $stripe -> error ;
$this -> errors [] = $this -> error ;
2023-08-24 01:37:04 +02:00
}
/* if ( ! empty ( $customer ) && empty ( $customer -> sources )) {
$customer = null ;
2025-01-02 17:32:36 +01:00
$this -> error = '\Stripe\Customer::retrieve did not returned the sources' ;
$this -> errors [] = $this -> error ;
2023-08-24 01:37:04 +02:00
} */
2023-02-27 15:58:15 +01:00
}
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
// $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);
$postactionmessages = [];
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
if ( $resultthirdparty > 0 && ! empty ( $customer )) {
if ( ! $error ) { // Payment was not canceled
$stripecard = null ;
if ( $companypaymentmode -> type == 'ban' ) {
// Check into societe_rib if a payment mode for Stripe and ban payment exists
2024-01-13 19:48:20 +01:00
// To make a Stripe SEPA payment request, we must have the payment mode source already saved into societe_rib and retrieved with ->sepaStripe
2023-02-27 15:58:15 +01:00
// The payment mode source is created when we create the bank account on Stripe with paymentmodes.php?action=create
$stripecard = $stripe -> sepaStripe ( $customer , $companypaymentmode , $stripeacc , $servicestatus , 0 );
2023-03-04 12:16:38 +01:00
} else {
$error ++ ;
$this -> error = 'The payment mode type is not "ban"' ;
2022-10-13 05:31:36 +02:00
}
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
if ( $stripecard ) { // Can be src_... (for sepa) or pm_... (new card mode). Note that card_... (old card mode) should not happen here.
$FULLTAG = 'DID=' . $did . '-INV=' . $this -> id . '-CUS=' . $thirdparty -> id ;
$description = 'Stripe payment from makeStripeSepaRequest: ' . $FULLTAG . ' did=' . $did . ' ref=' . $this -> ref ;
$stripefailurecode = '' ;
$stripefailuremessage = '' ;
$stripefailuredeclinecode = '' ;
// Using new SCA method
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 , 1 , $did );
$charge = new stdClass ();
if ( $paymentintent -> status === 'succeeded' || $paymentintent -> status === 'processing' ) {
$charge -> status = 'ok' ;
$charge -> id = $paymentintent -> id ;
$charge -> customer = $customer -> id ;
} elseif ( $paymentintent -> status === 'requires_action' ) {
//paymentintent->status may be => 'requires_action' (no error in such a case)
dol_syslog ( var_export ( $paymentintent , true ), LOG_DEBUG );
$charge -> status = 'failed' ;
$charge -> customer = $customer -> id ;
$charge -> failure_code = $stripe -> code ;
$charge -> failure_message = $stripe -> error ;
$charge -> failure_declinecode = $stripe -> declinecode ;
$stripefailurecode = $stripe -> code ;
$stripefailuremessage = 'Action required. Contact the support at ' ; // . $conf->global->SELLYOURSAAS_MAIN_EMAIL;
$stripefailuredeclinecode = $stripe -> declinecode ;
} else {
dol_syslog ( var_export ( $paymentintent , true ), LOG_DEBUG );
$charge -> status = 'failed' ;
$charge -> customer = $customer -> id ;
$charge -> failure_code = $stripe -> code ;
$charge -> failure_message = $stripe -> error ;
$charge -> failure_declinecode = $stripe -> declinecode ;
$stripefailurecode = $stripe -> code ;
$stripefailuremessage = $stripe -> error ;
$stripefailuredeclinecode = $stripe -> declinecode ;
}
2022-10-13 05:31:36 +02:00
2023-02-27 15:58:15 +01:00
//var_dump("stripefailurecode=".$stripefailurecode." stripefailuremessage=".$stripefailuremessage." stripefailuredeclinecode=".$stripefailuredeclinecode);
//exit;
// Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...)
if ( empty ( $charge ) || $charge -> status == 'failed' ) {
dol_syslog ( 'Failed to charge payment mode ' . $stripecard -> id . ' stripefailurecode=' . $stripefailurecode . ' stripefailuremessage=' . $stripefailuremessage . ' stripefailuredeclinecode=' . $stripefailuredeclinecode , LOG_WARNING );
// Save a stripe payment was in error
$this -> stripechargeerror ++ ;
$error ++ ;
$errorforinvoice ++ ;
2025-01-03 14:23:58 +01:00
$errmsg = $langs -> trans ( " FailedToChargeSEPA " );
2023-02-27 15:58:15 +01:00
if ( ! empty ( $charge )) {
if ( $stripefailuredeclinecode == 'authentication_required' ) {
$errauthenticationmessage = $langs -> trans ( " ErrSCAAuthentication " );
$errmsg = $errauthenticationmessage ;
} elseif ( in_array ( $stripefailuredeclinecode , [ 'insufficient_funds' , 'generic_decline' ])) {
$errmsg .= ': ' . $charge -> failure_code ;
$errmsg .= ( $charge -> failure_message ? ' - ' : '' ) . ' ' . $charge -> failure_message ;
if ( empty ( $stripefailurecode )) {
$stripefailurecode = $charge -> failure_code ;
}
if ( empty ( $stripefailuremessage )) {
$stripefailuremessage = $charge -> failure_message ;
}
} else {
$errmsg .= ': failure_code=' . $charge -> failure_code ;
$errmsg .= ( $charge -> failure_message ? ' - ' : '' ) . ' failure_message=' . $charge -> failure_message ;
if ( empty ( $stripefailurecode )) {
$stripefailurecode = $charge -> failure_code ;
}
if ( empty ( $stripefailuremessage )) {
$stripefailuremessage = $charge -> failure_message ;
}
2022-09-09 04:10:48 +02:00
}
} else {
2023-02-27 15:58:15 +01:00
$errmsg .= ': ' . $stripefailurecode . ' - ' . $stripefailuremessage ;
$errmsg .= ( $stripefailuredeclinecode ? ' - ' . $stripefailuredeclinecode : '' );
2022-09-09 04:10:48 +02:00
}
2023-02-27 15:58:15 +01:00
$description = 'Stripe payment ERROR from makeStripeSepaRequest: ' . $FULLTAG ;
$postactionmessages [] = $errmsg . ' (' . $stripearrayofkeys [ 'publishable_key' ] . ')' ;
2025-01-02 17:32:36 +01:00
$this -> error = $errmsg ;
$this -> errors [] = $this -> error ;
2022-09-09 04:10:48 +02:00
} else {
2023-03-04 12:16:38 +01:00
dol_syslog ( 'Successfuly request ' . $type . ' ' . $stripecard -> id );
2022-09-09 04:10:48 +02:00
2023-03-04 12:16:38 +01:00
$postactionmessages [] = 'Success to request ' . $type . ' (' . $charge -> id . ' with ' . $stripearrayofkeys [ 'publishable_key' ] . ')' ;
2022-09-09 04:10:48 +02:00
2024-01-13 19:48:20 +01:00
// Save a stripe payment was done in real life so later we will be able to force a commit on recorded payments
2023-02-27 15:58:15 +01:00
// even if in batch mode (method doTakePaymentStripe), we will always make all action in one transaction with a forced commit.
$this -> stripechargedone ++ ;
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
// Default description used for label of event. Will be overwrite by another value later.
$description = 'Stripe payment request OK (' . $charge -> id . ') from makeStripeSepaRequest: ' . $FULLTAG ;
}
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
$object = $this ;
2022-10-13 05:31:36 +02:00
2023-02-27 15:58:15 +01:00
// Track an event
if ( empty ( $charge ) || $charge -> status == 'failed' ) {
$actioncode = 'PAYMENT_STRIPE_KO' ;
$extraparams = $stripefailurecode ;
$extraparams .= (( $extraparams && $stripefailuremessage ) ? ' - ' : '' ) . $stripefailuremessage ;
$extraparams .= (( $extraparams && $stripefailuredeclinecode ) ? ' - ' : '' ) . $stripefailuredeclinecode ;
} else {
$actioncode = 'PAYMENT_STRIPE_OK' ;
$extraparams = '' ;
}
} else {
$error ++ ;
$errorforinvoice ++ ;
2023-03-04 12:16:38 +01:00
dol_syslog ( " No ban payment method found for this stripe customer " . $customer -> id , LOG_WARNING );
2025-01-02 17:32:36 +01:00
$this -> error = 'Failed to get direct debit payment method for stripe customer = ' . $customer -> id ;
$this -> errors [] = $this -> error ;
2023-02-27 15:58:15 +01:00
2023-03-04 12:16:38 +01:00
$description = 'Failed to find or use the payment mode - no ban defined for the thirdparty account' ;
2023-02-27 15:58:15 +01:00
$stripefailurecode = 'BADPAYMENTMODE' ;
2023-03-04 12:16:38 +01:00
$stripefailuremessage = 'Failed to find or use the payment mode - no ban defined for the thirdparty account' ;
2023-02-27 15:58:15 +01:00
$postactionmessages [] = $description . ' (' . $stripearrayofkeys [ 'publishable_key' ] . ')' ;
$object = $this ;
2022-09-09 04:10:48 +02:00
2023-01-18 14:43:09 +01:00
$actioncode = 'PAYMENT_STRIPE_KO' ;
$extraparams = '' ;
}
2022-09-09 04:10:48 +02:00
} else {
2023-02-27 15:58:15 +01:00
// If error because payment was canceled for a logical reason, we do nothing (no event added)
$description = '' ;
$stripefailurecode = '' ;
$stripefailuremessage = '' ;
2023-01-18 14:43:09 +01:00
$object = $this ;
2023-02-27 15:58:15 +01:00
$actioncode = '' ;
2022-09-09 04:10:48 +02:00
$extraparams = '' ;
}
2023-02-27 15:58:15 +01:00
} else { // Else of the if ($resultthirdparty > 0 && ! empty($customer)) {
if ( $resultthirdparty <= 0 ) {
dol_syslog ( 'SellYourSaasUtils Failed to load customer for thirdparty_id = ' . $thirdparty -> id , LOG_WARNING );
2025-01-02 17:32:36 +01:00
$this -> error = 'Failed to load Stripe account for thirdparty_id = ' . $thirdparty -> id ;
$this -> errors [] = $this -> error ;
2023-02-27 15:58:15 +01:00
} else { // $customer stripe not found
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 );
2025-01-02 17:32:36 +01:00
$this -> error = 'Failed to get Stripe account id for thirdparty_id = ' . $thirdparty -> id . " in mode " . $servicestatus . " in Stripe env " . $stripearrayofkeysbyenv [ $servicestatus ][ 'publishable_key' ];
$this -> errors [] = $this -> error ;
2023-02-27 15:58:15 +01:00
}
$error ++ ;
$errorforinvoice ++ ;
$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)' ;
2024-05-30 13:37:17 +02:00
$postactionmessages = [];
2022-09-09 04:10:48 +02:00
2023-01-18 14:43:09 +01:00
$object = $this ;
2022-09-09 04:10:48 +02:00
2023-02-27 15:58:15 +01:00
$actioncode = 'PAYMENT_STRIPE_KO' ;
2022-09-09 04:10:48 +02:00
$extraparams = '' ;
}
2023-02-27 15:58:15 +01:00
if ( $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)
$actioncomm = new ActionComm ( $this -> db );
$actioncomm -> type_code = 'AC_OTH_AUTO' ; // Type of event ('AC_OTH', 'AC_OTH_AUTO', 'AC_XXX'...)
$actioncomm -> code = 'AC_' . $actioncode ;
$actioncomm -> label = $description ;
Qual: Apply automatic phan fixes (deprecations, unneeded imports) (#28154)
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
* Qual: Apply automatic phan fixes (deprecations, unneeded imports)
# Qual: Apply automatic phan fixes (deprecations, unneeded imports)
This applies automatic fixes by phan for deprecated functions, unneeded imports).
2024-02-13 21:46:12 +01:00
$actioncomm -> note_private = implode ( " , \n " , $postactionmessages );
2023-02-27 15:58:15 +01:00
$actioncomm -> fk_project = $this -> fk_project ;
$actioncomm -> datep = $now ;
$actioncomm -> datef = $now ;
$actioncomm -> percentage = - 1 ; // Not applicable
$actioncomm -> socid = $thirdparty -> id ;
$actioncomm -> contactid = 0 ;
$actioncomm -> authorid = $user -> id ; // User saving action
$actioncomm -> userownerid = $user -> id ; // Owner of action
// Fields when action is a real email (content is already into note)
/* $actioncomm -> email_msgid = $object -> email_msgid ;
$actioncomm -> email_from = $object -> email_from ;
$actioncomm -> email_sender = $object -> email_sender ;
$actioncomm -> email_to = $object -> email_to ;
$actioncomm -> email_tocc = $object -> email_tocc ;
$actioncomm -> email_tobcc = $object -> email_tobcc ;
$actioncomm -> email_subject = $object -> email_subject ;
$actioncomm -> errors_to = $object -> errors_to ; */
$actioncomm -> fk_element = $this -> id ;
$actioncomm -> elementtype = $this -> element ;
$actioncomm -> extraparams = dol_trunc ( $extraparams , 250 );
$actioncomm -> create ( $user );
2022-10-13 05:31:36 +02:00
}
2023-02-27 15:58:15 +01:00
$this -> description = $description ;
$this -> postactionmessages = $postactionmessages ;
} catch ( Exception $e ) {
2022-10-13 05:31:36 +02:00
$error ++ ;
$errorforinvoice ++ ;
2023-02-27 15:58:15 +01:00
dol_syslog ( 'Error ' . $e -> getMessage (), LOG_ERR );
2025-01-02 17:32:36 +01:00
$this -> error = 'Error ' . $e -> getMessage ();
$this -> errors [] = $this -> error ;
2022-10-13 05:31:36 +02:00
}
2023-02-27 15:58:15 +01:00
} else { // If remain to pay is null
2022-09-09 04:10:48 +02:00
$error ++ ;
2022-10-13 05:31:36 +02:00
$errorforinvoice ++ ;
2023-02-27 15:58:15 +01:00
dol_syslog ( " Remain to pay is null for the invoice " . $this -> id . " " . $this -> ref . " . Why is the invoice not classified 'Paid' ? " , LOG_WARNING );
2025-01-02 17:32:36 +01:00
$this -> error = " Remain to pay is null for the invoice " . $this -> id . " " . $this -> ref . " . Why is the invoice not classified 'Paid' ? " ;
$this -> errors [] = $this -> error ;
2022-09-09 04:10:48 +02:00
}
}
2023-02-24 23:15:54 +01:00
// Set status of the order to "Transferred" with method 'api'
if ( ! $error && ! $errorforinvoice ) {
$result = $bon -> set_infotrans ( $user , $now , 3 );
2023-02-22 15:09:37 +01:00
if ( $result < 0 ) {
$error ++ ;
$errorforinvoice ++ ;
dol_syslog ( " Error on BonPrelevement creation " , LOG_ERR );
2025-01-02 17:32:36 +01:00
$this -> error = " Error on BonPrelevement creation " ;
$this -> errors [] = $this -> error ;
2023-02-22 15:09:37 +01:00
}
2023-02-10 15:30:36 +01:00
}
2024-10-13 16:45:42 +02:00
if ( ! $error && ! $errorforinvoice && $paymentintent !== null ) {
2023-02-10 15:30:36 +01:00
// 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 " ;
2023-02-24 23:15:54 +01:00
$sql .= " ext_payment_id = ' " . $this -> db -> escape ( $paymentintent -> id ) . " ', " ;
$sql .= " ext_payment_site = ' " . $this -> db -> escape ( $service ) . " ' " ;
2023-02-10 15:30:36 +01:00
$sql .= " WHERE rowid = " . (( int ) $did );
2023-02-24 23:15:54 +01:00
dol_syslog ( get_class ( $this ) . " ::makeStripeSepaRequest update to save stripe paymentintent ids " , LOG_DEBUG );
2023-02-10 15:30:36 +01:00
$resql = $this -> db -> query ( $sql );
if ( ! $resql ) {
$this -> error = $this -> db -> lasterror ();
dol_syslog ( get_class ( $this ) . '::makeStripeSepaRequest Erreur' );
$error ++ ;
}
2022-09-09 04:10:48 +02:00
}
2023-02-24 23:15:54 +01:00
if ( ! $error && ! $errorforinvoice ) {
$this -> db -> commit ();
} else {
$this -> db -> rollback ();
}
2022-10-13 05:31:36 +02:00
} else {
$this -> error = 'WithdrawRequestErrorNilAmount' ;
dol_syslog ( get_class ( $this ) . '::makeStripeSepaRequest WithdrawRequestErrorNilAmount' );
$error ++ ;
}
2022-09-09 04:10:48 +02:00
2023-02-24 23:15:54 +01:00
/*
2022-10-13 05:31:36 +02:00
if ( ! $error ) {
2023-02-24 23:15:54 +01:00
// Force payment mode of the invoice to withdraw
2022-10-13 05:31:36 +02:00
$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 );
2022-09-09 04:10:48 +02:00
}
2023-02-24 23:15:54 +01:00
} */
2022-10-13 05:31:36 +02:00
if ( $error ) {
return - 1 ;
}
return 1 ;
2022-09-09 04:10:48 +02:00
} else {
$this -> error = $this -> db -> error ();
2022-10-13 05:31:36 +02:00
dol_syslog ( get_class ( $this ) . '::makeStripeSepaRequest Erreur -2' );
2022-09-09 04:10:48 +02:00
return - 2 ;
}
} else {
$this -> error = " Status of invoice does not allow this " ;
2024-01-18 00:42:43 +01:00
dol_syslog ( get_class ( $this ) . " ::makeStripeSepaRequest " . $this -> error . " " . $this -> status . " , " . $this -> paye . " , " . $this -> mode_reglement_id , LOG_WARNING );
2022-09-09 04:10:48 +02:00
return - 3 ;
}
}
2020-06-24 19:59:06 +02:00
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Remove a direct debit request or a credit transfer request
*
* @ param User $fuser User making delete
* @ param int $did ID of request to delete
2023-12-06 15:46:39 +01:00
* @ return int Return integer < 0 if OK , > 0 if KO
2020-06-24 19:59:06 +02:00
*/
public function demande_prelevement_delete ( $fuser , $did )
{
// phpcs:enable
2022-10-28 17:51:25 +02:00
$sql = 'DELETE FROM ' . $this -> db -> prefix () . 'prelevement_demande' ;
2021-03-30 11:36:50 +02:00
$sql .= ' WHERE rowid = ' . (( int ) $did );
2020-06-24 19:59:06 +02:00
$sql .= ' AND traite = 0' ;
2021-02-23 22:03:23 +01:00
if ( $this -> db -> query ( $sql )) {
2020-06-24 19:59:06 +02:00
return 0 ;
2020-06-27 02:00:42 +02:00
} else {
2020-06-24 19:59:06 +02:00
$this -> error = $this -> db -> lasterror ();
dol_syslog ( get_class ( $this ) . '::demande_prelevement_delete Error ' . $this -> error );
return - 1 ;
}
}
2022-01-04 20:44:17 +01:00
2024-04-24 21:57:55 +02:00
/**
* Build string for EPC QR Code
*
* @ return string String for EPC QR Code
*/
public function buildEPCQrCodeString ()
{
global $mysoc ;
2022-01-04 20:44:17 +01:00
2024-04-24 21:57:55 +02:00
// Convert total_ttc to a string with 2 decimal places
$totalTTCString = number_format ( $this -> total_ttc , 2 , '.' , '' );
// Initialize an array to hold the lines of the QR code
$lines = array ();
// Add the standard elements to the QR code
$lines = [
'BCD' , // Service Tag (optional)
'002' , // Version (optional)
'1' , // Character set (optional)
'SCT' , // Identification (optional)
];
// Add the bank account information
include_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php' ;
$bankAccount = new Account ( $this -> db );
if ( $this -> fk_account > 0 ) {
$bankAccount -> fetch ( $this -> fk_account );
$lines [] = $bankAccount -> bic ; //BIC (required)
2024-11-11 17:38:41 +01:00
if ( ! empty ( $bankAccount -> owner_name )) {
$lines [] = $bankAccount -> owner_name ; //Owner of the bank account, if present (required)
} else {
$lines [] = $mysoc -> name ; //Name (required)
}
2024-04-24 21:57:55 +02:00
$lines [] = $bankAccount -> iban ; //IBAN (required)
} else {
$lines [] = " " ; //BIC (required)
$lines [] = $mysoc -> name ; //Name (required)
$lines [] = " " ; //IBAN (required)
}
// Add the amount and reference
$lines [] = 'EUR' . $totalTTCString ; // Amount (optional)
2024-10-25 17:14:48 +02:00
$lines [] = '' ; // Purpose (optional)
2024-04-24 21:57:55 +02:00
$lines [] = '' ; // Payment reference (optional)
$lines [] = $this -> ref ; // Remittance Information (optional)
// Join the lines with newline characters and return the result
return implode ( " \n " , $lines );
}
2022-01-04 20:44:17 +01:00
/**
* Build string for ZATCA QR Code ( Arabi Saudia )
*
* @ return string String for ZATCA QR Code
*/
public function buildZATCAQRString ()
{
2022-05-22 12:38:52 +02:00
global $conf , $mysoc ;
2022-01-04 20:44:17 +01:00
$tmplang = new Translate ( '' , $conf );
$tmplang -> setDefaultLang ( 'en_US' );
$tmplang -> load ( " main " );
$datestring = dol_print_date ( $this -> date , 'dayhourrfc' );
2022-03-19 19:14:12 +01:00
//$pricewithtaxstring = price($this->total_ttc, 0, $tmplang, 0, -1, 2);
//$pricetaxstring = price($this->total_tva, 0, $tmplang, 0, -1, 2);
$pricewithtaxstring = price2num ( $this -> total_ttc , 2 , 1 );
$pricetaxstring = price2num ( $this -> total_tva , 2 , 1 );
2022-01-04 20:44:17 +01:00
/*
$name = implode ( unpack ( " H* " , $this -> thirdparty -> name ));
$vatnumber = implode ( unpack ( " H* " , $this -> thirdparty -> tva_intra ));
$date = implode ( unpack ( " H* " , $datestring ));
$pricewithtax = implode ( unpack ( " H* " , price2num ( $pricewithtaxstring , 2 )));
$pricetax = implode ( unpack ( " H* " , $pricetaxstring ));
2022-05-17 14:55:38 +02:00
//var_dump(strlen($this->thirdparty->name));
//var_dump(str_pad(dechex('9'), 2, '0', STR_PAD_LEFT));
//var_dump($this->thirdparty->name);
//var_dump(implode(unpack("H*", $this->thirdparty->name)));
//var_dump(price($this->total_tva, 0, $tmplang, 0, -1, 2));
2022-01-04 20:44:17 +01:00
$s = '01' . str_pad ( dechex ( strlen ( $this -> thirdparty -> name )), 2 , '0' , STR_PAD_LEFT ) . $name ;
$s .= '02' . str_pad ( dechex ( strlen ( $this -> thirdparty -> tva_intra )), 2 , '0' , STR_PAD_LEFT ) . $vatnumber ;
$s .= '03' . str_pad ( dechex ( strlen ( $datestring )), 2 , '0' , STR_PAD_LEFT ) . $date ;
$s .= '04' . str_pad ( dechex ( strlen ( $pricewithtaxstring )), 2 , '0' , STR_PAD_LEFT ) . $pricewithtax ;
$s .= '05' . str_pad ( dechex ( strlen ( $pricetaxstring )), 2 , '0' , STR_PAD_LEFT ) . $pricetax ;
$s .= '' ; // Hash of xml invoice
$s .= '' ; // ecda signature
$s .= '' ; // ecda public key
$s .= '' ; // ecda signature of public key stamp
*/
2024-11-26 03:43:42 +01:00
$mysocname = $mysoc -> name ? ? '' ;
2022-01-04 20:44:17 +01:00
// Using TLV format
2024-11-26 03:43:42 +01:00
$s = pack ( 'C1' , 1 ) . pack ( 'C1' , strlen ( $mysocname )) . $mysocname ;
2022-05-22 13:02:51 +02:00
$s .= pack ( 'C1' , 2 ) . pack ( 'C1' , strlen ( $mysoc -> tva_intra )) . $mysoc -> tva_intra ;
2022-03-19 19:14:12 +01:00
$s .= pack ( 'C1' , 3 ) . pack ( 'C1' , strlen ( $datestring )) . $datestring ;
2022-01-04 20:44:17 +01:00
$s .= pack ( 'C1' , 4 ) . pack ( 'C1' , strlen ( $pricewithtaxstring )) . $pricewithtaxstring ;
$s .= pack ( 'C1' , 5 ) . pack ( 'C1' , strlen ( $pricetaxstring )) . $pricetaxstring ;
$s .= '' ; // Hash of xml invoice
$s .= '' ; // ecda signature
$s .= '' ; // ecda public key
$s .= '' ; // ecda signature of public key stamp
$s = base64_encode ( $s );
return $s ;
}
2022-06-19 13:06:07 +02:00
/**
* Build string for QR - Bill ( Switzerland )
*
* @ return string String for Switzerland QR Code if QR - Bill
*/
public function buildSwitzerlandQRString ()
{
global $conf , $mysoc ;
$tmplang = new Translate ( '' , $conf );
$tmplang -> setDefaultLang ( 'en_US' );
$tmplang -> load ( " main " );
$pricewithtaxstring = price2num ( $this -> total_ttc , 2 , 1 );
$pricetaxstring = price2num ( $this -> total_tva , 2 , 1 );
$complementaryinfo = '' ;
/*
Example : //S1/10/10201409/11/190512/20/1400.000-53/30/106017086/31/180508/32/7.7/40/2:10;0:30
/ 10 / Numéro de facture – 10201409
/ 11 / Date de facture – 12.05 . 2019
/ 20 / Référence client – 1400.000 - 53
/ 30 / Numéro IDE pour la TVA – CHE - 106.017 . 086 TVA
/ 31 / Date de la prestation pour la comptabilisation de la TVA – 08.05 . 2018
/ 32 / Taux de TVA sur le montant total de la facture – 7.7 %
/ 40 / Conditions – 2 % d’ escompte à 10 jours , paiement net à 30 jours
*/
$datestring = dol_print_date ( $this -> date , '%y%m%d' );
//$pricewithtaxstring = price($this->total_ttc, 0, $tmplang, 0, -1, 2);
//$pricetaxstring = price($this->total_tva, 0, $tmplang, 0, -1, 2);
$complementaryinfo = '//S1/10/' . str_replace ( '/' , '' , $this -> ref ) . '/11/' . $datestring ;
if ( $this -> ref_client ) {
$complementaryinfo .= '/20/' . $this -> ref_client ;
}
2022-11-08 17:49:15 +01:00
if ( $this -> thirdparty -> tva_intra ) {
$complementaryinfo .= '/30/' . $this -> thirdparty -> tva_intra ;
2022-06-19 13:06:07 +02:00
}
2023-02-02 15:06:19 +01:00
include_once DOL_DOCUMENT_ROOT . '/compta/bank/class/account.class.php' ;
2023-02-02 14:56:03 +01:00
$bankaccount = new Account ( $this -> db );
2022-06-19 13:06:07 +02:00
// Header
2022-12-04 15:16:45 +01:00
$s = '' ;
2022-06-19 13:06:07 +02:00
$s .= " SPC \n " ;
$s .= " 0200 \n " ;
$s .= " 1 \n " ;
2023-02-02 15:06:19 +01:00
// Info Seller ("Compte / Payable à")
2022-06-19 13:06:07 +02:00
if ( $this -> fk_account > 0 ) {
2023-02-02 15:06:19 +01:00
// Bank BAN if country is LI or CH. TODO Add a test to check than IBAN start with CH or LI
2022-06-19 13:26:49 +02:00
$bankaccount -> fetch ( $this -> fk_account );
$s .= $bankaccount -> iban . " \n " ;
2022-06-19 13:06:07 +02:00
} else {
$s .= " \n " ;
}
2023-02-02 15:06:19 +01:00
if ( $bankaccount -> id > 0 && getDolGlobalString ( 'PDF_SWISS_QRCODE_USE_OWNER_OF_ACCOUNT_AS_CREDITOR' )) {
2024-01-13 19:48:20 +01:00
// If a bank account is provided and we ask to use it as creditor, we use the bank address
2023-02-02 15:06:19 +01:00
// TODO In a future, we may always use this address, and if name/address/zip/town/country differs from $mysoc, we can use the address of $mysoc into the final seller field ?
$s .= " S \n " ;
2024-10-24 12:38:41 +02:00
$s .= dol_trunc ( $bankaccount -> owner_name , 70 , 'right' , 'UTF-8' , 1 ) . " \n " ;
2023-02-02 15:06:19 +01:00
$addresslinearray = explode ( " \n " , $bankaccount -> owner_address );
$s .= dol_trunc ( empty ( $addresslinearray [ 1 ]) ? '' : $addresslinearray [ 1 ], 70 , 'right' , 'UTF-8' , 1 ) . " \n " ; // address line 1
$s .= dol_trunc ( empty ( $addresslinearray [ 2 ]) ? '' : $addresslinearray [ 2 ], 70 , 'right' , 'UTF-8' , 1 ) . " \n " ; // address line 2
/* $s .= dol_trunc ( $mysoc -> zip , 16 , 'right' , 'UTF-8' , 1 ) . " \n " ;
$s .= dol_trunc ( $mysoc -> town , 35 , 'right' , 'UTF-8' , 1 ) . " \n " ;
$s .= dol_trunc ( $mysoc -> country_code , 2 , 'right' , 'UTF-8' , 1 ) . " \n " ; */
} else {
$s .= " S \n " ;
2025-02-01 15:53:36 +01:00
$s .= dol_trunc (( string ) $mysoc -> name , 70 , 'right' , 'UTF-8' , 1 ) . " \n " ;
2023-02-02 15:06:19 +01:00
$addresslinearray = explode ( " \n " , $mysoc -> address );
$s .= dol_trunc ( empty ( $addresslinearray [ 1 ]) ? '' : $addresslinearray [ 1 ], 70 , 'right' , 'UTF-8' , 1 ) . " \n " ; // address line 1
$s .= dol_trunc ( empty ( $addresslinearray [ 2 ]) ? '' : $addresslinearray [ 2 ], 70 , 'right' , 'UTF-8' , 1 ) . " \n " ; // address line 2
$s .= dol_trunc ( $mysoc -> zip , 16 , 'right' , 'UTF-8' , 1 ) . " \n " ;
$s .= dol_trunc ( $mysoc -> town , 35 , 'right' , 'UTF-8' , 1 ) . " \n " ;
$s .= dol_trunc ( $mysoc -> country_code , 2 , 'right' , 'UTF-8' , 1 ) . " \n " ;
}
// Final seller (Ultimate seller) ("Créancier final" = "En faveur de")
2022-06-19 13:06:07 +02:00
$s .= " \n " ;
$s .= " \n " ;
$s .= " \n " ;
$s .= " \n " ;
$s .= " \n " ;
$s .= " \n " ;
$s .= " \n " ;
// Amount of payment (to do?)
$s .= price ( $pricewithtaxstring , 0 , 'none' , 0 , 0 , 2 ) . " \n " ;
2022-06-19 13:26:49 +02:00
$s .= ( $this -> multicurrency_code ? $this -> multicurrency_code : $conf -> currency ) . " \n " ;
2022-06-19 13:06:07 +02:00
// Buyer
2022-06-19 13:26:49 +02:00
$s .= " S \n " ;
2025-02-01 15:53:36 +01:00
$s .= dol_trunc (( string ) $this -> thirdparty -> name , 70 , 'right' , 'UTF-8' , 1 ) . " \n " ;
2022-06-19 13:26:49 +02:00
$addresslinearray = explode ( " \n " , $this -> thirdparty -> address );
$s .= dol_trunc ( empty ( $addresslinearray [ 1 ]) ? '' : $addresslinearray [ 1 ], 70 , 'right' , 'UTF-8' , 1 ) . " \n " ; // address line 1
$s .= dol_trunc ( empty ( $addresslinearray [ 2 ]) ? '' : $addresslinearray [ 2 ], 70 , 'right' , 'UTF-8' , 1 ) . " \n " ; // address line 2
2022-06-19 13:06:07 +02:00
$s .= dol_trunc ( $this -> thirdparty -> zip , 16 , 'right' , 'UTF-8' , 1 ) . " \n " ;
$s .= dol_trunc ( $this -> thirdparty -> town , 35 , 'right' , 'UTF-8' , 1 ) . " \n " ;
$s .= dol_trunc ( $this -> thirdparty -> country_code , 2 , 'right' , 'UTF-8' , 1 ) . " \n " ;
// ID of payment
$s .= " NON \n " ; // NON or QRR
2023-02-02 15:06:19 +01:00
$s .= " \n " ; // QR Code reference if previous field is QRR
// Free text
2022-06-19 13:06:07 +02:00
if ( $complementaryinfo ) {
$s .= $complementaryinfo . " \n " ;
} else {
$s .= " \n " ;
}
$s .= " EPD \n " ;
2023-02-02 15:06:19 +01:00
// More text, complementary info
if ( $complementaryinfo ) {
$s .= $complementaryinfo . " \n " ;
}
2022-06-19 13:06:07 +02:00
$s .= " \n " ;
//var_dump($s);exit;
return $s ;
}
2012-07-11 18:13:41 +02:00
}
2014-09-23 19:37:59 +02:00
2020-04-10 10:59:32 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobjectline.class.php' ;
2014-09-23 19:37:59 +02:00
2013-07-07 13:14:32 +02:00
/**
* Parent class of all other business classes for details of elements ( invoices , contracts , proposals , orders , ... )
*/
2014-09-23 19:37:59 +02:00
abstract class CommonInvoiceLine extends CommonObjectLine
2013-06-10 16:05:41 +02:00
{
2015-03-23 01:39:12 +01:00
/**
2020-10-12 19:33:00 +02:00
* Custom label of line . Not used by default .
* @ deprecated
2024-10-13 16:45:42 +02:00
* @ var string
2015-03-23 01:39:12 +01:00
*/
2020-10-12 19:33:00 +02:00
public $label ;
2015-03-23 01:39:12 +01:00
/**
2024-10-13 16:45:42 +02:00
* @ deprecated Use $product_ref
2020-10-12 19:33:00 +02:00
* @ see $product_ref
2024-10-13 16:45:42 +02:00
* @ var string
2015-03-23 01:39:12 +01:00
*/
2020-10-12 19:33:00 +02:00
public $ref ; // Product ref (deprecated)
/**
2024-10-13 16:45:42 +02:00
* @ var string
* @ deprecated Use $product_label
2020-10-12 19:33:00 +02:00
* @ see $product_label
*/
public $libelle ; // Product label (deprecated)
2015-03-23 01:39:12 +01:00
/**
* Type of the product . 0 for product 1 for service
* @ var int
*/
public $product_type = 0 ;
2020-10-12 19:33:00 +02:00
/**
* Product ref
* @ var string
*/
public $product_ref ;
/**
* Product label
* @ var string
*/
public $product_label ;
/**
* Product description
* @ var string
*/
public $product_desc ;
/**
* Quantity
2024-10-13 16:45:42 +02:00
* @ var float
2020-10-12 19:33:00 +02:00
*/
public $qty ;
/**
* Unit price before taxes
* @ var float
*/
public $subprice ;
2021-03-08 11:33:07 +01:00
/**
* Unit price before taxes
* @ var float
* @ deprecated
*/
public $price ;
2015-03-23 01:39:12 +01:00
/**
* Id of corresponding product
* @ var int
*/
public $fk_product ;
2017-05-02 21:27:56 +02:00
/**
* VAT code
* @ var string
*/
public $vat_src_code ;
2015-03-23 01:39:12 +01:00
/**
2024-03-19 18:23:00 +01:00
* VAT % Vat rate can be like " 21.30 (CODE) "
2024-10-13 16:45:42 +02:00
* @ var float | string
2015-03-23 01:39:12 +01:00
*/
public $tva_tx ;
/**
* Local tax 1 %
* @ var float
*/
public $localtax1_tx ;
/**
* Local tax 2 %
* @ var float
*/
public $localtax2_tx ;
2021-03-08 11:33:07 +01:00
/**
* Local tax 1 type
2024-02-18 15:04:18 +01:00
* @ var int < 0 , 6 > From 1 to 6 , or 0 if not found
* @ see getLocalTaxesFromRate ()
2021-03-08 11:33:07 +01:00
*/
public $localtax1_type ;
/**
* Local tax 2 type
2024-02-18 15:04:18 +01:00
* @ var int < 0 , 6 > From 1 to 6 , or 0 if not found
* @ see getLocalTaxesFromRate ()
2021-03-08 11:33:07 +01:00
*/
public $localtax2_type ;
2015-03-23 01:39:12 +01:00
/**
* Percent of discount
* @ var float
*/
public $remise_percent ;
2021-03-08 11:33:07 +01:00
/**
* Fixed discount
* @ var float
* @ deprecated
*/
public $remise ;
2015-03-23 01:39:12 +01:00
/**
* Total amount before taxes
* @ var float
*/
public $total_ht ;
/**
* Total VAT amount
* @ var float
*/
public $total_tva ;
/**
* Total local tax 1 amount
* @ var float
*/
public $total_localtax1 ;
/**
* Total local tax 2 amount
* @ var float
*/
public $total_localtax2 ;
/**
* Total amount with taxes
* @ var float
*/
public $total_ttc ;
2024-10-13 16:45:42 +02:00
/**
* @ var int < 0 , 1 >
*/
2020-11-09 15:18:56 +01:00
public $date_start_fill ; // If set to 1, when invoice is created from a template invoice, it will also auto set the field date_start at creation
2024-10-13 16:45:42 +02:00
/**
* @ var int < 0 , 1 >
*/
2020-11-09 15:18:56 +01:00
public $date_end_fill ; // If set to 1, when invoice is created from a template invoice, it will also auto set the field date_end at creation
2020-11-09 15:15:21 +01:00
2024-10-13 16:45:42 +02:00
/**
* @ var float
*/
2021-03-08 11:33:07 +01:00
public $buy_price_ht ;
2024-10-13 16:45:42 +02:00
/**
* @ var float
* @ deprecated For backward compatibility
*/
public $buyprice ;
/**
* @ var float | int | string
* @ deprecated For backward compatibility
*/
public $pa_ht ;
2021-03-08 11:33:07 +01:00
2024-10-13 16:45:42 +02:00
/**
* @ var string
*/
2021-03-08 11:33:07 +01:00
public $marge_tx ;
2024-10-13 16:45:42 +02:00
/**
* @ var string
*/
2021-03-08 11:33:07 +01:00
public $marque_tx ;
2015-03-23 01:39:12 +01:00
/**
2019-10-19 18:33:06 +02:00
* List of cumulative options :
2020-11-10 13:20:45 +01:00
* Bit 0 : 0 for common VAT - 1 if VAT french NPR
2015-03-23 01:39:12 +01:00
* Bit 1 : 0 si ligne normal - 1 si bit discount ( link to line into llx_remise_except )
* @ var int
*/
public $info_bits = 0 ;
2024-03-28 12:54:08 +01:00
/**
* List of special options to define line :
2024-03-28 20:16:32 +01:00
* 1 : shipment cost lines
* 2 : ecotaxe
* 3 : ? ?
* id of module : a meaning for the module
* @ var int
2024-03-28 12:54:08 +01:00
*/
2024-03-28 20:16:32 +01:00
public $special_code = 0 ;
2020-11-08 12:34:45 +01:00
2024-02-23 13:28:17 +01:00
/**
2024-10-13 16:45:42 +02:00
* @ var int
2024-02-23 13:28:17 +01:00
* @ deprecated Use user_creation_id
*/
2021-03-08 11:33:07 +01:00
public $fk_user_author ;
2024-03-28 20:16:32 +01:00
2024-02-23 13:28:17 +01:00
/**
2024-10-13 16:45:42 +02:00
* @ var int
2024-02-23 13:28:17 +01:00
* @ deprecated Use user_modification_id
*/
2021-03-08 11:33:07 +01:00
public $fk_user_modif ;
2022-06-11 21:53:14 +02:00
2024-10-13 16:45:42 +02:00
/**
* @ var int
*/
2022-06-11 21:53:14 +02:00
public $fk_accounting_account ;
2013-06-10 16:05:41 +02:00
}