2012-07-11 18:13:41 +02:00
< ? php
2018-10-27 14:43:12 +02:00
/* Copyright ( C ) 2012 Regis Houssin < regis . houssin @ inodbox . com >
2014-11-14 16:43:49 +01:00
* Copyright ( C ) 2012 Cédric Salvador < csalvador @ gpcsolutions . fr >
* Copyright ( C ) 2012 - 2014 Raphaël Doursenaud < rdoursenaud @ gpcsolutions . fr >
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
* \brief File of the superclass of invoices classes ( customer and supplier )
*/
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
/**
2012-09-19 12:49:58 +02:00
* Superclass for invoices classes
2012-07-11 18:13:41 +02:00
*/
abstract class CommonInvoice extends CommonObject
{
2020-09-16 02:50:18 +02:00
use CommonIncoterm ;
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 .
* @ deprectad Remove this . A " proforma invoice " is an order with a look of invoice , not an invoice !
*/
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
* If paid completelly , this -> close_code will be null
*/
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
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
2020-10-23 22:24:20 +02:00
* @ return float 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' );
if ( $this -> statut == self :: STATUS_CLOSED && $this -> close_code == 'discount_vat' ) { // If invoice closed with discount for anticipated payment
$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 .
* Payments dones using discounts , credit notes , etc are not included .
2012-07-11 18:13:41 +02:00
*
2016-02-10 23:16:38 +01:00
* @ param int $multicurrency Return multicurrency_amount instead of amount
2020-10-23 22:24:20 +02:00
* @ return float Amount of payment already done , < 0 if KO
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
}
2016-02-10 23:16:38 +01:00
$sql = 'SELECT sum(amount) as amount, sum(multicurrency_amount) as multicurrency_amount' ;
2020-04-10 10:59:32 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . $table ;
$sql .= ' WHERE ' . $field . ' = ' . $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 );
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 );
$this -> db -> free ( $resql );
2021-02-23 22:03:23 +01:00
if ( $multicurrency ) {
return $obj -> multicurrency_amount ;
} else {
return $obj -> amount ;
}
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
/**
2017-02-17 00:19:28 +01:00
* Return amount ( with tax ) of all deposits invoices used by invoice .
2020-10-27 19:46:07 +01:00
* Should always be empty , except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS is on ( not recommended ) .
2017-01-23 20:54:52 +01:00
*
* @ param int $multicurrency Return multicurrency_amount instead of amount
2020-10-23 22:24:20 +02:00
* @ return float < 0 if KO , Sum of deposits amount otherwise
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
{
2021-02-23 22:03:23 +01:00
if ( $this -> element == 'facture_fourn' || $this -> element == 'invoice_supplier' ) {
2020-10-27 19:46:07 +01:00
// TODO
return 0.0 ;
}
require_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php' ;
$discountstatic = new DiscountAbsolute ( $this -> db );
$result = $discountstatic -> getSumDepositsUsed ( $this , $multicurrency );
if ( $result >= 0 ) {
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
/**
2018-07-02 11:33:33 +02:00
* Return amount ( with tax ) of all credit notes invoices + excess received used by invoice
2017-01-23 20:54:52 +01:00
*
* @ param int $multicurrency Return multicurrency_amount instead of amount
2020-10-23 22:24:20 +02:00
* @ return float < 0 if KO , Sum of credit notes and deposits amount otherwise
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 ) {
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
2020-10-23 22:24:20 +02:00
* @ return float < 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
*
2019-10-19 18:33:06 +02:00
* @ return array 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
$sql = 'SELECT rowid' ;
2020-04-10 10:59:32 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this -> table_element ;
$sql .= ' WHERE fk_facture_source = ' . $this -> id ;
$sql .= ' AND type = 2' ;
$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 );
}
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' , ... )
* @ return int < 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
{
$sql = 'SELECT rowid' ;
2020-04-10 10:59:32 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . $this -> table_element ;
$sql .= ' WHERE fk_facture_source = ' . $this -> id ;
$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)
2020-04-10 10:59:32 +02: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 ;
}
}
2018-02-26 09:45:15 +01:00
/**
* Return list of payments
*
* @ param string $filtertype 1 to filter on type of payment == 'PRE'
* @ return array Array with list of payments
*/
2019-02-25 22:27:04 +01:00
public function getListOfPayments ( $filtertype = '' )
2018-02-26 09:45:15 +01:00
{
2020-04-10 10:59:32 +02:00
$retarray = array ();
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' ;
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
}
2020-09-12 19:05:33 +02:00
$sql = 'SELECT p.ref, pf.amount, pf.multicurrency_amount, p.fk_paiement, p.datep, p.num_paiement as num, t.code' . $field3 ;
2020-04-10 10:59:32 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . $table . ' as pf, ' . MAIN_DB_PREFIX . $table2 . ' as p, ' . MAIN_DB_PREFIX . 'c_paiement as t' ;
$sql .= ' WHERE pf.' . $field . ' = ' . $this -> id ;
2018-02-26 09:45:15 +01:00
//$sql.= ' WHERE pf.'.$field.' = 1';
2020-04-10 10:59:32 +02:00
$sql .= ' AND pf.' . $field2 . ' = p.rowid' ;
$sql .= ' AND p.fk_paiement = t.id' ;
$sql .= ' AND p.entity IN (' . getEntity ( $sharedentity ) . ')' ;
2021-02-23 22:03:23 +01:00
if ( $filtertype ) {
$sql .= " AND t.code='PRE' " ;
}
2018-02-26 09:45:15 +01:00
dol_syslog ( get_class ( $this ) . " ::getListOfPayments " , LOG_DEBUG );
2020-04-10 10:59:32 +02:00
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2018-02-26 09:45:15 +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 ) {
2018-02-26 09:45:15 +01:00
$obj = $this -> db -> fetch_object ( $resql );
2020-10-31 14:32:18 +01:00
$tmp = array ( 'amount' => $obj -> amount , 'type' => $obj -> code , 'date' => $obj -> datep , 'num' => $obj -> num , 'ref' => $obj -> ref );
2020-09-12 19:05:33 +02:00
if ( ! empty ( $field3 )) {
2020-10-27 19:46:07 +01:00
$tmp [ 'ref_ext' ] = $obj -> ref_ext ;
2020-09-12 19:05:33 +02:00
}
2020-10-31 14:32:18 +01:00
$retarray [] = $tmp ;
2018-02-26 09:45:15 +01:00
$i ++ ;
}
2019-12-31 17:10:03 +01:00
$this -> db -> free ( $resql );
2019-12-31 17:10:36 +01:00
2019-12-31 17:06:30 +01:00
//look for credit notes and discounts and deposits
2019-12-31 17:07:56 +01:00
$sql = '' ;
2021-02-23 22:03:23 +01:00
if ( $this -> element == 'facture' || $this -> element == 'invoice' ) {
2019-12-31 01:08:25 +01: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' ;
2020-04-10 10:59:32 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe_remise_except as rc, ' . MAIN_DB_PREFIX . 'facture as f' ;
$sql .= ' WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = ' . $this -> id ;
$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' ) {
2019-12-31 01:08:25 +01: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' ;
2020-04-10 10:59:32 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe_remise_except as rc, ' . MAIN_DB_PREFIX . 'facture_fourn as f' ;
$sql .= ' WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = ' . $this -> id ;
$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)
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 ) {
2020-04-10 10:59:32 +02:00
$retarray [] = array ( 'amount' => $obj -> multicurrency_amount , 'type' => $obj -> type , 'date' => $obj -> date , 'num' => '0' , 'ref' => $obj -> ref );
2020-05-21 15:05:19 +02:00
} else {
2020-04-10 10:59:32 +02:00
$retarray [] = array ( 'amount' => $obj -> amount , 'type' => $obj -> type , '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 );
}
2019-12-31 17:07:07 +01:00
2018-02-26 09:45:15 +01:00
return $retarray ;
2020-05-21 15:05:19 +02:00
} else {
2020-04-10 10:59:32 +02:00
$this -> error = $this -> db -> lasterror ();
2018-02-26 09:45:15 +01:00
dol_print_error ( $this -> db );
return array ();
}
}
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
*
* @ return int <= 0 if no , > 0 if yes
*/
2020-10-27 19:46:07 +01:00
public function is_erasable ()
{
// phpcs:enable
2017-12-05 10:01:30 +01:00
global $conf ;
// We check if invoice is a temporary number (PROVxxxx)
$tmppart = substr ( $this -> ref , 1 , 4 );
2021-02-23 22:03:23 +01:00
if ( $this -> statut == self :: STATUS_DRAFT && $tmppart === 'PROV' ) { // If draft invoice and ref not yet defined
2017-12-05 10:01:30 +01:00
return 1 ;
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $conf -> global -> INVOICE_CAN_NEVER_BE_REMOVED )) {
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
2021-02-23 22:03:23 +01:00
if ( empty ( $conf -> global -> INVOICE_CAN_ALWAYS_BE_REMOVED ) && $maxref != '' && $maxref != $this -> ref ) {
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.
2021-02-23 22:03:23 +01:00
if ( empty ( $conf -> global -> INVOICE_CAN_ALWAYS_BE_REMOVED ) && $this -> getSommePaiement () > 0 ) {
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
}
/**
2018-01-09 19:12:08 +01:00
* Return if an invoice was dispatched into bookkeeping
2017-12-05 10:01:30 +01:00
*
* @ return int < 0 if KO , 0 = no , 1 = yes
*/
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
2020-09-19 21:19:04 +02:00
$sql = " SELECT COUNT(ab.rowid) as nb FROM " . MAIN_DB_PREFIX . " accounting_bookkeeping as ab WHERE ab.doc_type=' " . $this -> db -> escape ( $type ) . " ' AND ab.fk_doc = " . $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 ;
}
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
*
2016-09-29 10:38:15 +02:00
* @ return string Label of type of invoice
2012-07-11 18:13:41 +02:00
*/
2020-10-27 19:46:07 +01:00
public function getLibType ()
2012-07-11 18:13:41 +02:00
{
global $langs ;
2021-02-23 22:03:23 +01:00
if ( $this -> type == CommonInvoice :: TYPE_STANDARD ) {
return $langs -> trans ( " InvoiceStandard " );
} elseif ( $this -> type == CommonInvoice :: TYPE_REPLACEMENT ) {
return $langs -> trans ( " InvoiceReplacement " );
} elseif ( $this -> type == CommonInvoice :: TYPE_CREDIT_NOTE ) {
return $langs -> trans ( " InvoiceAvoir " );
} elseif ( $this -> type == CommonInvoice :: TYPE_DEPOSIT ) {
return $langs -> trans ( " InvoiceDeposit " );
} elseif ( $this -> type == CommonInvoice :: TYPE_PROFORMA ) {
return $langs -> trans ( " InvoiceProForma " ); // Not used.
} elseif ( $this -> type == CommonInvoice :: TYPE_SITUATION ) {
return $langs -> trans ( " InvoiceSituation " );
}
2012-07-11 18:13:41 +02:00
return $langs -> trans ( " Unknown " );
}
/**
* Return label of object status
*
2016-10-05 21:49:04 +02: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
2015-04-06 12:25:30 +02:00
* @ param integer $alreadypaid 0 = No payment already done , > 0 = Some payments were already done ( we recommand to put here amount payed if you have it , 1 otherwise )
2017-11-25 11:10:52 +01:00
* @ 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
{
2017-11-25 11:10:52 +01:00
return $this -> LibStatut ( $this -> paye , $this -> statut , $mode , $alreadypaid , $this -> type );
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
*
2013-04-14 01:28:43 +02:00
* @ param int $paye Status field paye
* @ param int $status Id status
2017-04-13 15:15:44 +02: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
2017-09-17 20:17:51 +02:00
* @ param integer $alreadypaid 0 = No payment already done , > 0 = Some payments were already done ( we recommand to put here amount payed if you have it , - 1 otherwise )
2020-11-06 11:52:48 +01:00
* @ param int $type Type invoice . If - 1 , we use $this -> type
2017-11-25 11:10:52 +01:00
* @ return string Label of status
2012-07-11 18:13:41 +02:00
*/
2020-11-06 11:52:48 +01:00
public function LibStatut ( $paye , $status , $mode = 0 , $alreadypaid = - 1 , $type = - 1 )
2012-07-11 18:13:41 +02:00
{
2020-10-27 19:46:07 +01:00
// phpcs:enable
2012-07-11 18:13:41 +02:00
global $langs ;
$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 ) {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusClosedUnpaid' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusClosedUnpaid' );
$statusType = 'status5' ;
} elseif (( $status == 3 || $status == 2 ) && $alreadypaid > 0 ) {
$labelStatus = $langs -> transnoentitiesnoconv ( 'BillStatusClosedPaidPartially' );
$labelStatusShort = $langs -> transnoentitiesnoconv ( 'Bill' . $prefix . 'StatusClosedPaidPartially' );
$statusType = 'status9' ;
} elseif ( $alreadypaid == 0 ) {
$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
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
*
2015-04-06 12:25:30 +02:00
* @ param integer $cond_reglement Condition of payment ( code or id ) to use . If 0 , we use current condition .
2019-03-15 23:00:50 +01:00
* @ return integer Date limite de reglement si ok , < 0 si 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 ;
}
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
2018-10-04 16:06:26 +02:00
$sqltemp = 'SELECT c.type_cdr, c.nbjour, c.decalage' ;
2020-04-10 10:59:32 +02:00
$sqltemp .= ' FROM ' . MAIN_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 );
/* Definition de la date limite */
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
2019-01-27 11:55:16 +01:00
$date_piece = dol_mktime ( 0 , 0 , 0 , date ( 'm' , $datelim ), date ( 'd' , $datelim ), date ( 'Y' , $datelim )); // Sans les heures minutes et secondes
2018-10-04 16:06:26 +02:00
$date_lim_current = dol_mktime ( 0 , 0 , 0 , date ( 'm' , $datelim ), $cdr_decalage , date ( 'Y' , $datelim )); // Sans les heures minutes et secondes
2020-04-10 10:59:32 +02:00
$date_lim_next = dol_time_plus_duree ( $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 .
*
* @ 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' )
* @ return int < 0 if KO , > 0 if OK
*/
public function demande_prelevement ( $fuser , $amount = 0 , $type = 'direct-debit' , $sourcetype = 'facture' )
{
// phpcs:enable
global $conf ;
$error = 0 ;
dol_syslog ( get_class ( $this ) . " ::demande_prelevement " , LOG_DEBUG );
2021-02-23 22:03:23 +01:00
if ( $this -> statut > 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 );
$bac -> fetch ( 0 , $this -> socid );
$sql = 'SELECT count(*)' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'prelevement_facture_demande' ;
if ( $type == 'bank-transfer' ) {
$sql .= ' WHERE fk_facture_fourn = ' . $this -> id ;
} else {
$sql .= ' WHERE fk_facture = ' . $this -> id ;
}
2020-10-31 14:32:18 +01:00
$sql .= ' AND ext_payment_id IS NULL' ; // To exclude record done for some online payments
2020-06-24 19:59:06 +02:00
$sql .= ' AND traite = 0' ;
dol_syslog ( get_class ( $this ) . " ::demande_prelevement " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
2021-02-23 22:03:23 +01:00
if ( $resql ) {
2020-06-24 19:59:06 +02:00
$row = $this -> db -> fetch_row ( $resql );
2021-02-23 22:03:23 +01:00
if ( $row [ 0 ] == 0 ) {
2020-06-24 19:59:06 +02:00
$now = dol_now ();
$totalpaye = $this -> getSommePaiement ();
$totalcreditnotes = $this -> getSumCreditNotesUsed ();
$totaldeposits = $this -> getSumDepositsUsed ();
//print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits;
// We can also use bcadd to avoid pb with floating points
// For example print 239.2 - 229.3 - 9.9; does not return 0.
//$resteapayer=bcadd($this->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT);
//$resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT);
2021-02-23 22:03:23 +01:00
if ( empty ( $amount )) {
$amount = price2num ( $this -> total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits , 'MT' );
}
2020-06-24 19:59:06 +02:00
2021-02-23 22:03:23 +01:00
if ( is_numeric ( $amount ) && $amount != 0 ) {
2020-06-24 19:59:06 +02:00
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'prelevement_facture_demande(' ;
if ( $type == 'bank-transfer' ) {
$sql .= 'fk_facture_fourn, ' ;
} else {
$sql .= 'fk_facture, ' ;
}
$sql .= ' amount, date_demande, fk_user_demande, code_banque, code_guichet, number, cle_rib, sourcetype, entity)' ;
$sql .= ' VALUES (' . $this -> id ;
$sql .= " ,' " . price2num ( $amount ) . " ' " ;
$sql .= " ,' " . $this -> db -> idate ( $now ) . " ' " ;
$sql .= " , " . $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 ) . " ' " ;
$sql .= " , " . $conf -> entity ;
$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 " ;
dol_syslog ( get_class ( $this ) . '::demandeprelevement Impossible de creer une demande, demande deja en cours' );
return 0 ;
}
2020-06-27 02:00:42 +02:00
} else {
2020-06-24 19:59:06 +02:00
$this -> error = $this -> db -> error ();
dol_syslog ( get_class ( $this ) . '::demandeprelevement Erreur -2' );
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 " ;
dol_syslog ( get_class ( $this ) . " ::demandeprelevement " . $this -> error . " $this->statut , $this->paye , $this->mode_reglement_id " );
return - 3 ;
}
}
// 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
* @ return int < 0 if OK , > 0 if KO
*/
public function demande_prelevement_delete ( $fuser , $did )
{
// phpcs:enable
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . 'prelevement_facture_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 ;
}
}
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
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
/**
2020-10-12 19:33:00 +02:00
* @ deprecated
* @ see $product_ref
2015-03-23 01:39:12 +01:00
*/
2020-10-12 19:33:00 +02:00
public $ref ; // Product ref (deprecated)
/**
* @ deprecated
* @ 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
* @ var double
*/
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
/**
* VAT %
* @ var float
*/
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
* @ var string
*/
public $localtax1_type ;
/**
* Local tax 2 type
* @ var string
*/
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 ;
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
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
2021-03-08 11:33:07 +01:00
public $buy_price_ht ;
public $buyprice ; // For backward compatibility
public $pa_ht ; // For backward compatibility
public $marge_tx ;
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 ;
2020-11-09 15:15:21 +01:00
public $special_code = 0 ;
2020-11-08 12:34:45 +01:00
2020-11-09 15:15:21 +01:00
public $fk_multicurrency ;
2020-11-10 13:20:45 +01:00
public $multicurrency_code ;
2020-11-10 20:13:54 +01:00
public $multicurrency_subprice ;
public $multicurrency_total_ht ;
public $multicurrency_total_tva ;
public $multicurrency_total_ttc ;
2021-03-08 11:33:07 +01:00
public $fk_user_author ;
public $fk_user_modif ;
2013-06-10 16:05:41 +02:00
}