2024-09-23 03:34:00 +02:00
< ? php
/* Copyright ( C ) 2011 Dimitri Mouillard < dmouillard @ teclib . com >
* Copyright ( C ) 2015 Laurent Destailleur < eldy @ users . sourceforge . net >
* Copyright ( C ) 2015 Alexandre Spangaro < aspangaro @ open - dsi . fr >
* Copyright ( C ) 2018 Nicolas ZABOURI < info @ inovea - conseil . com >
* Copyright ( c ) 2018 - 2024 Frédéric France < frederic . france @ free . fr >
* Copyright ( C ) 2016 - 2020 Ferran Marcet < fmarcet @ 2 byte . es >
* Copyright ( C ) 2024 MDW < mdeweerd @ users . noreply . github . com >
* Copyright ( C ) 2024 Frédéric France < frederic . france @ free . fr >
* Copyright ( C ) 2024 William Mead < william . mead @ manchenumerique . fr >
*
* 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
* the Free Software Foundation ; either version 3 of the License , or
* ( 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
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*/
/**
* \file htdocs / expensereport / class / expensereportline . class . php
* \ingroup expensereport
* \brief File to manage Expense Report lines
*/
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobjectline.class.php' ;
require_once DOL_DOCUMENT_ROOT . '/expensereport/class/expensereport_rule.class.php' ;
/**
* Class of expense report details lines
*/
class ExpenseReportLine extends CommonObjectLine
{
/**
* @ var DoliDB Database handler .
*/
public $db ;
/**
* @ var string Name of table without prefix where object is stored
*/
public $table_element = 'expensereport_det' ;
/**
* @ var string Error code ( or message )
*/
public $error = '' ;
/**
* @ var int ID
*/
public $rowid ;
/**
* @ var string
*/
public $comments ;
/**
* @ var float Quantity
*/
public $qty ;
/**
* @ var string | float | int
*/
public $value_unit ;
/**
* @ var int | string
*/
public $date ;
/**
* @ var int | string
*/
public $dates ;
/**
* @ var int ID
*/
public $fk_c_type_fees ;
/**
* @ var int ID
*/
public $fk_c_exp_tax_cat ;
/**
* @ var int ID
*/
public $fk_projet ;
/**
* @ var int ID
*/
public $fk_expensereport ;
/**
* @ var string
*/
public $type_fees_code ;
/**
* @ var string
*/
public $type_fees_libelle ;
/**
* @ var string
*/
public $type_fees_accountancy_code ;
/**
* @ var string
*/
public $projet_ref ;
/**
* @ var string
*/
public $projet_title ;
/**
* @ var int
*/
public $rang ;
/**
* @ var int | string
*/
public $vatrate ;
/**
* @ var string
*/
public $vat_src_code ;
/**
* @ var float
*/
public $tva_tx ;
/**
* @ var int | string
*/
public $localtax1_tx ;
/**
* @ var int | string
*/
public $localtax2_tx ;
/**
* @ var string
*/
public $localtax1_type ;
/**
* @ var string
*/
public $localtax2_type ;
/**
* @ var float
*/
public $total_ht ;
/**
* @ var float
*/
public $total_tva ;
/**
* @ var float
*/
public $total_ttc ;
/**
* @ var float
*/
public $total_localtax1 ;
/**
* @ var float
*/
public $total_localtax2 ;
// Multicurrency
/**
* @ var int Currency ID
*/
public $fk_multicurrency ;
/**
* @ var string multicurrency code
*/
public $multicurrency_code ;
/**
* @ var float
*/
public $multicurrency_tx ;
/**
* @ var float
*/
public $multicurrency_total_ht ;
/**
* @ var float
*/
public $multicurrency_total_tva ;
/**
* @ var float
*/
public $multicurrency_total_ttc ;
/**
* @ var int ID into llx_ecm_files table to link line to attached file
*/
public $fk_ecm_files ;
/**
* @ var string
*/
public $rule_warning_message ;
/**
* Constructor
*
* @ param DoliDB $db Handlet database
*/
public function __construct ( $db )
{
$this -> db = $db ;
}
/**
* Fetch record for expense report detailed line
*
* @ param int $rowid Id of object to load
* @ return int Return integer < 0 if KO , > 0 if OK
*/
public function fetch ( $rowid )
{
$sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_c_exp_tax_cat, fde.fk_projet as fk_project, fde.date,' ;
$sql .= ' fde.tva_tx as vatrate, fde.vat_src_code, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc, fde.fk_ecm_files,' ;
$sql .= ' fde.localtax1_tx, fde.localtax2_tx, fde.localtax1_type, fde.localtax2_type, fde.total_localtax1, fde.total_localtax2, fde.rule_warning_message,' ;
$sql .= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,' ;
$sql .= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'expensereport_det as fde' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_type_fees as ctf ON fde.fk_c_type_fees=ctf.id' ; // Sometimes type of expense report has been removed, so we use a left join here.
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'projet as pjt ON fde.fk_projet=pjt.rowid' ;
$sql .= ' WHERE fde.rowid = ' . (( int ) $rowid );
$result = $this -> db -> query ( $sql );
if ( $result ) {
$objp = $this -> db -> fetch_object ( $result );
$this -> rowid = $objp -> rowid ;
$this -> id = $objp -> rowid ;
2024-11-16 10:55:31 +01:00
//$this->ref = $objp->ref; Undefined property
2024-09-23 03:34:00 +02:00
$this -> fk_expensereport = $objp -> fk_expensereport ;
$this -> comments = $objp -> comments ;
$this -> qty = $objp -> qty ;
$this -> date = $objp -> date ;
$this -> dates = $this -> db -> jdate ( $objp -> date );
$this -> value_unit = $objp -> value_unit ;
$this -> fk_c_type_fees = $objp -> fk_c_type_fees ;
$this -> fk_c_exp_tax_cat = $objp -> fk_c_exp_tax_cat ;
$this -> fk_projet = $objp -> fk_project ; // deprecated
$this -> fk_project = $objp -> fk_project ;
$this -> type_fees_code = $objp -> type_fees_code ;
$this -> type_fees_libelle = $objp -> type_fees_libelle ;
$this -> projet_ref = $objp -> projet_ref ;
$this -> projet_title = $objp -> projet_title ;
$this -> vatrate = $objp -> vatrate ;
$this -> vat_src_code = $objp -> vat_src_code ;
$this -> localtax1_tx = $objp -> localtax1_tx ;
$this -> localtax2_tx = $objp -> localtax2_tx ;
$this -> localtax1_type = $objp -> localtax1_type ;
$this -> localtax2_type = $objp -> localtax2_type ;
$this -> total_ht = $objp -> total_ht ;
$this -> total_tva = $objp -> total_tva ;
$this -> total_ttc = $objp -> total_ttc ;
$this -> total_localtax1 = $objp -> total_localtax1 ;
$this -> total_localtax2 = $objp -> total_localtax2 ;
$this -> fk_ecm_files = $objp -> fk_ecm_files ;
$this -> rule_warning_message = $objp -> rule_warning_message ;
$this -> db -> free ( $result );
return $this -> id ;
} else {
dol_print_error ( $this -> db );
return - 1 ;
}
}
/**
* Insert a line of expense report
*
* @ param int $notrigger 1 = No trigger
* @ param bool $fromaddline false = keep default behavior , true = exclude the update_price () of parent object
* @ return int Return integer < 0 if KO , > 0 if OK
*/
public function insert ( $notrigger = 0 , $fromaddline = false )
{
global $user ;
$error = 0 ;
dol_syslog ( " ExpenseReportLine::Insert " , LOG_DEBUG );
// Clean parameters
$this -> comments = trim ( $this -> comments );
if ( empty ( $this -> value_unit )) {
$this -> value_unit = 0 ;
}
$this -> qty = ( float ) price2num ( $this -> qty );
$this -> vatrate = price2num ( $this -> vatrate );
if ( empty ( $this -> fk_c_exp_tax_cat )) {
$this -> fk_c_exp_tax_cat = 0 ;
}
$this -> db -> begin ();
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'expensereport_det' ;
$sql .= ' (fk_expensereport, fk_c_type_fees, fk_projet,' ;
$sql .= ' tva_tx, vat_src_code,' ;
$sql .= ' localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,' ;
$sql .= ' comments, qty, value_unit,' ;
$sql .= ' total_ht, total_tva, total_ttc,' ;
$sql .= ' total_localtax1, total_localtax2,' ;
$sql .= ' date, rule_warning_message, fk_c_exp_tax_cat, fk_ecm_files)' ;
$sql .= " VALUES ( " . $this -> db -> escape ( $this -> fk_expensereport ) . " , " ;
$sql .= " " . (( int ) $this -> fk_c_type_fees ) . " , " ;
$sql .= " " . (( int ) ( ! empty ( $this -> fk_project ) && $this -> fk_project > 0 ) ? $this -> fk_project : (( ! empty ( $this -> fk_projet ) && $this -> fk_projet > 0 ) ? $this -> fk_projet : 'null' )) . " , " ;
$sql .= " " . (( float ) $this -> vatrate ) . " , " ;
$sql .= " ' " . $this -> db -> escape ( empty ( $this -> vat_src_code ) ? '' : $this -> vat_src_code ) . " ', " ;
$sql .= " " . (( float ) price2num ( $this -> localtax1_tx )) . " , " ;
$sql .= " " . (( float ) price2num ( $this -> localtax2_tx )) . " , " ;
$sql .= " ' " . $this -> db -> escape ( $this -> localtax1_type ) . " ', " ;
$sql .= " ' " . $this -> db -> escape ( $this -> localtax2_type ) . " ', " ;
$sql .= " ' " . $this -> db -> escape ( $this -> comments ) . " ', " ;
$sql .= " " . (( float ) $this -> qty ) . " , " ;
$sql .= " " . (( float ) $this -> value_unit ) . " , " ;
$sql .= " " . (( float ) price2num ( $this -> total_ht )) . " , " ;
$sql .= " " . (( float ) price2num ( $this -> total_tva )) . " , " ;
$sql .= " " . (( float ) price2num ( $this -> total_ttc )) . " , " ;
$sql .= " " . (( float ) price2num ( $this -> total_localtax1 )) . " , " ;
$sql .= " " . (( float ) price2num ( $this -> total_localtax2 )) . " , " ;
$sql .= " ' " . $this -> db -> idate ( $this -> date ) . " ', " ;
$sql .= " " . ( empty ( $this -> rule_warning_message ) ? 'null' : " ' " . $this -> db -> escape ( $this -> rule_warning_message ) . " ' " ) . " , " ;
$sql .= " " . (( int ) $this -> fk_c_exp_tax_cat ) . " , " ;
$sql .= " " . ( $this -> fk_ecm_files > 0 ? (( int ) $this -> fk_ecm_files ) : 'null' );
$sql .= " ) " ;
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
$this -> id = $this -> db -> last_insert_id ( MAIN_DB_PREFIX . 'expensereport_det' );
if ( ! $error && ! $notrigger ) {
// Call triggers
$result = $this -> call_trigger ( 'EXPENSE_REPORT_DET_CREATE' , $user );
if ( $result < 0 ) {
$error ++ ;
}
// End call triggers
}
if ( ! $fromaddline ) {
$tmpparent = new ExpenseReport ( $this -> db );
$tmpparent -> fetch ( $this -> fk_expensereport );
$result = $tmpparent -> update_price ( 1 );
if ( $result < 0 ) {
$error ++ ;
$this -> error = $tmpparent -> error ;
$this -> errors = $tmpparent -> errors ;
}
}
} else {
$error ++ ;
}
if ( ! $error ) {
$this -> db -> commit ();
return $this -> id ;
} else {
$this -> error = $this -> db -> lasterror ();
dol_syslog ( " ExpenseReportLine::insert Error " . $this -> error , LOG_ERR );
$this -> db -> rollback ();
return - 2 ;
}
}
/**
* Function to get total amount in expense reports for a same rule
*
* @ param ExpenseReportRule $rule object rule to check
* @ param int $fk_user user author id
* @ param string $mode day | EX_DAY / month | EX_MON / year | EX_YEA to get amount
* @ return float Amount
*/
public function getExpAmount ( ExpenseReportRule $rule , $fk_user , $mode = 'day' )
{
$amount = 0 ;
$sql = 'SELECT SUM(d.total_ttc) as total_amount' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'expensereport_det d' ;
$sql .= ' INNER JOIN ' . MAIN_DB_PREFIX . 'expensereport e ON (d.fk_expensereport = e.rowid)' ;
$sql .= ' WHERE e.fk_user_author = ' . (( int ) $fk_user );
if ( ! empty ( $this -> id )) {
$sql .= ' AND d.rowid <> ' . (( int ) $this -> id );
}
$sql .= ' AND d.fk_c_type_fees = ' . (( int ) $rule -> fk_c_type_fees );
if ( $mode == 'day' || $mode == 'EX_DAY' ) {
$sql .= " AND d.date = ' " . dol_print_date ( $this -> date , '%Y-%m-%d' ) . " ' " ;
} elseif ( $mode == 'mon' || $mode == 'EX_MON' ) {
$sql .= " AND DATE_FORMAT(d.date, '%Y-%m') = ' " . dol_print_date ( $this -> date , '%Y-%m' ) . " ' " ; // @todo DATE_FORMAT is forbidden
} elseif ( $mode == 'year' || $mode == 'EX_YEA' ) {
$sql .= " AND DATE_FORMAT(d.date, '%Y') = ' " . dol_print_date ( $this -> date , '%Y' ) . " ' " ; // @todo DATE_FORMAT is forbidden
}
dol_syslog ( 'ExpenseReportLine::getExpAmount' );
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
$num = $this -> db -> num_rows ( $resql );
if ( $num > 0 ) {
$obj = $this -> db -> fetch_object ( $resql );
$amount = ( float ) $obj -> total_amount ;
}
} else {
dol_print_error ( $this -> db );
}
return $amount + $this -> total_ttc ;
}
/**
* Update line
*
* @ param User $user User
2024-10-19 01:14:20 +02:00
* @ param int $notrigger 1 = No trigger
2024-09-23 03:34:00 +02:00
* @ return int Return integer < 0 if KO , > 0 if OK
*/
2024-10-19 01:14:20 +02:00
public function update ( User $user , $notrigger = 0 )
2024-09-23 03:34:00 +02:00
{
global $langs ;
$error = 0 ;
// Clean parameters
$this -> comments = trim ( $this -> comments );
$this -> vatrate = price2num ( $this -> vatrate );
$this -> value_unit = price2num ( $this -> value_unit );
if ( empty ( $this -> fk_c_exp_tax_cat )) {
$this -> fk_c_exp_tax_cat = 0 ;
}
$this -> db -> begin ();
// Update line in database
$sql = " UPDATE " . MAIN_DB_PREFIX . " expensereport_det SET " ;
$sql .= " comments=' " . $this -> db -> escape ( $this -> comments ) . " ' " ;
$sql .= " , value_unit = " . (( float ) $this -> value_unit );
$sql .= " , qty= " . (( float ) $this -> qty );
$sql .= " , date=' " . $this -> db -> idate ( $this -> date ) . " ' " ;
$sql .= " , total_ht= " . (( float ) price2num ( $this -> total_ht , 'MT' ));
$sql .= " , total_tva= " . (( float ) price2num ( $this -> total_tva , 'MT' ));
$sql .= " , total_ttc= " . (( float ) price2num ( $this -> total_ttc , 'MT' ));
$sql .= " , total_localtax1= " . (( float ) price2num ( $this -> total_localtax1 , 'MT' ));
$sql .= " , total_localtax2= " . (( float ) price2num ( $this -> total_localtax2 , 'MT' ));
$sql .= " , tva_tx= " . (( float ) $this -> vatrate );
$sql .= " , vat_src_code=' " . $this -> db -> escape ( $this -> vat_src_code ) . " ' " ;
$sql .= " , localtax1_tx= " . (( float ) $this -> localtax1_tx );
$sql .= " , localtax2_tx= " . (( float ) $this -> localtax2_tx );
$sql .= " , localtax1_type=' " . $this -> db -> escape ( $this -> localtax1_type ) . " ' " ;
$sql .= " , localtax2_type=' " . $this -> db -> escape ( $this -> localtax2_type ) . " ' " ;
$sql .= " , rule_warning_message=' " . $this -> db -> escape ( $this -> rule_warning_message ) . " ' " ;
$sql .= " , fk_c_exp_tax_cat= " . $this -> db -> escape ( $this -> fk_c_exp_tax_cat );
$sql .= " , fk_ecm_files= " . ( $this -> fk_ecm_files > 0 ? (( int ) $this -> fk_ecm_files ) : 'null' );
if ( $this -> fk_c_type_fees ) {
$sql .= " , fk_c_type_fees = " . (( int ) $this -> fk_c_type_fees );
} else {
$sql .= " , fk_c_type_fees=null " ;
}
if ( $this -> fk_project > 0 ) {
$sql .= " , fk_projet= " . (( int ) $this -> fk_project );
} else {
$sql .= " , fk_projet=null " ;
}
$sql .= " WHERE rowid = " . (( int ) ( $this -> rowid ? $this -> rowid : $this -> id ));
dol_syslog ( " ExpenseReportLine::update " );
$resql = $this -> db -> query ( $sql );
if ( $resql ) {
$tmpparent = new ExpenseReport ( $this -> db );
$result = $tmpparent -> fetch ( $this -> fk_expensereport );
if ( $result > 0 ) {
$result = $tmpparent -> update_price ( 1 );
if ( $result < 0 ) {
$error ++ ;
$this -> error = $tmpparent -> error ;
$this -> errors = $tmpparent -> errors ;
}
} else {
$error ++ ;
$this -> error = $tmpparent -> error ;
$this -> errors = $tmpparent -> errors ;
}
} else {
$error ++ ;
dol_print_error ( $this -> db );
}
2024-10-19 01:14:20 +02:00
if ( ! $error && ! $notrigger ) {
// Call triggers
$result = $this -> call_trigger ( 'EXPENSE_REPORT_DET_MODIFY' , $user );
if ( $result < 0 ) {
$error ++ ;
}
// End call triggers
}
2024-09-23 03:34:00 +02:00
if ( ! $error ) {
$this -> db -> commit ();
return 1 ;
} else {
$this -> error = $this -> db -> lasterror ();
dol_syslog ( " ExpenseReportLine::update Error " . $this -> error , LOG_ERR );
$this -> db -> rollback ();
return - 2 ;
}
}
}