2006-06-30 23:38:12 +00:00
< ? php
/* Copyright ( C ) 2005 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
2018-03-27 16:00:17 +00:00
* Copyright ( C ) 2004 - 2018 Laurent Destailleur < eldy @ users . sourceforge . net >
2023-11-21 17:49:33 +00:00
* Copyright ( C ) 2024 Alexandre Janniaux < alexandre . janniaux @ gmail . com >
2026-06-28 11:43:41 +00:00
* Copyright ( C ) 2024 - 2026 Frédéric France < frederic . france @ free . fr >
2026-02-08 14:29:53 +00:00
* Copyright ( C ) 2024 - 2026 MDW < mdeweerd @ users . noreply . github . com >
2024-06-30 22:21:14 +00:00
* Copyright ( C ) 2024 Noé Cendrier < noe . cendrier @ altairis . fr >
2026-06-15 02:16:42 +00:00
* Copyright ( C ) 2026 Vincent de Grandpré < vincent @ de - grandpre . quebec >
2006-06-30 23:38:12 +00: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 14:36:08 +00:00
* the Free Software Foundation ; either version 3 of the License , or
2006-06-30 23:38:12 +00: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 19:55:30 +00:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
2006-06-30 23:38:12 +00:00
*/
/**
2010-06-01 21:33:48 +00:00
* \file htdocs / core / class / discount . class . php
2011-06-19 14:35:16 +00:00
* \ingroup core propal facture commande
* \brief File of class to manage absolute discounts
2008-08-08 22:12:27 +00:00
*/
2006-06-30 23:38:12 +00:00
2023-11-21 17:49:33 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php' ;
2006-06-30 23:38:12 +00:00
/**
2018-03-27 16:00:17 +00:00
* Class to manage absolute discounts
2008-08-08 22:12:27 +00:00
*/
2023-11-21 17:49:33 +00:00
class DiscountAbsolute extends CommonObject
2006-06-30 23:38:12 +00:00
{
2020-10-31 13:32:18 +00:00
/**
2023-11-26 16:27:14 +00:00
* @ var int Thirdparty ID
2024-03-27 17:07:51 +00:00
* @ deprecated Use socid instead .
2018-10-10 07:12:25 +00:00
*/
2020-10-31 13:32:18 +00:00
public $fk_soc ;
2023-11-26 16:27:14 +00:00
/**
* @ var int Thirdparty ID
*/
public $socid ;
2020-10-31 13:32:18 +00:00
2024-03-27 17:56:24 +00:00
/**
* @ var int < 0 , 1 >
*/
2020-10-31 13:32:18 +00:00
public $discount_type ; // 0 => customer discount, 1 => supplier discount
2022-03-17 10:24:23 +00:00
2024-10-26 16:24:40 +00:00
/**
* @ var float
*/
2022-03-17 10:24:23 +00:00
public $total_ht ;
2024-10-26 16:24:40 +00:00
/**
* @ var float
*/
2022-03-17 10:24:23 +00:00
public $total_tva ;
2024-10-26 16:24:40 +00:00
/**
* @ var float
*/
2022-03-17 10:24:23 +00:00
public $total_ttc ;
2024-10-26 16:24:40 +00:00
/**
* @ var string | float
* @ deprecated
*/
2022-03-17 10:24:23 +00:00
public $amount_ht ; // deprecated
2024-10-26 16:24:40 +00:00
/**
* @ var string | float
* @ deprecated
*/
2022-03-17 10:24:23 +00:00
public $amount_tva ; // deprecated
2024-10-26 16:24:40 +00:00
/**
* @ var string | float
* @ deprecated
*/
2022-03-17 10:24:23 +00:00
public $amount_ttc ; // deprecated
2024-10-26 16:24:40 +00:00
/**
* @ var float
*/
2022-03-17 10:24:23 +00:00
public $multicurrency_total_ht ;
2024-10-26 16:24:40 +00:00
/**
* @ var float
*/
2022-03-17 10:24:23 +00:00
public $multicurrency_total_tva ;
2024-10-26 16:24:40 +00:00
/**
* @ var float
*/
2022-03-17 10:24:23 +00:00
public $multicurrency_total_ttc ;
2024-10-26 16:24:40 +00:00
/**
* @ var string | float
* @ deprecated
*/
2022-03-17 10:24:23 +00:00
public $multicurrency_amount_ht ; // deprecated
2024-10-26 16:24:40 +00:00
/**
* @ var string | float
* @ deprecated
*/
2022-03-17 10:24:23 +00:00
public $multicurrency_amount_tva ; // deprecated
2024-10-26 16:24:40 +00:00
/**
* @ var string | float
* @ deprecated
*/
2022-03-17 10:24:23 +00:00
public $multicurrency_amount_ttc ; // deprecated
2023-11-08 16:26:00 +00:00
/**
2024-10-26 16:24:40 +00:00
* @ var float
2023-11-08 16:26:00 +00:00
*/
public $multicurrency_subprice ;
/**
* @ var int
*/
public $fk_invoice_supplier ;
/**
* @ var int
*/
public $fk_invoice_supplier_line ;
2024-10-26 16:24:40 +00:00
/**
* @ var string | float Vat rate
*/
2020-10-31 13:32:18 +00:00
public $tva_tx ;
2026-06-15 02:16:42 +00:00
/**
* @ var string | float Localtax1 rate
*/
public $localtax1_tx ;
/**
* @ var string | float Localtax2 rate
*/
public $localtax2_tx ;
/**
* @ var string | float Localtax1 type
*/
public $localtax1_type ;
/**
* @ var string | float Localtax2 type
*/
public $localtax2_type ;
2024-10-26 16:24:40 +00:00
/**
* @ var string
*/
2020-10-31 13:32:18 +00:00
public $vat_src_code ;
/**
2026-02-08 14:29:53 +00:00
* @ var int User ID of the user authorising the discount
2018-10-10 07:12:25 +00:00
*/
public $fk_user ;
2018-08-31 15:55:31 +00:00
2020-10-31 13:32:18 +00:00
/**
2018-10-10 07:12:25 +00:00
* @ var string description
*/
public $description ;
2018-08-31 17:26:08 +00:00
2020-10-31 13:32:18 +00:00
/**
* Date creation record ( datec )
*
2024-10-26 16:24:40 +00:00
* @ var int
2020-10-31 13:32:18 +00:00
*/
public $datec ;
/**
* @ var int ID invoice line when a discount is used into an invoice line ( for absolute discounts )
*/
public $fk_facture_line ;
/**
* @ var int ID invoice when a discount line is used into an invoice ( for credit note )
*/
public $fk_facture ;
/**
* @ var int ID credit note or deposit used to create the discount
*/
public $fk_facture_source ;
2024-10-26 16:24:40 +00:00
/**
* @ var string
*/
2020-10-31 13:32:18 +00:00
public $ref_facture_source ; // Ref credit note or deposit used to create the discount
2024-10-26 16:24:40 +00:00
/**
* @ var int
*/
2019-10-17 10:14:38 +00:00
public $type_facture_source ;
2018-10-10 07:12:25 +00:00
2024-10-26 16:24:40 +00:00
/**
* @ var int
*/
2020-10-31 13:32:18 +00:00
public $fk_invoice_supplier_source ;
2024-10-26 16:24:40 +00:00
/**
* @ var string
*/
2020-10-31 13:32:18 +00:00
public $ref_invoice_supplier_source ; // Ref credit note or deposit used to create the discount
2024-10-26 16:24:40 +00:00
/**
* @ var int
*/
2020-10-31 13:32:18 +00:00
public $type_invoice_supplier_source ;
2024-12-10 12:38:50 +00:00
/* Customer Discount */
const TYPE_CUSTOMER = 0 ;
/* Supplier Discount */
const TYPE_SUPPLIER = 1 ;
2020-10-31 13:32:18 +00:00
/**
* Constructor
*
* @ param DoliDB $db Database handler
*/
public function __construct ( $db )
{
$this -> db = $db ;
}
/**
* Load object from database into memory
*
* @ param int $rowid id discount to load
* @ param int $fk_facture_source fk_facture_source
* @ param int $fk_invoice_supplier_source fk_invoice_supplier_source
2024-03-27 17:56:24 +00:00
* @ return int <- 1 , 1 > Return integer < 0 if KO , = 0 if not found , > 0 if OK
2020-10-31 13:32:18 +00:00
*/
public function fetch ( $rowid , $fk_facture_source = 0 , $fk_invoice_supplier_source = 0 )
{
// Check parameters
2021-02-23 21:03:23 +00:00
if ( ! $rowid && ! $fk_facture_source && ! $fk_invoice_supplier_source ) {
2020-10-31 13:32:18 +00:00
$this -> error = 'ErrorBadParameters' ;
return - 1 ;
}
$sql = " SELECT sr.rowid, sr.fk_soc, sr.discount_type, " ;
$sql .= " sr.fk_user, " ;
2026-06-15 02:16:42 +00:00
$sql .= " sr.amount_ht, sr.amount_tva, sr.amount_localtax1, sr.amount_localtax2, sr.amount_ttc, sr.tva_tx, sr.localtax1_tx, sr.localtax1_type, sr.localtax2_tx, sr.localtax2_type, sr.vat_src_code, " ;
2020-10-31 13:32:18 +00:00
$sql .= " sr.multicurrency_amount_ht, sr.multicurrency_amount_tva, sr.multicurrency_amount_ttc, " ;
$sql .= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.fk_invoice_supplier_line, sr.fk_invoice_supplier, sr.fk_invoice_supplier_source, sr.description, " ;
$sql .= " sr.datec, " ;
$sql .= " f.ref as ref_facture_source, f.type as type_facture_source, " ;
$sql .= " fsup.ref as ref_invoice_supplier_source, fsup.type as type_invoice_supplier_source " ;
2022-01-27 09:19:35 +00:00
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except as sr " ;
$sql .= " LEFT JOIN " . $this -> db -> prefix () . " facture as f ON sr.fk_facture_source = f.rowid " ;
$sql .= " LEFT JOIN " . $this -> db -> prefix () . " facture_fourn as fsup ON sr.fk_invoice_supplier_source = fsup.rowid " ;
2020-10-31 13:32:18 +00:00
$sql .= " WHERE sr.entity IN ( " . getEntity ( 'invoice' ) . " ) " ;
2021-02-23 21:03:23 +00:00
if ( $rowid ) {
2021-08-23 16:56:46 +00:00
$sql .= " AND sr.rowid = " . (( int ) $rowid );
2021-02-23 21:03:23 +00:00
}
if ( $fk_facture_source ) {
2021-03-24 18:53:31 +00:00
$sql .= " AND sr.fk_facture_source = " . (( int ) $fk_facture_source );
2021-02-23 21:03:23 +00:00
}
if ( $fk_invoice_supplier_source ) {
2021-03-24 18:53:31 +00:00
$sql .= " AND sr.fk_invoice_supplier_source = " . (( int ) $fk_invoice_supplier_source );
2021-02-23 21:03:23 +00:00
}
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::fetch " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
if ( $this -> db -> num_rows ( $resql )) {
2020-10-31 13:32:18 +00:00
$obj = $this -> db -> fetch_object ( $resql );
$this -> id = $obj -> rowid ;
$this -> fk_soc = $obj -> fk_soc ;
2024-03-27 17:07:51 +00:00
$this -> socid = $obj -> fk_soc ;
2020-10-31 13:32:18 +00:00
$this -> discount_type = $obj -> discount_type ;
2022-03-17 10:24:23 +00:00
$this -> total_ht = $obj -> amount_ht ;
$this -> total_tva = $obj -> amount_tva ;
2026-06-15 02:16:42 +00:00
$this -> total_localtax1 = $obj -> amount_localtax1 ;
$this -> total_localtax2 = $obj -> amount_localtax2 ;
2022-03-17 10:24:23 +00:00
$this -> total_ttc = $obj -> amount_ttc ;
// For backward compatibility
$this -> amount_ht = $this -> total_ht ;
$this -> amount_tva = $this -> total_tva ;
$this -> amount_ttc = $this -> total_ttc ;
$this -> multicurrency_total_ht = $this -> multicurrency_subprice = $obj -> multicurrency_amount_ht ;
$this -> multicurrency_total_tva = $obj -> multicurrency_amount_tva ;
$this -> multicurrency_total_ttc = $obj -> multicurrency_amount_ttc ;
// For backward compatibility
$this -> multicurrency_amount_ht = $this -> multicurrency_total_ht ;
$this -> multicurrency_amount_tva = $this -> multicurrency_total_tva ;
$this -> multicurrency_amount_ttc = $this -> multicurrency_total_ttc ;
2020-10-31 13:32:18 +00:00
$this -> tva_tx = $obj -> tva_tx ;
2026-06-15 02:16:42 +00:00
$this -> localtax1_tx = $obj -> localtax1_tx ;
$this -> localtax1_type = $obj -> localtax1_type ;
$this -> localtax2_tx = $obj -> localtax2_tx ;
$this -> localtax2_type = $obj -> localtax2_type ;
2020-10-31 13:32:18 +00:00
$this -> vat_src_code = $obj -> vat_src_code ;
$this -> fk_user = $obj -> fk_user ;
$this -> fk_facture_line = $obj -> fk_facture_line ;
$this -> fk_facture = $obj -> fk_facture ;
$this -> fk_facture_source = $obj -> fk_facture_source ; // Id credit note or deposit source
$this -> ref_facture_source = $obj -> ref_facture_source ; // Ref credit note or deposit source
$this -> type_facture_source = $obj -> type_facture_source ; // Type credit note or deposit source
$this -> fk_invoice_supplier_line = $obj -> fk_invoice_supplier_line ;
$this -> fk_invoice_supplier = $obj -> fk_invoice_supplier ;
$this -> fk_invoice_supplier_source = $obj -> fk_invoice_supplier_source ; // Id credit note or deposit source
$this -> ref_invoice_supplier_source = $obj -> ref_invoice_supplier_source ; // Ref credit note or deposit source
$this -> type_invoice_supplier_source = $obj -> type_invoice_supplier_source ; // Type credit note or deposit source
$this -> description = $obj -> description ;
$this -> datec = $this -> db -> jdate ( $obj -> datec );
$this -> db -> free ( $resql );
return 1 ;
} else {
$this -> db -> free ( $resql );
return 0 ;
}
} else {
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
/**
* Create a discount into database
*
* @ param User $user User that create
2024-03-27 17:56:24 +00:00
* @ return int <- 1 , 1 > Return integer < 0 if KO , > 0 if OK
2020-10-31 13:32:18 +00:00
*/
public function create ( $user )
{
2024-06-30 13:40:19 +00:00
global $conf ;
2020-10-31 13:32:18 +00:00
// Clean parameters
$this -> amount_ht = price2num ( $this -> amount_ht );
$this -> amount_tva = price2num ( $this -> amount_tva );
$this -> amount_ttc = price2num ( $this -> amount_ttc );
$this -> tva_tx = price2num ( $this -> tva_tx );
2026-06-15 02:16:42 +00:00
$this -> localtax1_tx = price2num ( $this -> localtax1_tx );
$this -> localtax1_type = price2num ( $this -> localtax1_type );
$this -> localtax2_tx = price2num ( $this -> localtax2_tx );
$this -> localtax2_type = price2num ( $this -> localtax2_type );
2020-10-31 13:32:18 +00:00
$this -> multicurrency_amount_ht = price2num ( $this -> multicurrency_amount_ht );
$this -> multicurrency_amount_tva = price2num ( $this -> multicurrency_amount_tva );
$this -> multicurrency_amount_ttc = price2num ( $this -> multicurrency_amount_ttc );
2021-02-23 21:03:23 +00:00
if ( empty ( $this -> multicurrency_amount_ht )) {
$this -> multicurrency_amount_ht = 0 ;
}
if ( empty ( $this -> multicurrency_amount_tva )) {
$this -> multicurrency_amount_tva = 0 ;
}
if ( empty ( $this -> multicurrency_amount_ttc )) {
$this -> multicurrency_amount_ttc = 0 ;
}
if ( empty ( $this -> tva_tx )) {
$this -> tva_tx = 0 ;
}
2026-06-15 02:16:42 +00:00
if ( empty ( $this -> localtax1_tx )) {
$this -> localtax1_tx = 0 ;
$this -> localtax1_type = 0 ;
}
if ( empty ( $this -> localtax2_tx )) {
$this -> localtax2_tx = 0 ;
$this -> localtax2_type = 0 ;
}
2020-10-31 13:32:18 +00:00
// Check parameters
2021-02-23 21:03:23 +00:00
if ( empty ( $this -> description )) {
2023-08-10 00:09:17 +00:00
$this -> error = 'BadValueForPropertyDescriptionOfDiscount' ;
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::create " . $this -> error , LOG_ERR );
return - 1 ;
}
$userid = $user -> id ;
2021-02-23 21:03:23 +00:00
if ( ! ( $userid > 0 )) { // For example when record is saved into an anonymous context with a not loaded object $user.
2019-06-24 16:43:16 +00:00
include_once DOL_DOCUMENT_ROOT . '/compta/facture/class/facture.class.php' ;
2019-06-24 16:40:31 +00:00
$tmpinvoice = new Facture ( $this -> db );
$tmpinvoice -> fetch ( $this -> fk_facture_source );
2025-02-10 12:03:37 +00:00
$userid = $tmpinvoice -> user_creation_id ; // We use the author of invoice
2019-06-24 16:40:31 +00:00
}
2020-10-31 13:32:18 +00:00
// Insert request
2022-01-27 09:19:35 +00:00
$sql = " INSERT INTO " . $this -> db -> prefix () . " societe_remise_except " ;
2020-10-31 13:32:18 +00:00
$sql .= " (entity, datec, fk_soc, discount_type, fk_user, description, " ;
2026-06-15 02:16:42 +00:00
$sql .= " amount_ht, amount_tva, amount_localtax1, amount_localtax2, amount_ttc, tva_tx, localtax1_tx, localtax1_type, localtax2_tx, localtax2_type, vat_src_code, " ;
2020-10-31 13:32:18 +00:00
$sql .= " multicurrency_amount_ht, multicurrency_amount_tva, multicurrency_amount_ttc, " ;
2025-01-30 09:44:07 +00:00
$sql .= " fk_facture_source, fk_invoice_supplier_source, multicurrency_code, multicurrency_tx " ;
2020-10-31 13:32:18 +00:00
$sql .= " ) " ;
2026-07-18 00:49:05 +00:00
$sql .= " VALUES ( " . (( int ) $conf -> entity ) . " , ' " . $this -> db -> idate ( $this -> datec != '' ? $this -> datec : dol_now ()) . " ', " . (( int ) $this -> socid ) . " , " . ( empty ( $this -> discount_type ) ? 0 : intval ( $this -> discount_type )) . " , " . (( int ) $userid ) . " , ' " . $this -> db -> escape ( $this -> description ) . " ', " ;
2026-06-15 02:16:42 +00:00
$sql .= " " . price2num ( $this -> amount_ht ) . " , " . price2num ( $this -> amount_tva ) . " , " ;
$sql .= " " . ( $this -> total_localtax1 ? price2num ( $this -> total_localtax1 ) : 0 ) . " , " . ( $this -> total_localtax2 ? price2num ( $this -> total_localtax2 ) : 0 ) . " , " . price2num ( $this -> amount_ttc ) . " , " . price2num ( $this -> tva_tx ) . " , " ;
2026-08-04 16:59:31 +00:00
$sql .= " " . ( $this -> localtax1_tx ? price2num ( $this -> localtax1_tx ) : 0 ) . " , " . ( $this -> localtax1_type ? price2num ( $this -> localtax1_type ) : 0 ) . " , " ;
2026-06-15 02:16:42 +00:00
$sql .= " " . ( $this -> localtax2_tx ? price2num ( $this -> localtax2_tx ) : 0 ) . " , " . ( $this -> localtax2_type ? price2num ( $this -> localtax2_type ) : 0 ) . " , ' " . $this -> db -> escape ( $this -> vat_src_code ) . " ', " ;
$sql .= " " . price2num ( $this -> multicurrency_amount_ht ) . " , " . price2num ( $this -> multicurrency_amount_tva ) . " , " ;
$sql .= " " . price2num ( $this -> multicurrency_amount_ttc ) . " , " ;
2021-06-14 11:51:09 +00:00
$sql .= " " . ( $this -> fk_facture_source ? (( int ) $this -> fk_facture_source ) : " null " ) . " , " ;
2025-01-30 09:44:07 +00:00
$sql .= " " . ( $this -> fk_invoice_supplier_source ? (( int ) $this -> fk_invoice_supplier_source ) : " null " ) . " , " ;
2025-02-07 15:26:26 +00:00
$sql .= " " . ( $this -> multicurrency_code ? " ' " . $this -> db -> escape ( $this -> multicurrency_code ) . " ' " : " null " ) . " , " ;
2025-01-30 09:44:07 +00:00
$sql .= " " . ( $this -> multicurrency_tx ? price2num ( $this -> multicurrency_tx ) : " null " );
2020-10-31 13:32:18 +00:00
$sql .= " ) " ;
dol_syslog ( get_class ( $this ) . " ::create " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2022-01-27 09:19:35 +00:00
$this -> id = $this -> db -> last_insert_id ( $this -> db -> prefix () . " societe_remise_except " );
2020-10-31 13:32:18 +00:00
return $this -> id ;
} else {
$this -> error = $this -> db -> lasterror () . ' - sql=' . $sql ;
return - 1 ;
}
}
/**
2024-01-13 18:48:20 +00:00
* Delete object in database . If fk_facture_source is defined , we delete all family with same fk_facture_source . If not , only with id is removed
2020-10-31 13:32:18 +00:00
*
2024-03-27 17:56:24 +00:00
* @ param User $user Object of user asking to delete
2024-03-29 16:50:04 +00:00
* @ return int <- 2 , 1 > Return integer < 0 if KO , > 0 if OK
2020-10-31 13:32:18 +00:00
*/
public function delete ( $user )
{
// Check if we can remove the discount
2021-02-23 21:03:23 +00:00
if ( $this -> fk_facture_source ) {
2020-10-31 13:32:18 +00:00
$sql = " SELECT COUNT(rowid) as nb " ;
2022-01-27 09:19:35 +00:00
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except " ;
2020-10-31 13:32:18 +00:00
$sql .= " WHERE (fk_facture_line IS NOT NULL " ; // Not used as absolute simple discount
$sql .= " OR fk_facture IS NOT NULL) " ; // Not used as credit note and not used as deposit
2021-06-09 13:36:47 +00:00
$sql .= " AND fk_facture_source = " . (( int ) $this -> fk_facture_source );
2026-07-19 15:32:14 +00:00
//$sql.=" AND rowid != ".((int) $this->id);
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::delete Check if we can remove discount " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2020-10-31 13:32:18 +00:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-23 21:03:23 +00:00
if ( $obj -> nb > 0 ) {
2020-10-31 13:32:18 +00:00
$this -> error = 'ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved' ;
return - 2 ;
}
} else {
dol_print_error ( $this -> db );
return - 1 ;
}
}
// Check if we can remove the discount
2021-02-23 21:03:23 +00:00
if ( $this -> fk_invoice_supplier_source ) {
2020-10-31 13:32:18 +00:00
$sql = " SELECT COUNT(rowid) as nb " ;
2022-01-27 09:19:35 +00:00
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except " ;
2020-10-31 13:32:18 +00:00
$sql .= " WHERE (fk_invoice_supplier_line IS NOT NULL " ; // Not used as absolute simple discount
$sql .= " OR fk_invoice_supplier IS NOT NULL) " ; // Not used as credit note and not used as deposit
2021-08-23 16:56:46 +00:00
$sql .= " AND fk_invoice_supplier_source = " . (( int ) $this -> fk_invoice_supplier_source );
2026-07-19 15:32:14 +00:00
//$sql.=" AND rowid != ".((int) $this->id);
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::delete Check if we can remove discount " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2020-10-31 13:32:18 +00:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-23 21:03:23 +00:00
if ( $obj -> nb > 0 ) {
2020-10-31 13:32:18 +00:00
$this -> error = 'ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved' ;
return - 2 ;
}
} else {
dol_print_error ( $this -> db );
return - 1 ;
}
}
$this -> db -> begin ();
// Delete but only if not used
2022-01-27 09:19:35 +00:00
$sql = " DELETE FROM " . $this -> db -> prefix () . " societe_remise_except " ;
2021-02-23 21:03:23 +00:00
if ( $this -> fk_facture_source ) {
2024-01-13 18:48:20 +00:00
$sql .= " WHERE fk_facture_source = " . (( int ) $this -> fk_facture_source ); // Delete all lines of same series
2021-02-23 21:03:23 +00:00
} elseif ( $this -> fk_invoice_supplier_source ) {
2024-01-13 18:48:20 +00:00
$sql .= " WHERE fk_invoice_supplier_source = " . (( int ) $this -> fk_invoice_supplier_source ); // Delete all lines of same series
2021-02-23 21:03:23 +00:00
} else {
2021-03-30 15:53:25 +00:00
$sql .= " WHERE rowid = " . (( int ) $this -> id ); // Delete only line
2021-02-23 21:03:23 +00:00
}
2020-10-31 13:32:18 +00:00
$sql .= " AND (fk_facture_line IS NULL " ; // Not used as absolute simple discount
$sql .= " AND fk_facture IS NULL) " ; // Not used as credit note and not used as deposit
$sql .= " AND (fk_invoice_supplier_line IS NULL " ; // Not used as absolute simple discount
$sql .= " AND fk_invoice_supplier IS NULL) " ; // Not used as credit note and not used as deposit
dol_syslog ( get_class ( $this ) . " ::delete Delete discount " , LOG_DEBUG );
2024-06-30 13:40:19 +00:00
2023-06-01 09:49:56 +00:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commoninvoice.class.php' ;
2020-10-31 13:32:18 +00:00
$result = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $result ) {
2020-10-31 13:32:18 +00:00
// If source of discount was a credit note or deposit, we change source statut.
2021-02-23 21:03:23 +00:00
if ( $this -> fk_facture_source ) {
2022-01-27 09:19:35 +00:00
$sql = " UPDATE " . $this -> db -> prefix () . " facture " ;
2020-10-31 13:32:18 +00:00
$sql .= " set paye=0, fk_statut=1 " ;
2023-10-20 10:52:36 +00:00
$sql .= " WHERE type IN ( " . $this -> db -> sanitize ( CommonInvoice :: TYPE_CREDIT_NOTE . " , " . CommonInvoice :: TYPE_DEPOSIT ) . " ) AND rowid = " . (( int ) $this -> fk_facture_source );
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::delete Update credit note or deposit invoice statut " , LOG_DEBUG );
$result = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $result ) {
2020-10-31 13:32:18 +00:00
$this -> db -> commit ();
return 1 ;
} else {
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return - 1 ;
}
} elseif ( $this -> fk_invoice_supplier_source ) {
2022-01-27 09:19:35 +00:00
$sql = " UPDATE " . $this -> db -> prefix () . " facture_fourn " ;
2020-10-31 13:32:18 +00:00
$sql .= " set paye=0, fk_statut=1 " ;
2023-10-20 10:52:36 +00:00
$sql .= " WHERE type IN ( " . $this -> db -> sanitize ( CommonInvoice :: TYPE_CREDIT_NOTE . " , " . CommonInvoice :: TYPE_DEPOSIT ) . " ) AND rowid = " . (( int ) $this -> fk_invoice_supplier_source );
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::delete Update credit note or deposit invoice statut " , LOG_DEBUG );
$result = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $result ) {
2020-10-31 13:32:18 +00:00
$this -> db -> commit ();
return 1 ;
} else {
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return - 1 ;
}
} else {
$this -> db -> commit ();
return 1 ;
}
} else {
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return - 1 ;
}
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Link the discount to a particular invoice line or a particular invoice .
* When discount is a global discount used as an invoice line , we link using rowidline .
* When discount is from a credit note used to reduce payment of an invoice , we link using rowidinvoice
*
* @ param int $rowidline Invoice line id ( To use discount into invoice lines )
2023-01-03 13:06:25 +00:00
* @ param int $rowidinvoice Invoice id ( To use discount as a credit note to reduce payment of invoice )
2024-06-30 22:21:14 +00:00
* @ param int $notrigger 0 = launch triggers after , 1 = disable triggers
2024-03-29 16:50:04 +00:00
* @ return int <- 3 , 1 > Return integer < 0 if KO , > 0 if OK
2020-10-31 13:32:18 +00:00
*/
2024-06-30 22:21:14 +00:00
public function link_to_invoice ( $rowidline , $rowidinvoice , $notrigger = 0 )
2020-10-31 13:32:18 +00:00
{
// phpcs:enable
2024-06-30 22:21:14 +00:00
global $user ;
2020-10-31 13:32:18 +00:00
// Check parameters
2021-02-23 21:03:23 +00:00
if ( ! $rowidline && ! $rowidinvoice ) {
2020-10-31 13:32:18 +00:00
$this -> error = 'ErrorBadParameters' ;
return - 1 ;
}
2021-02-23 21:03:23 +00:00
if ( $rowidline && $rowidinvoice ) {
2020-10-31 13:32:18 +00:00
$this -> error = 'ErrorBadParameters' ;
return - 2 ;
}
2022-01-27 09:19:35 +00:00
$sql = " UPDATE " . $this -> db -> prefix () . " societe_remise_except " ;
2020-10-31 13:32:18 +00:00
if ( ! empty ( $this -> discount_type )) {
2021-02-23 21:03:23 +00:00
if ( $rowidline ) {
2021-03-30 01:37:54 +00:00
$sql .= " SET fk_invoice_supplier_line = " . (( int ) $rowidline );
2021-02-23 21:03:23 +00:00
}
if ( $rowidinvoice ) {
2021-03-30 01:37:54 +00:00
$sql .= " SET fk_invoice_supplier = " . (( int ) $rowidinvoice );
2021-02-23 21:03:23 +00:00
}
2020-10-31 13:32:18 +00:00
} else {
2021-02-23 21:03:23 +00:00
if ( $rowidline ) {
2021-03-30 01:37:54 +00:00
$sql .= " SET fk_facture_line = " . (( int ) $rowidline );
2021-02-23 21:03:23 +00:00
}
if ( $rowidinvoice ) {
2021-03-30 01:37:54 +00:00
$sql .= " SET fk_facture = " . (( int ) $rowidinvoice );
2021-02-23 21:03:23 +00:00
}
2020-10-31 13:32:18 +00:00
}
2021-08-27 14:33:03 +00:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::link_to_invoice " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2020-10-31 13:32:18 +00:00
if ( ! empty ( $this -> discount_type )) {
$this -> fk_invoice_supplier_line = $rowidline ;
$this -> fk_invoice_supplier = $rowidinvoice ;
} else {
$this -> fk_facture_line = $rowidline ;
$this -> fk_facture = $rowidinvoice ;
}
2026-03-26 16:08:55 +00:00
// If a discount comes from a source invoice (deposit/credit note/excess) and is applied to another invoice,
// also create a link between the source invoice and the target invoice.
if ( $rowidinvoice ) {
$sourcetype = '' ;
$targettype = '' ;
$sourceinvoiceid = 0 ;
if ( ! empty ( $this -> discount_type )) {
$sourcetype = 'invoice_supplier' ;
$targettype = 'invoice_supplier' ;
$sourceinvoiceid = ( int ) $this -> fk_invoice_supplier_source ;
} else {
$sourcetype = 'facture' ;
$targettype = 'facture' ;
$sourceinvoiceid = ( int ) $this -> fk_facture_source ;
}
if ( $sourceinvoiceid > 0 && $sourceinvoiceid !== ( int ) $rowidinvoice ) {
$sqlcheck = " SELECT 1 " ;
$sqlcheck .= " FROM " . $this -> db -> prefix () . " element_element " ;
$sqlcheck .= " WHERE fk_source = " . (( int ) $sourceinvoiceid );
$sqlcheck .= " AND sourcetype = ' " . $this -> db -> escape ( $sourcetype ) . " ' " ;
$sqlcheck .= " AND fk_target = " . (( int ) $rowidinvoice );
$sqlcheck .= " AND targettype = ' " . $this -> db -> escape ( $targettype ) . " ' " ;
$sqlcheck .= $this -> db -> plimit ( 1 );
$rescheck = $this -> db -> query ( $sqlcheck );
if ( $rescheck && $this -> db -> num_rows ( $rescheck ) === 0 ) {
$sqladd = " INSERT INTO " . $this -> db -> prefix () . " element_element (fk_source, sourcetype, fk_target, targettype) " ;
$sqladd .= " VALUES ( " . (( int ) $sourceinvoiceid ) . " , ' " . $this -> db -> escape ( $sourcetype ) . " ', " . (( int ) $rowidinvoice ) . " , ' " . $this -> db -> escape ( $targettype ) . " ') " ;
$this -> db -> query ( $sqladd ); // Best-effort: do not fail discount link if object link can't be created.
}
}
}
2024-06-30 22:21:14 +00:00
if ( ! $notrigger ) {
// Call trigger
$result = $this -> call_trigger ( 'DISCOUNT_MODIFY' , $user );
if ( $result < 0 ) {
return - 2 ;
}
// End call triggers
}
2020-10-31 13:32:18 +00:00
return 1 ;
} else {
$this -> error = $this -> db -> error ();
return - 3 ;
}
}
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
/**
* Link the discount to a particular invoice line or a particular invoice .
* Do not call this if discount is linked to a reconcialiated invoice
*
2024-06-30 22:21:14 +00:00
* @ param int $notrigger 0 = launch triggers after , 1 = disable triggers
2024-03-29 16:50:04 +00:00
* @ return int <- 3 , 1 > Return integer < 0 if KO , > 0 if OK
2020-10-31 13:32:18 +00:00
*/
2024-06-30 22:21:14 +00:00
public function unlink_invoice ( $notrigger = 0 )
2020-10-31 13:32:18 +00:00
{
// phpcs:enable
2024-06-30 22:21:14 +00:00
global $user ;
2022-01-27 09:19:35 +00:00
$sql = " UPDATE " . $this -> db -> prefix () . " societe_remise_except " ;
2020-10-31 13:32:18 +00:00
if ( ! empty ( $this -> discount_type )) {
$sql .= " SET fk_invoice_supplier_line = NULL, fk_invoice_supplier = NULL " ;
} else {
2019-11-13 18:35:39 +00:00
$sql .= " SET fk_facture_line = NULL, fk_facture = NULL " ;
2018-02-14 09:47:10 +00:00
}
2021-08-27 14:33:03 +00:00
$sql .= " WHERE rowid = " . (( int ) $this -> id );
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::unlink_invoice " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2024-06-30 22:21:14 +00:00
if ( ! $notrigger ) {
// Call trigger
$result = $this -> call_trigger ( 'DISCOUNT_MODIFY' , $user );
if ( $result < 0 ) {
return - 2 ;
}
// End call triggers
}
2020-10-31 13:32:18 +00:00
return 1 ;
} else {
$this -> error = $this -> db -> error ();
return - 3 ;
}
}
/**
* Return amount ( with tax ) of discounts currently available for a company , user or other criteria
*
2024-03-27 17:56:24 +00:00
* @ param ? Societe $company Object third party for filter
2025-08-15 16:43:58 +00:00
* @ param ? User $user Filtre on an author of the discount
2021-08-23 15:41:11 +00:00
* @ param string $filter Filter other . Warning : Do not use a user input value here .
2024-03-27 17:56:24 +00:00
* @ param int | float $maxvalue Filter on max value for discount
* @ param int < 0 , 1 > $discount_type 0 => customer discount , 1 => supplier discount
* @ param int < 0 , 1 > $multicurrency Return multicurrency_amount instead of amount
* @ return int <- 1 , - 1 >| float Return integer < 0 if KO , amount otherwise
2020-10-31 13:32:18 +00:00
*/
2023-12-21 12:43:19 +00:00
public function getAvailableDiscounts ( $company = null , $user = null , $filter = '' , $maxvalue = 0 , $discount_type = 0 , $multicurrency = 0 )
2020-10-31 13:32:18 +00:00
{
2025-07-29 11:25:07 +00:00
global $conf , $hookmanager ;
2020-10-31 13:32:18 +00:00
dol_syslog ( get_class ( $this ) . " ::getAvailableDiscounts discount_type= " . $discount_type , LOG_DEBUG );
2025-07-29 11:25:07 +00:00
$parameters = array (
'company' => $company ,
'user' => $user ,
'filter' => $filter ,
'maxvalue' => $maxvalue ,
'discount_type' => $discount_type ,
'multicurrency' => $multicurrency
);
$reshook = $hookmanager -> executeHooks ( 'getAvailableDiscounts' , $parameters );
if ( empty ( $reshook )) {
$sql = " SELECT SUM(rc.amount_ttc) as amount, SUM(rc.multicurrency_amount_ttc) as multicurrency_amount " ;
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except as rc " ;
2026-07-19 15:32:14 +00:00
$sql .= " WHERE rc.entity = " . (( int ) $conf -> entity );
2025-07-29 11:25:07 +00:00
$sql .= " AND rc.discount_type= " . (( int ) $discount_type );
if ( ! empty ( $discount_type )) {
$sql .= " AND (rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line IS NULL) " ; // Available from supplier
} else {
$sql .= " AND (rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL) " ; // Available to customer
}
if ( is_object ( $company )) {
$sql .= " AND rc.fk_soc = " . (( int ) $company -> id );
}
if ( is_object ( $user )) {
$sql .= " AND rc.fk_user = " . (( int ) $user -> id );
}
if ( $filter ) {
2026-07-19 15:32:14 +00:00
$sql .= " AND ( " . $filter . " ) " ; // @phan-suppress-current-line SqlInjection
2025-07-29 11:25:07 +00:00
}
if ( $maxvalue ) {
$sql .= ' AND rc.amount_ttc <= ' . (( float ) price2num ( $maxvalue ));
}
2020-10-31 13:32:18 +00:00
} else {
2025-07-29 11:25:07 +00:00
$sql = $hookmanager -> resArray [ 'sql' ];
2021-02-23 21:03:23 +00:00
}
2020-10-31 13:32:18 +00:00
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2020-10-31 13:32:18 +00:00
$obj = $this -> db -> fetch_object ( $resql );
//while ($obj)
//{
//print 'zz'.$obj->amount;
//$obj = $this->db->fetch_object($resql);
//}
2021-02-23 21:03:23 +00:00
if ( $multicurrency ) {
2021-06-10 18:58:56 +00:00
return $obj -> multicurrency_amount ;
2020-02-27 13:10:00 +00:00
}
2020-10-31 13:32:18 +00:00
return $obj -> amount ;
}
return - 1 ;
}
/**
* Return amount ( with tax ) of all deposits invoices used by invoice as a payment .
2022-10-12 09:52:33 +00:00
* Should always be empty , except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS or FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS is on ( not recommended ) .
2020-10-31 13:32:18 +00:00
*
* @ param CommonInvoice $invoice Object invoice ( customer of supplier )
2024-03-27 17:56:24 +00:00
* @ param int <- 1 , 1 > $multicurrency 1 = Return multicurrency_amount instead of amount . TODO Add a mode multicurrency = - 1 to return array with amount + multicurrency amount
* @ return int <- 1 , - 1 >| float Return integer < 0 if KO , Sum of credit notes and deposits amount otherwise
2020-10-31 13:32:18 +00:00
*/
public function getSumDepositsUsed ( $invoice , $multicurrency = 0 )
{
dol_syslog ( get_class ( $this ) . " ::getSumDepositsUsed " , LOG_DEBUG );
2021-02-23 21:03:23 +00:00
if ( $invoice -> element == 'facture' || $invoice -> element == 'invoice' ) {
2022-01-27 11:52:13 +00:00
$sql = " SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount " ;
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except as rc, " . $this -> db -> prefix () . " facture as f " ;
$sql .= " WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = " . (( int ) $invoice -> id );
2023-06-01 09:49:56 +00:00
$sql .= " AND f.type = " . ( int ) $invoice :: TYPE_DEPOSIT ;
2021-02-23 21:03:23 +00:00
} elseif ( $invoice -> element == 'invoice_supplier' ) {
2022-01-27 11:52:13 +00:00
$sql = " SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount " ;
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except as rc, " . $this -> db -> prefix () . " facture_fourn as f " ;
$sql .= " WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = " . (( int ) $invoice -> id );
2023-06-01 09:49:56 +00:00
$sql .= " AND f.type = " . ( int ) $invoice :: TYPE_DEPOSIT ;
2020-10-31 13:32:18 +00:00
} else {
$this -> error = get_class ( $this ) . " ::getSumDepositsUsed was called with a bad object as a first parameter " ;
2024-01-10 15:57:10 +00:00
dol_print_error ( $this -> db , $this -> error );
2020-10-31 13:32:18 +00:00
return - 1 ;
}
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2020-10-31 13:32:18 +00:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-23 21:03:23 +00:00
if ( $multicurrency == 1 ) {
return $obj -> multicurrency_amount ;
} else {
return $obj -> amount ;
}
2020-10-31 13:32:18 +00:00
} else {
$this -> error = $this -> db -> lasterror ();
return - 1 ;
}
}
/**
* Return amount ( with tax ) of all credit notes invoices + excess received used by invoice as a payment
*
* @ param CommonInvoice $invoice Object invoice
2024-03-27 17:56:24 +00:00
* @ param int <- 1 , 1 > $multicurrency 1 = Return multicurrency_amount instead of amount . TODO Add a mode multicurrency = - 1 to return array with amount + multicurrency amount
2025-06-21 14:16:47 +00:00
* @ return float | string Return string 'Error...' if KO , Sum of credit notes and excess received amount otherwise
2020-10-31 13:32:18 +00:00
*/
public function getSumCreditNotesUsed ( $invoice , $multicurrency = 0 )
{
dol_syslog ( get_class ( $this ) . " ::getSumCreditNotesUsed " , LOG_DEBUG );
2021-02-23 21:03:23 +00:00
if ( $invoice -> element == 'facture' || $invoice -> element == 'invoice' ) {
2022-01-27 11:52:13 +00:00
$sql = " SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount " ;
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except as rc, " . $this -> db -> prefix () . " facture as f " ;
$sql .= " WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = " . (( int ) $invoice -> id );
$sql .= " AND f.type IN ( " . $this -> db -> sanitize ( $invoice :: TYPE_STANDARD . " , " . $invoice :: TYPE_CREDIT_NOTE . " , " . $invoice :: TYPE_SITUATION ) . " ) " ; // Find discount coming from credit note or excess received
2021-02-23 21:03:23 +00:00
} elseif ( $invoice -> element == 'invoice_supplier' ) {
2022-01-27 11:52:13 +00:00
$sql = " SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount " ;
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except as rc, " . $this -> db -> prefix () . " facture_fourn as f " ;
$sql .= " WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = " . (( int ) $invoice -> id );
$sql .= " AND f.type IN ( " . $this -> db -> sanitize ( $invoice :: TYPE_STANDARD . " , " . $invoice :: TYPE_CREDIT_NOTE ) . " ) " ; // Find discount coming from credit note or excess paid
2020-10-31 13:32:18 +00:00
} else {
$this -> error = get_class ( $this ) . " ::getSumCreditNotesUsed was called with a bad object as a first parameter " ;
2024-01-10 15:57:10 +00:00
dol_print_error ( $this -> db , $this -> error );
2025-06-21 14:16:47 +00:00
return 'ErrorBadElementType' ;
2020-10-31 13:32:18 +00:00
}
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2020-10-31 13:32:18 +00:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-23 21:03:23 +00:00
if ( $multicurrency == 1 ) {
return $obj -> multicurrency_amount ;
} else {
return $obj -> amount ;
}
2020-10-31 13:32:18 +00:00
} else {
$this -> error = $this -> db -> lasterror ();
2025-06-21 14:16:47 +00:00
return 'ErrorBadSQLquery' ;
2020-10-31 13:32:18 +00:00
}
}
/**
* Return amount ( with tax ) of all converted amount for this credit note
*
* @ param CommonInvoice $invoice Object invoice
2024-03-27 17:56:24 +00:00
* @ param int <- 1 , 1 > $multicurrency Return multicurrency_amount instead of amount . TODO Add a mode multicurrency = - 1 to return array with amount + multicurrency amount
2023-12-06 14:46:39 +00:00
* @ return int Return integer < 0 if KO , Sum of credit notes and deposits amount otherwise
2020-10-31 13:32:18 +00:00
*/
public function getSumFromThisCreditNotesNotUsed ( $invoice , $multicurrency = 0 )
{
dol_syslog ( get_class ( $this ) . " ::getSumCreditNotesUsed " , LOG_DEBUG );
2021-02-23 21:03:23 +00:00
if ( $invoice -> element == 'facture' || $invoice -> element == 'invoice' ) {
2022-01-27 11:52:13 +00:00
$sql = " SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount " ;
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except as rc " ;
$sql .= " WHERE rc.fk_facture IS NULL AND rc.fk_facture_source = " . (( int ) $invoice -> id );
2021-02-23 21:03:23 +00:00
} elseif ( $invoice -> element == 'invoice_supplier' ) {
2022-01-27 11:52:13 +00:00
$sql = " SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount " ;
$sql .= " FROM " . $this -> db -> prefix () . " societe_remise_except as rc " ;
$sql .= " WHERE rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_source = " . (( int ) $invoice -> id );
2020-10-31 13:32:18 +00:00
} else {
$this -> error = get_class ( $this ) . " ::getSumCreditNotesUsed was called with a bad object as a first parameter " ;
2024-01-10 15:57:10 +00:00
dol_print_error ( $this -> db , $this -> error );
2020-10-31 13:32:18 +00:00
return - 1 ;
}
$resql = $this -> db -> query ( $sql );
2021-02-23 21:03:23 +00:00
if ( $resql ) {
2020-10-31 13:32:18 +00:00
$obj = $this -> db -> fetch_object ( $resql );
2021-02-23 21:03:23 +00:00
if ( $multicurrency ) {
return $obj -> multicurrency_amount ;
} else {
return $obj -> amount ;
}
2020-10-31 13:32:18 +00:00
} else {
$this -> error = $this -> db -> lasterror ();
return - 1 ;
}
}
/**
* Return clickable ref of object ( with picto or not )
*
2024-03-27 17:56:24 +00:00
* @ param int < 0 , 1 > $withpicto 0 = No picto , 1 = Include picto into link , 2 = Picto only
* @ param string $option Where to link to ( 'invoice' or 'discount' )
* @ return string String with URL
2020-10-31 13:32:18 +00:00
*/
2024-11-05 14:33:09 +00:00
public function getNomUrl ( $withpicto = 0 , $option = 'invoice' )
2020-10-31 13:32:18 +00:00
{
global $langs ;
$result = '' ;
$link = '' ;
$linkend = '' ;
$label = '' ;
$picto = '' ;
$ref = '' ;
if ( $option == 'invoice' ) {
$facid = ! empty ( $this -> discount_type ) ? $this -> fk_invoice_supplier_source : $this -> fk_facture_source ;
$link = ! empty ( $this -> discount_type ) ? '/fourn/facture/card.php' : '/compta/facture/card.php' ;
$label = $langs -> trans ( " ShowSourceInvoice " ) . ': ' . $this -> ref_facture_source ;
$link = '<a href="' . DOL_URL_ROOT . $link . '?facid=' . $facid . '" title="' . dol_escape_htmltag ( $label , 1 ) . '" class="classfortooltip">' ;
$linkend = '</a>' ;
$ref = ! empty ( $this -> discount_type ) ? $this -> ref_invoice_supplier_source : $this -> ref_facture_source ;
$picto = 'bill' ;
}
if ( $option == 'discount' ) {
$label = $langs -> trans ( " Discount " );
2024-03-27 17:07:51 +00:00
$link = '<a href="' . DOL_URL_ROOT . '/comm/remx.php?id=' . $this -> socid . '" title="' . dol_escape_htmltag ( $label , 1 ) . '" class="classfortooltip">' ;
2020-10-31 13:32:18 +00:00
$linkend = '</a>' ;
$ref = $langs -> trans ( " Discount " );
$picto = 'generic' ;
}
2021-02-23 21:03:23 +00:00
if ( $withpicto ) {
$result .= ( $link . img_object ( $label , $picto , 'class="classfortooltip"' ) . $linkend );
}
if ( $withpicto && $withpicto != 2 ) {
$result .= ' ' ;
}
2020-10-31 13:32:18 +00:00
$result .= $link . $ref . $linkend ;
return $result ;
}
2009-03-02 21:21:49 +00:00
2011-09-11 10:33:48 +00:00
/**
2020-10-31 13:32:18 +00:00
* Initialise an instance with random values .
* Used to build previews or test instances .
* id must be 0 if object instance is a specimen .
*
2024-03-27 17:56:24 +00:00
* @ return int < 0 , 1 >
2011-09-11 10:33:48 +00:00
*/
2019-02-27 19:45:07 +00:00
public function initAsSpecimen ()
2011-09-11 10:33:48 +00:00
{
2023-11-26 16:27:14 +00:00
$this -> socid = 1 ;
2011-09-11 10:33:48 +00:00
$this -> amount_ht = 10 ;
$this -> amount_tva = 1.96 ;
$this -> amount_ttc = 11.96 ;
$this -> tva_tx = 19.6 ;
$this -> description = 'Specimen discount' ;
2024-03-02 15:38:35 +00:00
return 1 ;
2011-09-11 10:33:48 +00:00
}
2026-06-15 02:16:42 +00:00
/**
* Helper method to create a discount from an amount .
* Used by Service . class : set_remise_except ()
2026-07-15 00:06:09 +00:00
*
* @ param float $amount Currency amount to process ( with or without tax , depending on $amount_type )
2026-06-15 02:16:42 +00:00
* @ param int < 0 , 1 > $amount_type 0 = Amount includes no taxes , 1 = Amount includes all the taxes
2026-07-15 00:34:01 +00:00
* @ param float $tva_tx TVA ( main tax ) percentage ( 0 - 100 )
* @ param float $localtax1_tx localtax1 percentage ( 0 - 100 )
* @ param float $localtax2_tx localtax2 percentage ( 0 - 100 )
2026-06-15 02:16:42 +00:00
* @ param int < 0 , 1 > $localtax1_type localtax1 type
* @ param int < 0 , 1 > $localtax2_type localtax2 type
* @ return int OK = >= 0 , KO = < 0
*/
public function generateFromAmount ( $amount , $amount_type , $tva_tx , $localtax1_tx , $localtax2_tx , $localtax1_type = 1 , $localtax2_type = 1 )
{
2026-07-15 00:34:01 +00:00
$tva_tx_pct = ( float ) ( $tva_tx / 100 );
2026-06-15 02:16:42 +00:00
$localtax1_tx_pct = ( float ) ( $localtax1_tx / 100 );
$localtax2_tx_pct = ( float ) ( $localtax2_tx / 100 );
2026-07-15 00:34:01 +00:00
2026-06-15 02:16:42 +00:00
$err = 0 ;
2026-07-15 22:00:17 +00:00
//var_dump("amount=$amount, amount_type=$amount_type, tva_tx=$tva_tx, localtax1_tx=$localtax1_tx, localtax2_tx=$localtax2_tx, localtax1_type=$localtax1_type, localtax2_type=$localtax2_type");
// Test if localtax type is 2, 4 or 6 (loca tax are calculated on ht + vat)
2026-06-15 02:16:42 +00:00
$localtax1_type2 = (( int ) $localtax1_type > 0 && ( int ) $localtax1_type % 2 == 0 ? 1 : 0 );
$localtax2_type2 = (( int ) $localtax2_type > 0 && ( int ) $localtax2_type % 2 == 0 ? 1 : 0 );
if ( $amount_type == 1 ) {
// TTC
2026-07-15 22:00:17 +00:00
$this -> total_ttc = ( float ) price2num ( $amount , 'MT' );
$ttc = ( float ) $this -> total_ttc ;
2026-06-15 02:16:42 +00:00
2026-07-15 22:00:17 +00:00
// Calculate lt1 and/or lt2 = taxes added after VAT
2026-08-04 16:59:31 +00:00
$lt1 = 0 ;
$lt2 = 0 ;
$tx_before_vat = 0 ;
$tx_before_vat_without1 = 0 ;
$tx_before_vat_without2 = 0 ;
$tx_after_vat = 0 ;
$tx_after_vat_without1 = 0 ;
$tx_after_vat_without2 = 0 ;
2026-07-15 22:00:17 +00:00
if ( $localtax1_type2 && $localtax1_tx_pct > 0 ) {
$tx_after_vat += $localtax1_tx_pct ;
$tx_after_vat_without2 += $localtax1_tx_pct ;
2026-06-15 02:16:42 +00:00
} else {
2026-07-15 22:00:17 +00:00
$tx_before_vat += $localtax1_tx_pct ;
$tx_before_vat_without2 += $localtax1_tx_pct ;
}
if ( $localtax2_type2 && $localtax2_tx_pct > 0 ) {
$tx_after_vat += $localtax2_tx_pct ;
$tx_after_vat_without1 += $localtax2_tx_pct ;
} else {
$tx_before_vat += $localtax2_tx_pct ;
$tx_before_vat_without1 += $localtax2_tx_pct ;
}
$tx_before_vat += $tva_tx_pct ;
$tx_before_vat_without1 += $tva_tx_pct ;
$tx_before_vat_without2 += $tva_tx_pct ;
if ( $localtax1_type2 && $localtax1_tx_pct > 0 ) {
$lt1 = ( float ) price2num ( $ttc - $ttc / ( 1 + $tx_after_vat ) * ( 1 + $tx_after_vat_without1 ), 'MT' );
}
if ( $localtax2_type2 && $localtax2_tx_pct > 0 ) {
$lt2 = ( float ) price2num ( $ttc - $ttc / ( 1 + $tx_after_vat ) * ( 1 + $tx_after_vat_without2 ), 'MT' );
}
// lt1 and lt2 if calculated including taxes
//var_dump("if lt1 or lt2 are calculated including vat: lt1=$lt1 lt2=$lt2");
$htplusbeforevat = $ttc - $lt1 - $lt2 ; // $htplusbeforevat = amount with HT + taxes added before VAT
if ( ! $localtax1_type2 && $localtax1_tx_pct > 0 ) {
$lt1 = ( float ) price2num ( $htplusbeforevat - $htplusbeforevat / ( 1 + $tx_before_vat ) * ( 1 + $tx_before_vat_without1 ), 'MT' );
2026-06-15 02:16:42 +00:00
}
2026-07-15 22:00:17 +00:00
if ( ! $localtax2_type2 && $localtax2_tx_pct > 0 ) {
$lt2 = ( float ) price2num ( $htplusbeforevat - $htplusbeforevat / ( 1 + $tx_before_vat ) * ( 1 + $tx_before_vat_without2 ), 'MT' );
}
// lt1 and lt2 are now local taxes (whatever they are calculated before of after vat)
2026-08-04 16:59:31 +00:00
//var_dump("lt1 or lt2 whatever is calculation mode: lt1=$lt1 lt2=$lt2");
2026-07-15 22:00:17 +00:00
2026-08-04 16:59:31 +00:00
$tva = ( $ttc - $lt2 - $lt1 ) - ( $ttc - $lt2 - $lt1 ) / ( 1 + $tva_tx_pct );
2026-07-15 22:00:17 +00:00
$this -> total_tva = ( float ) price2num ( $tva , 'MT' );
$this -> total_localtax1 = $lt1 ;
$this -> total_localtax2 = $lt2 ;
$this -> total_ht = ( float ) price2num ( $this -> total_ttc - $this -> total_localtax1 - $this -> total_localtax2 - $this -> total_tva , 'MT' );
2026-06-15 02:16:42 +00:00
2026-07-15 22:00:17 +00:00
$this -> multicurrency_total_ttc = ( float ) price2num ( $amount * ( float ) $this -> multicurrency_tx , 'MT' );
$this -> multicurrency_total_ht = ( float ) price2num (( float ) $amount / ( 1 + $tva_tx_pct ) * ( float ) $this -> multicurrency_tx , 'MT' );
$this -> multicurrency_total_tva = ( float ) price2num ( $this -> multicurrency_total_ttc - $this -> multicurrency_total_ht , 'MT' );
2026-06-15 02:16:42 +00:00
} elseif ( $amount_type == 0 ) {
// HT
2026-07-15 22:00:17 +00:00
$this -> total_ht = ( float ) price2num ( $amount , 'MT' );
$this -> total_tva = ( float ) price2num (( float ) $this -> total_ht * $tva_tx_pct , 'MT' );
2026-07-15 00:34:01 +00:00
//$this->total_ttc = price2num((float) $this->total_ht + (float) $this->total_tva + ..., 'MT'); // Is set later
2026-06-15 02:16:42 +00:00
2026-07-15 22:00:17 +00:00
$this -> multicurrency_total_ht = ( float ) price2num ( $amount * ( float ) $this -> multicurrency_tx , 'MT' );
$this -> multicurrency_total_tva = ( float ) price2num ((( float ) $amount * $tva_tx_pct ) * ( float ) $this -> multicurrency_tx , 'MT' );
2026-07-15 00:34:01 +00:00
//$this->multicurrency_total_ttc = price2num(((float) $this->total_ht + (float) $this->total_tva + ...) * (float) $this->multicurrency_tx, 'MT'); // Is set later
2026-07-15 22:00:17 +00:00
if ( $localtax1_type2 == 0 ) {
$this -> total_localtax1 = ( float ) price2num (( float ) $this -> total_ht * $localtax1_tx_pct , 'MT' );
} elseif ( $localtax1_type2 == 1 ) {
$this -> total_localtax1 = ( float ) price2num ((( float ) $this -> total_ht + ( float ) $this -> total_tva ) * $localtax1_tx_pct , 'MT' );
}
if ( $localtax2_type2 == 0 ) {
$this -> total_localtax2 = ( float ) price2num (( float ) $this -> total_ht * $localtax2_tx_pct , 'MT' );
} elseif ( $localtax2_type2 == 1 ) {
$this -> total_localtax2 = ( float ) price2num ((( float ) $this -> total_ht + ( float ) $this -> total_tva ) * $localtax2_tx_pct , 'MT' );
}
2026-06-15 02:16:42 +00:00
}
2026-07-15 00:06:09 +00:00
// For backward compatibility
$this -> amount_ht = $this -> total_ht ;
$this -> amount_tva = $this -> total_tva ;
$this -> amount_ttc = $this -> total_ttc ;
$this -> multicurrency_amount_ht = $this -> multicurrency_total_ht ;
$this -> multicurrency_amount_tva = $this -> multicurrency_total_tva ;
$this -> multicurrency_amount_ttc = $this -> multicurrency_total_ttc ;
2026-06-15 02:16:42 +00:00
$this -> tva_tx = $tva_tx ;
$this -> localtax1_tx = $localtax1_tx ;
$this -> localtax1_type = $localtax1_type ;
$this -> localtax2_tx = $localtax2_tx ;
$this -> localtax2_type = $localtax2_type ;
2026-07-15 22:00:17 +00:00
//var_dump("localtax1 mode=$localtax1_type2 localtax2 mode=$localtax2_type2");
2026-06-15 02:16:42 +00:00
2026-07-15 00:06:09 +00:00
if ( empty ( $this -> total_ttc )) {
2026-06-28 11:43:41 +00:00
// If the total amount comes from a split discount, we take it as-is
// because recalculating the total amount from the net amount creates precision errors.
2026-07-15 22:00:17 +00:00
$this -> total_ttc = ( float ) price2num (( float ) $this -> total_ht + ( float ) $this -> total_tva + $this -> total_localtax1 + $this -> total_localtax2 , 'MT' );
$this -> multicurrency_total_ttc = ( float ) price2num ((( float ) $this -> total_ht + ( float ) $this -> total_tva + $this -> total_localtax1 + $this -> total_localtax2 ) * ( float ) $this -> multicurrency_tx , 'MT' );
2026-07-15 00:06:09 +00:00
// For backward compatibility
$this -> amount_ttc = $this -> total_ttc ;
$this -> multicurrency_amount_ttc = $this -> multicurrency_total_ttc ;
2026-06-15 02:16:42 +00:00
}
2026-07-15 22:00:17 +00:00
//var_dump("total_ht=".$this->total_ht." total_tva=".$this->total_tva." total_localtax1=".$this->total_localtax1." total_localtax2=".$this->total_localtax2." total_ttc=".$this->total_ttc);
2026-06-15 02:16:42 +00:00
return $err ;
}
/**
* Helper method to create two new discounts from split amount .
*
* @ param float $amount_ttc1 Currency amount 1
* @ param float $amount_ttc2 Currency amount 2
* @ return array < DiscountAbsolute > Array of 2 DiscountAbsolute , representing the splits
*/
public function splitAmount ( $amount_ttc1 , $amount_ttc2 )
{
// Moved from remx.php :: domain-related operations within action confirm_split
$newdiscount1 = new DiscountAbsolute ( $this -> db );
$newdiscount2 = new DiscountAbsolute ( $this -> db );
$newdiscount1 -> fk_facture_source = $this -> fk_facture_source ;
$newdiscount2 -> fk_facture_source = $this -> fk_facture_source ;
$newdiscount1 -> fk_facture = $this -> fk_facture ;
$newdiscount2 -> fk_facture = $this -> fk_facture ;
$newdiscount1 -> fk_facture_line = $this -> fk_facture_line ;
$newdiscount2 -> fk_facture_line = $this -> fk_facture_line ;
$newdiscount1 -> fk_invoice_supplier_source = $this -> fk_invoice_supplier_source ;
$newdiscount2 -> fk_invoice_supplier_source = $this -> fk_invoice_supplier_source ;
$newdiscount1 -> fk_invoice_supplier = $this -> fk_invoice_supplier ;
$newdiscount2 -> fk_invoice_supplier = $this -> fk_invoice_supplier ;
$newdiscount1 -> fk_invoice_supplier_line = $this -> fk_invoice_supplier_line ;
$newdiscount2 -> fk_invoice_supplier_line = $this -> fk_invoice_supplier_line ;
if ( $this -> description == '(CREDIT_NOTE)' || $this -> description == '(DEPOSIT)' ) {
$newdiscount1 -> description = $this -> description ;
$newdiscount2 -> description = $this -> description ;
} else {
$newdiscount1 -> description = $this -> description . ' (1)' ;
$newdiscount2 -> description = $this -> description . ' (2)' ;
}
$newdiscount1 -> fk_user = $this -> fk_user ;
$newdiscount2 -> fk_user = $this -> fk_user ;
$newdiscount1 -> fk_soc = $this -> fk_soc ;
$newdiscount1 -> socid = $this -> socid ;
$newdiscount2 -> fk_soc = $this -> fk_soc ;
$newdiscount2 -> socid = $this -> socid ;
$newdiscount1 -> discount_type = $this -> discount_type ;
$newdiscount2 -> discount_type = $this -> discount_type ;
$newdiscount1 -> datec = $this -> datec ;
$newdiscount2 -> datec = $this -> datec ;
$newdiscount1 -> tva_tx = $this -> tva_tx ;
$newdiscount2 -> tva_tx = $this -> tva_tx ;
$newdiscount1 -> localtax1_tx = $this -> localtax1_tx ;
$newdiscount2 -> localtax1_tx = $this -> localtax1_tx ;
$newdiscount1 -> localtax2_tx = $this -> localtax2_tx ;
$newdiscount2 -> localtax2_tx = $this -> localtax2_tx ;
$newdiscount1 -> vat_src_code = $this -> vat_src_code ;
$newdiscount2 -> vat_src_code = $this -> vat_src_code ;
$newdiscount1 -> generateFromAmount ( $amount_ttc1 , 1 , $newdiscount1 -> tva_tx , $newdiscount1 -> localtax1_tx , $newdiscount1 -> localtax2_tx , $this -> localtax1_type , $this -> localtax2_type );
2026-07-15 22:00:17 +00:00
$newdiscount2 -> generateFromAmount ( $amount_ttc2 , 1 , $newdiscount2 -> tva_tx , $newdiscount2 -> localtax1_tx , $newdiscount2 -> localtax2_tx , $this -> localtax1_type , $this -> localtax2_type );
2026-06-15 02:16:42 +00:00
return array ( $newdiscount1 , $newdiscount2 );
}
2006-06-30 23:38:12 +00:00
}