2004-10-20 23:06:45 +02:00
< ? php
2012-02-15 15:16:33 +01:00
/* Copyright ( C ) 2002 - 2004 Rodolphe Quiedeville < rodolphe @ quiedeville . org >
* Copyright ( C ) 2004 Eric Seigne < eric . seigne @ ryxeo . com >
2012-03-18 20:45:01 +01:00
* Copyright ( C ) 2004 - 2011 Laurent Destailleur < eldy @ users . sourceforge . net >
* Copyright ( C ) 2005 Marc Barilley < marc @ ocebo . com >
2013-01-22 21:36:30 +01:00
* Copyright ( C ) 2005 - 2013 Regis Houssin < regis . houssin @ capnetworks . com >
2012-03-18 20:45:01 +01:00
* Copyright ( C ) 2006 Andre Cianfarani < acianfa @ free . fr >
* Copyright ( C ) 2008 Raphael Bertrand < raphael . bertrand @ resultic . fr >
2014-07-04 11:02:41 +02:00
* Copyright ( C ) 2010 - 2014 Juanjo Menent < jmenent @ 2 byte . es >
2017-04-11 14:47:11 +02:00
* Copyright ( C ) 2010 - 2017 Philippe Grand < philippe . grand @ atoo - net . com >
2014-09-24 11:47:34 +02:00
* Copyright ( C ) 2012 - 2014 Christophe Battarel < christophe . battarel @ altairis . fr >
2015-02-26 14:15:33 +01:00
* Copyright ( C ) 2012 Cedric Salvador < csalvador @ gpcsolutions . fr >
2013-04-09 17:18:07 +02:00
* Copyright ( C ) 2013 Florian Henry < florian . henry @ open - concept . pro >
2015-02-15 15:07:24 +01:00
* Copyright ( C ) 2014 - 2015 Marcos García < marcosgdf @ gmail . com >
2018-06-15 09:47:28 +02:00
* Copyright ( C ) 2018 Nicolas ZABOURI < info @ inovea - conseil . com >
2018-09-19 15:03:24 +02:00
* Copyright ( C ) 2018 Frédéric France < frederic . france @ netlogic . fr >
2018-12-04 14:29:47 +01:00
* Copyright ( C ) 2018 Ferran Marcet < fmarcet @ 2 byte . es >
2012-03-19 17:18:11 +01:00
*
2012-03-18 20:45:01 +01: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-03-18 20:45:01 +01:00
* ( at your option ) any later version .
2012-03-19 17:18:11 +01:00
*
2012-03-18 20:45:01 +01:00
* 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 .
2012-03-19 17:18:11 +01:00
*
2012-03-18 20:45:01 +01:00
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
*/
2003-09-11 18:00:49 +02:00
2005-02-26 19:33:10 +01:00
/**
2010-04-28 19:30:59 +02:00
* \file htdocs / comm / propal / class / propal . class . php
2013-08-27 11:54:07 +02:00
* \brief File of class to manage proposals
2012-03-18 20:45:01 +01:00
*/
2004-08-07 17:35:08 +02:00
2012-08-22 23:11:24 +02:00
require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php' ;
2015-02-26 14:15:33 +01:00
require_once DOL_DOCUMENT_ROOT . " /core/class/commonobjectline.class.php " ;
2012-08-22 23:11:24 +02:00
require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php' ;
require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php' ;
require_once DOL_DOCUMENT_ROOT . '/margin/lib/margins.lib.php' ;
2016-02-16 20:44:23 +01:00
require_once DOL_DOCUMENT_ROOT . '/multicurrency/class/multicurrency.class.php' ;
2004-08-07 17:35:08 +02:00
2005-02-26 19:33:10 +01:00
/**
2013-08-27 11:54:07 +02:00
* Class to manage proposals
2008-08-28 01:00:37 +02:00
*/
2006-06-18 16:18:41 +02:00
class Propal extends CommonObject
2003-09-11 18:00:49 +02:00
{
2017-10-07 13:09:31 +02:00
public $element = 'propal' ;
public $table_element = 'propal' ;
public $table_element_line = 'propaldet' ;
public $fk_element = 'fk_propal' ;
public $picto = 'propal' ;
2017-12-18 15:39:40 +01:00
/**
* 0 = No test on entity , 1 = Test with field entity , 2 = Test with link by societe
* @ var int
*/
public $ismultientitymanaged = 1 ;
/**
* 0 = Default , 1 = View may be restricted to sales representative only if no permission to see all or to company of external user if external user
* @ var integer
*/
public $restrictiononfksoc = 1 ;
2016-12-10 12:21:48 +01:00
2017-10-07 13:09:31 +02:00
/**
* { @ inheritdoc }
*/
protected $table_ref_field = 'ref' ;
2014-12-25 21:47:39 +01:00
2015-04-03 05:18:47 +02:00
/**
* ID of the client
* @ var int
*/
2017-10-07 13:09:31 +02:00
public $socid ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
public $contactid ;
public $author ;
public $ref_client ;
2015-04-03 05:18:47 +02:00
/**
* Status of the quote
* @ var int
2015-04-23 23:21:06 +02:00
* @ see Propal :: STATUS_DRAFT , Propal :: STATUS_VALIDATED , Propal :: STATUS_SIGNED , Propal :: STATUS_NOTSIGNED , Propal :: STATUS_BILLED
2015-04-03 05:18:47 +02:00
*/
2017-10-07 13:09:31 +02:00
public $statut ;
2015-04-03 05:18:47 +02:00
/**
2015-04-23 23:21:06 +02:00
* @ deprecated
* @ see date_creation
2015-04-03 05:18:47 +02:00
*/
2017-10-07 13:09:31 +02:00
public $datec ;
2015-04-23 23:21:06 +02:00
2015-04-03 05:18:47 +02:00
/**
2015-04-23 23:21:06 +02:00
* Creation date
* @ var int
*/
public $date_creation ;
/**
* @ deprecated
* @ see date_validation
2015-04-03 05:18:47 +02:00
*/
2017-10-07 13:09:31 +02:00
public $datev ;
2015-04-23 23:21:06 +02:00
/**
* Validation date
* @ var int
*/
public $date_validation ;
2015-04-03 05:18:47 +02:00
/**
* Date of the quote
* @ var
*/
2017-10-07 13:09:31 +02:00
public $date ;
2015-04-03 05:18:47 +02:00
/**
2015-04-23 23:21:06 +02:00
* @ deprecated
* @ see date
2015-04-03 05:18:47 +02:00
*/
2017-10-07 13:09:31 +02:00
public $datep ;
public $date_livraison ;
public $fin_validite ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
public $user_author_id ;
public $user_valid_id ;
public $user_close_id ;
2012-03-18 19:23:01 +01:00
2015-04-03 05:18:47 +02:00
/**
* @ deprecated
2015-04-23 23:21:06 +02:00
* @ see total_ht
2015-04-03 05:18:47 +02:00
*/
2017-10-07 13:09:31 +02:00
public $price ;
2015-04-03 05:18:47 +02:00
/**
* @ deprecated
2015-04-23 23:21:06 +02:00
* @ see total_tva
2015-04-03 05:18:47 +02:00
*/
2017-10-07 13:09:31 +02:00
public $tva ;
2015-04-03 05:18:47 +02:00
/**
* @ deprecated
2015-04-23 23:21:06 +02:00
* @ see total_ttc
2015-04-03 05:18:47 +02:00
*/
2017-10-07 13:09:31 +02:00
public $total ;
public $cond_reglement_code ;
public $mode_reglement_code ;
2018-04-21 15:46:55 +02:00
public $remise = 0 ;
public $remise_percent = 0 ;
public $remise_absolue = 0 ;
2017-10-07 13:09:31 +02:00
public $fk_address ;
public $address_type ;
public $address ;
public $availability_id ;
public $availability_code ;
public $demand_reason_id ;
public $demand_reason_code ;
public $products = array ();
public $extraparams = array ();
2012-03-18 19:23:01 +01:00
2015-03-23 01:39:12 +01:00
/**
* @ var PropaleLigne []
*/
2017-10-07 13:09:31 +02:00
public $lines = array ();
public $line ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
public $labelstatut = array ();
public $labelstatut_short = array ();
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
public $specimen ;
2015-04-12 04:01:28 +02:00
2016-01-18 19:45:27 +01:00
// Multicurrency
2016-07-08 21:28:21 +02:00
public $fk_multicurrency ;
public $multicurrency_code ;
public $multicurrency_tx ;
public $multicurrency_total_ht ;
public $multicurrency_total_tva ;
public $multicurrency_total_ttc ;
public $oldcopy ;
2016-07-08 20:40:25 +02:00
2015-04-03 05:18:47 +02:00
/**
* Draft status
*/
const STATUS_DRAFT = 0 ;
/**
* Validated status
*/
const STATUS_VALIDATED = 1 ;
/**
* Signed quote
*/
const STATUS_SIGNED = 2 ;
/**
* Not signed quote
*/
const STATUS_NOTSIGNED = 3 ;
/**
2016-03-04 16:14:23 +01:00
* Billed or processed quote
2015-04-03 05:18:47 +02:00
*/
2017-05-05 13:43:43 +02:00
const STATUS_BILLED = 4 ; // Todo rename into STATUS_CLOSE ?
2012-03-18 19:23:01 +01:00
2018-04-21 15:46:55 +02:00
2017-10-07 13:09:31 +02:00
/**
* Constructor
*
* @ param DoliDB $db Database handler
* @ param int $socid Id third party
* @ param int $propalid Id proposal
*/
function __construct ( $db , $socid = " " , $propalid = 0 )
{
global $conf , $langs ;
$this -> db = $db ;
2018-04-21 15:46:55 +02:00
2017-10-07 13:09:31 +02:00
$this -> socid = $socid ;
$this -> id = $propalid ;
2018-04-21 15:46:55 +02:00
2017-10-07 13:09:31 +02:00
$this -> products = array ();
$this -> duree_validite = $conf -> global -> PROPALE_VALIDITY_DURATION ;
}
/**
* Add line into array products
* $this -> thirdparty should be loaded
*
* @ param int $idproduct Product Id to add
* @ param int $qty Quantity
* @ param int $remise_percent Discount effected on Product
* @ return int < 0 if KO , > 0 if OK
*
* TODO Replace calls to this function by generation objet Ligne
* inserted into table $this -> products
*/
function add_product ( $idproduct , $qty , $remise_percent = 0 )
{
global $conf , $mysoc ;
if ( ! $qty ) $qty = 1 ;
dol_syslog ( get_class ( $this ) . " ::add_product $idproduct , $qty , $remise_percent " );
if ( $idproduct > 0 )
{
$prod = new Product ( $this -> db );
$prod -> fetch ( $idproduct );
$productdesc = $prod -> description ;
$tva_tx = get_default_tva ( $mysoc , $this -> thirdparty , $prod -> id );
$tva_npr = get_default_npr ( $mysoc , $this -> thirdparty , $prod -> id );
if ( empty ( $tva_tx )) $tva_npr = 0 ;
$vat_src_code = '' ; // May be defined into tva_tx
$localtax1_tx = get_localtax ( $tva_tx , 1 , $mysoc , $this -> thirdparty , $tva_npr );
$localtax2_tx = get_localtax ( $tva_tx , 2 , $mysoc , $this -> thirdparty , $tva_npr );
// multiprices
if ( $conf -> global -> PRODUIT_MULTIPRICES && $this -> thirdparty -> price_level )
{
$price = $prod -> multiprices [ $this -> thirdparty -> price_level ];
}
else
{
$price = $prod -> price ;
}
$line = new PropaleLigne ( $this -> db );
$line -> fk_product = $idproduct ;
$line -> desc = $productdesc ;
$line -> qty = $qty ;
$line -> subprice = $price ;
$line -> remise_percent = $remise_percent ;
$line -> vat_src_code = $vat_src_code ;
$line -> tva_tx = $tva_tx ;
$line -> fk_unit = $prod -> fk_unit ;
2016-02-27 11:32:49 +01:00
if ( $tva_npr ) $line -> info_bits = 1 ;
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
$this -> lines [] = $line ;
}
}
/**
* Adding line of fixed discount in the proposal in DB
*
* @ param int $idremise Id of fixed discount
* @ return int > 0 if OK , < 0 if KO
*/
function insert_discount ( $idremise )
{
global $langs ;
include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php' ;
include_once DOL_DOCUMENT_ROOT . '/core/class/discount.class.php' ;
$this -> db -> begin ();
$remise = new DiscountAbsolute ( $this -> db );
$result = $remise -> fetch ( $idremise );
if ( $result > 0 )
{
if ( $remise -> fk_facture ) // Protection against multiple submission
{
$this -> error = $langs -> trans ( " ErrorDiscountAlreadyUsed " );
$this -> db -> rollback ();
return - 5 ;
}
$line = new PropaleLigne ( $this -> db );
$this -> line -> context = $this -> context ;
$line -> fk_propal = $this -> id ;
$line -> fk_remise_except = $remise -> id ;
$line -> desc = $remise -> description ; // Description ligne
$line -> vat_src_code = $remise -> vat_src_code ;
$line -> tva_tx = $remise -> tva_tx ;
$line -> subprice =- $remise -> amount_ht ;
$line -> fk_product = 0 ; // Id produit predefined
$line -> qty = 1 ;
$line -> remise = 0 ;
$line -> remise_percent = 0 ;
$line -> rang =- 1 ;
$line -> info_bits = 2 ;
// TODO deprecated
$line -> price =- $remise -> amount_ht ;
$line -> total_ht = - $remise -> amount_ht ;
$line -> total_tva = - $remise -> amount_tva ;
$line -> total_ttc = - $remise -> amount_ttc ;
$result = $line -> insert ();
if ( $result > 0 )
{
$result = $this -> update_price ( 1 );
if ( $result > 0 )
{
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> db -> rollback ();
return - 1 ;
}
}
else
{
$this -> error = $line -> error ;
$this -> db -> rollback ();
return - 2 ;
}
}
else
{
$this -> db -> rollback ();
return - 2 ;
}
}
2012-03-18 19:23:01 +01:00
/**
* Add a proposal line into database ( linked to product / service or not )
2016-07-08 18:24:55 +02:00
* The parameters are already supposed to be appropriate and with final values to the call
* of this method . Also , for the VAT rate , it must have already been defined
* by whose calling the method get_default_tva ( societe_vendeuse , societe_acheteuse , '' product )
* and desc must already have the right value ( it ' s up to the caller to manage multilanguage )
2012-03-18 19:23:01 +01:00
*
2017-11-13 13:07:31 +01:00
* @ param string $desc Description of line
* @ param float $pu_ht Unit price
* @ param float $qty Quantity
* @ param float $txtva Force Vat rate , - 1 for auto ( Can contain the vat_src_code too with syntax '9.9 (CODE)' )
* @ param float $txlocaltax1 Local tax 1 rate ( deprecated , use instead txtva with code inside )
* @ param float $txlocaltax2 Local tax 2 rate ( deprecated , use instead txtva with code inside )
2012-03-18 19:23:01 +01:00
* @ param int $fk_product Id du produit / service predefini
2015-02-10 11:38:13 +01:00
* @ param float $remise_percent Pourcentage de remise de la ligne
2012-03-18 19:23:01 +01:00
* @ param string $price_base_type HT or TTC
2015-02-10 11:38:13 +01:00
* @ param float $pu_ttc Prix unitaire TTC
2012-03-18 19:23:01 +01:00
* @ param int $info_bits Bits de type de lignes
2015-10-03 18:33:46 +02:00
* @ param int $type Type of line ( 0 = product , 1 = service ) . Not used if fk_product is defined , the type of product is used .
2012-03-18 19:23:01 +01:00
* @ param int $rang Position of line
2013-01-22 21:36:30 +01:00
* @ param int $special_code Special code ( also used by externals modules ! )
2012-03-18 19:23:01 +01:00
* @ param int $fk_parent_line Id of parent line
2012-07-23 10:46:09 +02:00
* @ param int $fk_fournprice Id supplier price
* @ param int $pa_ht Buying price without tax
2012-08-26 23:15:26 +02:00
* @ param string $label ? ? ?
2013-11-07 21:12:11 +01:00
* @ param int $date_start Start date of the line
* @ param int $date_end End date of the line
2015-02-28 04:59:27 +01:00
* @ param array $array_options extrafields array
2015-04-21 15:49:58 +02:00
* @ param string $fk_unit Code of the unit to use . Null to use the default one
2016-10-29 21:02:08 +02:00
* @ param string $origin 'order' , ...
* @ param int $origin_id Id of origin object
2016-12-11 00:42:52 +01:00
* @ param double $pu_ht_devise Unit price in currency
2017-05-04 10:45:20 +02:00
* @ param int $fk_remise_except Id discount if line is from a discount
* @ return int > 0 if OK , < 0 if KO
2012-03-18 19:23:01 +01:00
* @ see add_product
*/
2017-05-04 10:45:20 +02:00
function addline ( $desc , $pu_ht , $qty , $txtva , $txlocaltax1 = 0.0 , $txlocaltax2 = 0.0 , $fk_product = 0 , $remise_percent = 0.0 , $price_base_type = 'HT' , $pu_ttc = 0.0 , $info_bits = 0 , $type = 0 , $rang =- 1 , $special_code = 0 , $fk_parent_line = 0 , $fk_fournprice = 0 , $pa_ht = 0 , $label = '' , $date_start = '' , $date_end = '' , $array_options = 0 , $fk_unit = null , $origin = '' , $origin_id = 0 , $pu_ht_devise = 0 , $fk_remise_except = 0 )
2017-10-07 13:09:31 +02:00
{
global $mysoc , $conf , $langs ;
dol_syslog ( get_class ( $this ) . " ::addline propalid= $this->id , desc= $desc , pu_ht= $pu_ht , qty= $qty , txtva= $txtva , fk_product= $fk_product , remise_except= $remise_percent , price_base_type= $price_base_type , pu_ttc= $pu_ttc , info_bits= $info_bits , type= $type , fk_remise_except= " . $fk_remise_except );
2018-12-03 12:28:17 +01:00
if ( $this -> statut == self :: STATUS_DRAFT )
2017-10-07 13:09:31 +02:00
{
2018-12-03 12:28:17 +01:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php' ;
// Clean parameters
if ( empty ( $remise_percent )) $remise_percent = 0 ;
if ( empty ( $qty )) $qty = 0 ;
if ( empty ( $info_bits )) $info_bits = 0 ;
if ( empty ( $rang )) $rang = 0 ;
if ( empty ( $fk_parent_line ) || $fk_parent_line < 0 ) $fk_parent_line = 0 ;
$remise_percent = price2num ( $remise_percent );
$qty = price2num ( $qty );
$pu_ht = price2num ( $pu_ht );
$pu_ht_devise = price2num ( $pu_ht_devise );
$pu_ttc = price2num ( $pu_ttc );
if ( ! preg_match ( '/\((.*)\)/' , $txtva )) {
2018-12-04 14:54:58 +01:00
$txtva = price2num ( $txtva ); // $txtva can have format '5,1' or '5.1' or '5.1(XXX)', we must clean only if '5,1'
2018-12-03 12:28:17 +01:00
}
$txlocaltax1 = price2num ( $txlocaltax1 );
$txlocaltax2 = price2num ( $txlocaltax2 );
$pa_ht = price2num ( $pa_ht );
if ( $price_base_type == 'HT' )
{
$pu = $pu_ht ;
}
else
{
$pu = $pu_ttc ;
}
2017-10-07 13:09:31 +02:00
2018-12-03 12:28:17 +01:00
// Check parameters
if ( $type < 0 ) return - 1 ;
2017-10-07 13:09:31 +02:00
$this -> db -> begin ();
$product_type = $type ;
2015-10-03 18:33:46 +02:00
if ( ! empty ( $fk_product ))
{
$product = new Product ( $this -> db );
$result = $product -> fetch ( $fk_product );
$product_type = $product -> type ;
if ( ! empty ( $conf -> global -> STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL ) && $product_type == 0 && $product -> stock_reel < $qty ) {
2017-10-07 13:09:31 +02:00
$langs -> load ( " errors " );
$this -> error = $langs -> trans ( 'ErrorStockIsNotEnoughToAddProductOnProposal' , $product -> ref );
2015-10-03 18:33:46 +02:00
$this -> db -> rollback ();
return - 3 ;
}
}
2016-07-08 20:40:25 +02:00
2015-10-03 18:33:46 +02:00
// Calcul du total TTC et de la TVA pour la ligne a partir de
2017-10-07 13:09:31 +02:00
// qty, pu, remise_percent et txtva
// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
$localtaxes_type = getLocalTaxesFromRate ( $txtva , 0 , $this -> thirdparty , $mysoc );
// Clean vat code
$vat_src_code = '' ;
if ( preg_match ( '/\((.*)\)/' , $txtva , $reg ))
{
$vat_src_code = $reg [ 1 ];
$txtva = preg_replace ( '/\s*\(.*\)/' , '' , $txtva ); // Remove code into vatrate.
}
$tabprice = calcul_price_total ( $qty , $pu , $remise_percent , $txtva , $txlocaltax1 , $txlocaltax2 , 0 , $price_base_type , $info_bits , $product_type , $mysoc , $localtaxes_type , 100 , $this -> multicurrency_tx , $pu_ht_devise );
$total_ht = $tabprice [ 0 ];
$total_tva = $tabprice [ 1 ];
$total_ttc = $tabprice [ 2 ];
$total_localtax1 = $tabprice [ 9 ];
$total_localtax2 = $tabprice [ 10 ];
2016-12-11 00:42:52 +01:00
$pu_ht = $tabprice [ 3 ];
$pu_tva = $tabprice [ 4 ];
$pu_ttc = $tabprice [ 5 ];
2012-03-18 19:23:01 +01:00
2016-01-18 19:45:27 +01:00
// MultiCurrency
$multicurrency_total_ht = $tabprice [ 16 ];
2017-10-07 13:09:31 +02:00
$multicurrency_total_tva = $tabprice [ 17 ];
$multicurrency_total_ttc = $tabprice [ 18 ];
2016-12-11 00:42:52 +01:00
$pu_ht_devise = $tabprice [ 19 ];
2016-01-18 19:45:27 +01:00
2017-10-07 13:09:31 +02:00
// Rang to use
$rangtouse = $rang ;
if ( $rangtouse == - 1 )
{
$rangmax = $this -> line_max ( $fk_parent_line );
$rangtouse = $rangmax + 1 ;
}
// TODO A virer
// Anciens indicateurs: $price, $remise (a ne plus utiliser)
$price = $pu ;
$remise = 0 ;
if ( $remise_percent > 0 )
{
$remise = round (( $pu * $remise_percent / 100 ), 2 );
$price = $pu - $remise ;
}
// Insert line
$this -> line = new PropaleLigne ( $this -> db );
$this -> line -> context = $this -> context ;
$this -> line -> fk_propal = $this -> id ;
$this -> line -> label = $label ;
$this -> line -> desc = $desc ;
$this -> line -> qty = $qty ;
2016-12-10 12:21:48 +01:00
2016-10-29 21:02:08 +02:00
$this -> line -> vat_src_code = $vat_src_code ;
2017-10-07 13:09:31 +02:00
$this -> line -> tva_tx = $txtva ;
2018-01-05 01:43:51 +01:00
$this -> line -> localtax1_tx = ( $total_localtax1 ? $localtaxes_type [ 1 ] : 0 );
$this -> line -> localtax2_tx = ( $total_localtax2 ? $localtaxes_type [ 3 ] : 0 );
2013-09-12 09:59:23 +02:00
$this -> line -> localtax1_type = $localtaxes_type [ 0 ];
$this -> line -> localtax2_type = $localtaxes_type [ 2 ];
2017-10-07 13:09:31 +02:00
$this -> line -> fk_product = $fk_product ;
$this -> line -> product_type = $type ;
$this -> line -> fk_remise_except = $fk_remise_except ;
$this -> line -> remise_percent = $remise_percent ;
$this -> line -> subprice = $pu_ht ;
$this -> line -> rang = $rangtouse ;
$this -> line -> info_bits = $info_bits ;
$this -> line -> total_ht = $total_ht ;
$this -> line -> total_tva = $total_tva ;
$this -> line -> total_localtax1 = $total_localtax1 ;
$this -> line -> total_localtax2 = $total_localtax2 ;
$this -> line -> total_ttc = $total_ttc ;
$this -> line -> special_code = $special_code ;
$this -> line -> fk_parent_line = $fk_parent_line ;
$this -> line -> fk_unit = $fk_unit ;
$this -> line -> date_start = $date_start ;
$this -> line -> date_end = $date_end ;
2012-03-18 19:23:01 +01:00
2015-10-26 20:33:42 +01:00
$this -> line -> fk_fournprice = $fk_fournprice ;
2012-08-01 17:36:15 +02:00
$this -> line -> pa_ht = $pa_ht ;
2012-07-20 09:57:50 +02:00
2017-10-07 13:09:31 +02:00
$this -> line -> origin_id = $origin_id ;
$this -> line -> origin = $origin ;
2015-11-06 01:53:20 +01:00
2016-01-18 19:45:27 +01:00
// Multicurrency
$this -> line -> fk_multicurrency = $this -> fk_multicurrency ;
$this -> line -> multicurrency_code = $this -> multicurrency_code ;
2016-12-11 00:42:52 +01:00
$this -> line -> multicurrency_subprice = $pu_ht_devise ;
2016-01-18 19:45:27 +01:00
$this -> line -> multicurrency_total_ht = $multicurrency_total_ht ;
2017-10-07 13:09:31 +02:00
$this -> line -> multicurrency_total_tva = $multicurrency_total_tva ;
$this -> line -> multicurrency_total_ttc = $multicurrency_total_ttc ;
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
// Mise en option de la ligne
if ( empty ( $qty ) && empty ( $special_code )) $this -> line -> special_code = 3 ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// TODO deprecated
$this -> line -> price = $price ;
$this -> line -> remise = $remise ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
if ( is_array ( $array_options ) && count ( $array_options ) > 0 ) {
$this -> line -> array_options = $array_options ;
}
2013-06-10 16:05:41 +02:00
2017-10-07 13:09:31 +02:00
$result = $this -> line -> insert ();
if ( $result > 0 )
{
// Reorder if child line
if ( ! empty ( $fk_parent_line )) $this -> line_order ( true , 'DESC' );
2012-03-18 19:23:01 +01:00
// Mise a jour informations denormalisees au niveau de la propale meme
2016-04-08 19:46:56 +02:00
$result = $this -> update_price ( 1 , 'auto' , 0 , $mysoc ); // This method is designed to add line from user input so total calculation must be done using 'auto' mode.
2012-03-18 19:23:01 +01:00
if ( $result > 0 )
{
$this -> db -> commit ();
return $this -> line -> rowid ;
}
else
{
$this -> error = $this -> db -> error ();
$this -> db -> rollback ();
return - 1 ;
}
}
else
{
$this -> error = $this -> line -> error ;
$this -> db -> rollback ();
return - 2 ;
}
}
2017-10-19 12:30:36 +02:00
else
{
dol_syslog ( get_class ( $this ) . " ::addline status of order must be Draft to allow use of ->addline() " , LOG_ERR );
return - 3 ;
2017-10-07 13:09:31 +02:00
}
2012-03-18 19:23:01 +01:00
}
2017-10-07 13:09:31 +02:00
/**
* Update a proposal line
*
* @ param int $rowid Id de la ligne
* @ param float $pu Prix unitaire ( HT ou TTC selon price_base_type )
* @ param float $qty Quantity
* @ param float $remise_percent Remise effectuee sur le produit
* @ param float $txtva Taux de TVA
* @ param float $txlocaltax1 Local tax 1 rate
* @ param float $txlocaltax2 Local tax 2 rate
* @ param string $desc Description
* @ param string $price_base_type HT ou TTC
* @ param int $info_bits Miscellaneous informations
* @ param int $special_code Special code ( also used by externals modules ! )
* @ param int $fk_parent_line Id of parent line ( 0 in most cases , used by modules adding sublevels into lines ) .
* @ param int $skip_update_total Keep fields total_xxx to 0 ( used for special lines by some modules )
* @ param int $fk_fournprice Id of origin supplier price
* @ param int $pa_ht Price ( without tax ) of product when it was bought
* @ param string $label ? ? ?
* @ param int $type 0 / 1 = Product / service
* @ param int $date_start Start date of the line
* @ param int $date_end End date of the line
2015-02-28 04:59:27 +01:00
* @ param array $array_options extrafields array
2017-10-07 13:09:31 +02:00
* @ param string $fk_unit Code of the unit to use . Null to use the default one
2016-12-11 00:42:52 +01:00
* @ param double $pu_ht_devise Unit price in currency
2017-06-22 16:00:12 +02:00
* @ param int $notrigger disable line update trigger
2017-10-07 13:09:31 +02:00
* @ return int 0 if OK , < 0 if KO
*/
2017-06-22 16:00:12 +02:00
function updateline ( $rowid , $pu , $qty , $remise_percent , $txtva , $txlocaltax1 = 0.0 , $txlocaltax2 = 0.0 , $desc = '' , $price_base_type = 'HT' , $info_bits = 0 , $special_code = 0 , $fk_parent_line = 0 , $skip_update_total = 0 , $fk_fournprice = 0 , $pa_ht = 0 , $label = '' , $type = 0 , $date_start = '' , $date_end = '' , $array_options = 0 , $fk_unit = null , $pu_ht_devise = 0 , $notrigger = 0 )
2017-10-07 13:09:31 +02:00
{
global $mysoc ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
dol_syslog ( get_class ( $this ) . " ::updateLine rowid= $rowid , pu= $pu , qty= $qty , remise_percent= $remise_percent ,
2015-11-06 01:53:20 +01:00
txtva = $txtva , desc = $desc , price_base_type = $price_base_type , info_bits = $info_bits , special_code = $special_code , fk_parent_line = $fk_parent_line , pa_ht = $pa_ht , type = $type , date_start = $date_start , date_end = $date_end " );
2017-10-07 13:09:31 +02:00
include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php' ;
// Clean parameters
$remise_percent = price2num ( $remise_percent );
$qty = price2num ( $qty );
$pu = price2num ( $pu );
2018-06-13 23:04:08 +02:00
$pu_ht_devise = price2num ( $pu_ht_devise );
2017-10-07 13:09:31 +02:00
$txtva = price2num ( $txtva );
$txlocaltax1 = price2num ( $txlocaltax1 );
$txlocaltax2 = price2num ( $txlocaltax2 );
$pa_ht = price2num ( $pa_ht );
if ( empty ( $qty ) && empty ( $special_code )) $special_code = 3 ; // Set option tag
if ( ! empty ( $qty ) && $special_code == 3 ) $special_code = 0 ; // Remove option tag
if ( empty ( $type )) $type = 0 ;
if ( $this -> statut == self :: STATUS_DRAFT )
{
$this -> db -> begin ();
// Calcul du total TTC et de la TVA pour la ligne a partir de
// qty, pu, remise_percent et txtva
// TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
// la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
$localtaxes_type = getLocalTaxesFromRate ( $txtva , 0 , $this -> thirdparty , $mysoc );
// Clean vat code
$vat_src_code = '' ;
if ( preg_match ( '/\((.*)\)/' , $txtva , $reg ))
{
$vat_src_code = $reg [ 1 ];
$txtva = preg_replace ( '/\s*\(.*\)/' , '' , $txtva ); // Remove code into vatrate.
}
$tabprice = calcul_price_total ( $qty , $pu , $remise_percent , $txtva , $txlocaltax1 , $txlocaltax2 , 0 , $price_base_type , $info_bits , $type , $mysoc , $localtaxes_type , 100 , $this -> multicurrency_tx , $pu_ht_devise );
$total_ht = $tabprice [ 0 ];
$total_tva = $tabprice [ 1 ];
$total_ttc = $tabprice [ 2 ];
$total_localtax1 = $tabprice [ 9 ];
$total_localtax2 = $tabprice [ 10 ];
2016-12-11 00:42:52 +01:00
$pu_ht = $tabprice [ 3 ];
$pu_tva = $tabprice [ 4 ];
$pu_ttc = $tabprice [ 5 ];
2012-03-18 19:23:01 +01:00
2016-01-21 22:40:07 +01:00
// MultiCurrency
$multicurrency_total_ht = $tabprice [ 16 ];
2017-10-07 13:09:31 +02:00
$multicurrency_total_tva = $tabprice [ 17 ];
$multicurrency_total_ttc = $tabprice [ 18 ];
2016-12-11 00:42:52 +01:00
$pu_ht_devise = $tabprice [ 19 ];
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
// Anciens indicateurs: $price, $remise (a ne plus utiliser)
$price = $pu ;
2017-12-06 23:21:58 +01:00
$remise = 0 ;
2017-10-07 13:09:31 +02:00
if ( $remise_percent > 0 )
{
$remise = round (( $pu * $remise_percent / 100 ), 2 );
$price = $pu - $remise ;
}
//Fetch current line from the database and then clone the object and set it in $oldline property
$line = new PropaleLigne ( $this -> db );
$line -> fetch ( $rowid );
2016-11-30 16:48:27 +01:00
$line -> fetch_optionals (); // Fetch extrafields for oldcopy
2012-03-18 19:23:01 +01:00
2015-09-24 16:32:48 +02:00
$staticline = clone $line ;
2015-02-26 13:19:19 +01:00
2017-10-07 13:09:31 +02:00
$line -> oldline = $staticline ;
$this -> line = $line ;
$this -> line -> context = $this -> context ;
// Reorder if fk_parent_line change
if ( ! empty ( $fk_parent_line ) && ! empty ( $staticline -> fk_parent_line ) && $fk_parent_line != $staticline -> fk_parent_line )
{
$rangmax = $this -> line_max ( $fk_parent_line );
$this -> line -> rang = $rangmax + 1 ;
}
$this -> line -> rowid = $rowid ;
$this -> line -> label = $label ;
$this -> line -> desc = $desc ;
$this -> line -> qty = $qty ;
$this -> line -> product_type = $type ;
$this -> line -> vat_src_code = $vat_src_code ;
$this -> line -> tva_tx = $txtva ;
$this -> line -> localtax1_tx = $txlocaltax1 ;
$this -> line -> localtax2_tx = $txlocaltax2 ;
2013-09-12 09:59:23 +02:00
$this -> line -> localtax1_type = $localtaxes_type [ 0 ];
2013-11-19 21:08:02 +01:00
$this -> line -> localtax2_type = $localtaxes_type [ 2 ];
2017-10-07 13:09:31 +02:00
$this -> line -> remise_percent = $remise_percent ;
$this -> line -> subprice = $pu_ht ;
$this -> line -> info_bits = $info_bits ;
$this -> line -> total_ht = $total_ht ;
$this -> line -> total_tva = $total_tva ;
$this -> line -> total_localtax1 = $total_localtax1 ;
$this -> line -> total_localtax2 = $total_localtax2 ;
$this -> line -> total_ttc = $total_ttc ;
$this -> line -> special_code = $special_code ;
$this -> line -> fk_parent_line = $fk_parent_line ;
$this -> line -> skip_update_total = $skip_update_total ;
$this -> line -> fk_unit = $fk_unit ;
2012-03-18 19:23:01 +01:00
2015-10-26 20:33:42 +01:00
$this -> line -> fk_fournprice = $fk_fournprice ;
2017-10-07 13:09:31 +02:00
$this -> line -> pa_ht = $pa_ht ;
2013-04-27 15:08:35 +02:00
2017-10-07 13:09:31 +02:00
$this -> line -> date_start = $date_start ;
$this -> line -> date_end = $date_end ;
2012-07-20 09:57:50 +02:00
2017-10-07 13:09:31 +02:00
// TODO deprecated
$this -> line -> price = $price ;
$this -> line -> remise = $remise ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
if ( is_array ( $array_options ) && count ( $array_options ) > 0 ) {
$this -> line -> array_options = $array_options ;
}
2013-06-10 16:05:41 +02:00
2016-01-21 22:40:07 +01:00
// Multicurrency
2016-12-11 00:42:52 +01:00
$this -> line -> multicurrency_subprice = $pu_ht_devise ;
2016-01-21 22:40:07 +01:00
$this -> line -> multicurrency_total_ht = $multicurrency_total_ht ;
2017-10-07 13:09:31 +02:00
$this -> line -> multicurrency_total_tva = $multicurrency_total_tva ;
$this -> line -> multicurrency_total_ttc = $multicurrency_total_ttc ;
$result = $this -> line -> update ( $notrigger );
if ( $result > 0 )
{
// Reorder if child line
if ( ! empty ( $fk_parent_line )) $this -> line_order ( true , 'DESC' );
$this -> update_price ( 1 );
$this -> fk_propal = $this -> id ;
$this -> rowid = $rowid ;
$this -> db -> commit ();
return $result ;
}
else
{
$this -> error = $this -> line -> error ;
$this -> db -> rollback ();
return - 1 ;
}
}
else
{
dol_syslog ( get_class ( $this ) . " ::updateline Erreur -2 Propal en mode incompatible pour cette action " );
return - 2 ;
}
}
/**
* Delete detail line
*
* @ param int $lineid Id of line to delete
* @ return int > 0 if OK , < 0 if KO
*/
function deleteline ( $lineid )
{
2017-12-03 20:51:26 +01:00
global $user ;
2017-10-07 13:09:31 +02:00
if ( $this -> statut == self :: STATUS_DRAFT )
{
2017-12-21 16:50:18 +01:00
$this -> db -> begin ();
2017-10-07 13:09:31 +02:00
$line = new PropaleLigne ( $this -> db );
// For triggers
$line -> fetch ( $lineid );
2017-12-03 20:51:26 +01:00
if ( $line -> delete ( $user ) > 0 )
2017-10-07 13:09:31 +02:00
{
$this -> update_price ( 1 );
2017-12-21 16:50:18 +01:00
$this -> db -> commit ();
2017-10-07 13:09:31 +02:00
return 1 ;
}
else
{
2017-12-21 16:50:18 +01:00
$this -> db -> rollback ();
2017-10-07 13:09:31 +02:00
return - 1 ;
}
}
else
{
2017-12-21 16:50:18 +01:00
$this -> error = 'ErrorDeleteLineNotAllowedByObjectStatus' ;
2017-10-07 13:09:31 +02:00
return - 2 ;
}
}
/**
* Create commercial proposal into database
* this -> ref can be set or empty . If empty , we will use " (PROVid) "
*
* @ param User $user User that create
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , >= 0 if OK
*/
function create ( $user , $notrigger = 0 )
{
global $conf , $hookmanager ;
$error = 0 ;
$now = dol_now ();
// Clean parameters
if ( empty ( $this -> date )) $this -> date = $this -> datep ;
$this -> fin_validite = $this -> date + ( $this -> duree_validite * 24 * 3600 );
if ( empty ( $this -> availability_id )) $this -> availability_id = 0 ;
if ( empty ( $this -> demand_reason_id )) $this -> demand_reason_id = 0 ;
2009-09-13 22:19:59 +02:00
2017-11-02 18:14:55 +01:00
// Multicurrency (test on $this->multicurrency_tx because we should take the default rate only if not using origin rate)
if ( ! empty ( $this -> multicurrency_code ) && empty ( $this -> multicurrency_tx )) list ( $this -> fk_multicurrency , $this -> multicurrency_tx ) = MultiCurrency :: getIdAndTxFromCode ( $this -> db , $this -> multicurrency_code , $this -> date );
else $this -> fk_multicurrency = MultiCurrency :: getIdFromCode ( $this -> db , $this -> multicurrency_code );
2016-01-18 19:45:27 +01:00
if ( empty ( $this -> fk_multicurrency ))
{
2016-01-22 22:35:32 +01:00
$this -> multicurrency_code = $conf -> currency ;
2016-01-18 19:45:27 +01:00
$this -> fk_multicurrency = 0 ;
$this -> multicurrency_tx = 1 ;
}
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
dol_syslog ( get_class ( $this ) . " ::create " );
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// Check parameters
$result = $this -> fetch_thirdparty ();
if ( $result < 0 )
{
$this -> error = " Failed to fetch company " ;
dol_syslog ( get_class ( $this ) . " ::create " . $this -> error , LOG_ERR );
return - 3 ;
}
2014-05-13 10:12:45 +02:00
2017-10-07 13:09:31 +02:00
// Check parameters
2014-05-13 10:12:45 +02:00
if ( ! empty ( $this -> ref )) // We check that ref is not already used
{
$result = self :: isExistingObject ( $this -> element , 0 , $this -> ref ); // Check ref is not yet used
if ( $result > 0 )
{
$this -> error = 'ErrorRefAlreadyExists' ;
dol_syslog ( get_class ( $this ) . " ::create " . $this -> error , LOG_WARNING );
$this -> db -> rollback ();
return - 1 ;
}
}
2017-10-07 13:09:31 +02:00
if ( empty ( $this -> date ))
{
$this -> error = " Date of proposal is required " ;
dol_syslog ( get_class ( $this ) . " ::create " . $this -> error , LOG_ERR );
return - 4 ;
}
$this -> db -> begin ();
// Insert into database
$sql = " INSERT INTO " . MAIN_DB_PREFIX . " propal ( " ;
$sql .= " fk_soc " ;
$sql .= " , price " ;
$sql .= " , remise " ;
$sql .= " , remise_percent " ;
$sql .= " , remise_absolue " ;
$sql .= " , tva " ;
$sql .= " , total " ;
$sql .= " , datep " ;
$sql .= " , datec " ;
$sql .= " , ref " ;
$sql .= " , fk_user_author " ;
$sql .= " , note_private " ;
$sql .= " , note_public " ;
$sql .= " , model_pdf " ;
$sql .= " , fin_validite " ;
$sql .= " , fk_cond_reglement " ;
$sql .= " , fk_mode_reglement " ;
$sql .= " , fk_account " ;
$sql .= " , ref_client " ;
$sql .= " , date_livraison " ;
$sql .= " , fk_shipping_method " ;
$sql .= " , fk_availability " ;
$sql .= " , fk_input_reason " ;
$sql .= " , fk_projet " ;
$sql .= " , fk_incoterms " ;
$sql .= " , location_incoterms " ;
$sql .= " , entity " ;
$sql .= " , fk_multicurrency " ;
$sql .= " , multicurrency_code " ;
$sql .= " , multicurrency_tx " ;
$sql .= " ) " ;
$sql .= " VALUES ( " ;
$sql .= $this -> socid ;
$sql .= " , 0 " ;
$sql .= " , " . $this -> remise ;
$sql .= " , " . ( $this -> remise_percent ? $this -> db -> escape ( $this -> remise_percent ) : 'NULL' );
$sql .= " , " . ( $this -> remise_absolue ? $this -> db -> escape ( $this -> remise_absolue ) : 'NULL' );
$sql .= " , 0 " ;
$sql .= " , 0 " ;
$sql .= " , ' " . $this -> db -> idate ( $this -> date ) . " ' " ;
$sql .= " , ' " . $this -> db -> idate ( $now ) . " ' " ;
$sql .= " , '(PROV)' " ;
$sql .= " , " . ( $user -> id > 0 ? " ' " . $user -> id . " ' " : " NULL " );
$sql .= " , ' " . $this -> db -> escape ( $this -> note_private ) . " ' " ;
$sql .= " , ' " . $this -> db -> escape ( $this -> note_public ) . " ' " ;
$sql .= " , ' " . $this -> db -> escape ( $this -> modelpdf ) . " ' " ;
$sql .= " , " . ( $this -> fin_validite != '' ? " ' " . $this -> db -> idate ( $this -> fin_validite ) . " ' " : " NULL " );
$sql .= " , " . ( $this -> cond_reglement_id > 0 ? $this -> cond_reglement_id : 'NULL' );
$sql .= " , " . ( $this -> mode_reglement_id > 0 ? $this -> mode_reglement_id : 'NULL' );
$sql .= " , " . ( $this -> fk_account > 0 ? $this -> fk_account : 'NULL' );
$sql .= " , ' " . $this -> db -> escape ( $this -> ref_client ) . " ' " ;
$sql .= " , " . ( $this -> date_livraison != '' ? " ' " . $this -> db -> idate ( $this -> date_livraison ) . " ' " : " NULL " );
$sql .= " , " . ( $this -> shipping_method_id > 0 ? $this -> shipping_method_id : 'NULL' );
$sql .= " , " . $this -> availability_id ;
$sql .= " , " . $this -> demand_reason_id ;
$sql .= " , " . ( $this -> fk_project ? $this -> fk_project : " null " );
$sql .= " , " . ( int ) $this -> fk_incoterms ;
$sql .= " , ' " . $this -> db -> escape ( $this -> location_incoterms ) . " ' " ;
$sql .= " , " . $conf -> entity ;
2016-01-18 19:45:27 +01:00
$sql .= " , " . ( int ) $this -> fk_multicurrency ;
$sql .= " , ' " . $this -> db -> escape ( $this -> multicurrency_code ) . " ' " ;
$sql .= " , " . ( double ) $this -> multicurrency_tx ;
2017-10-07 13:09:31 +02:00
$sql .= " ) " ;
2017-09-15 15:41:07 +02:00
2017-10-07 13:09:31 +02:00
dol_syslog ( get_class ( $this ) . " ::create " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> id = $this -> db -> last_insert_id ( MAIN_DB_PREFIX . " propal " );
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
if ( $this -> id )
{
$this -> ref = '(PROV' . $this -> id . ')' ;
$sql = 'UPDATE ' . MAIN_DB_PREFIX . " propal SET ref=' " . $this -> db -> escape ( $this -> ref ) . " ' WHERE rowid= " . $this -> id ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
dol_syslog ( get_class ( $this ) . " ::create " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql ) $error ++ ;
2012-03-18 19:23:01 +01:00
2017-10-19 19:06:48 +02:00
if ( ! empty ( $this -> linkedObjectsIds ) && empty ( $this -> linked_objects )) // To use new linkedObjectsIds instead of old linked_objects
{
$this -> linked_objects = $this -> linkedObjectsIds ; // TODO Replace linked_objects with linkedObjectsIds
}
// Add object linked
if ( ! $error && $this -> id && is_array ( $this -> linked_objects ) && ! empty ( $this -> linked_objects ))
{
foreach ( $this -> linked_objects as $origin => $tmp_origin_id )
{
if ( is_array ( $tmp_origin_id )) // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
{
foreach ( $tmp_origin_id as $origin_id )
{
$ret = $this -> add_object_linked ( $origin , $origin_id );
if ( ! $ret )
{
$this -> error = $this -> db -> lasterror ();
$error ++ ;
}
}
}
else // Old behaviour, if linked_object has only one link per type, so is something like array('contract'=>id1))
{
$origin_id = $tmp_origin_id ;
$ret = $this -> add_object_linked ( $origin , $origin_id );
if ( ! $ret )
{
$this -> error = $this -> db -> lasterror ();
$error ++ ;
}
}
}
}
// Add linked object (deprecated, use ->linkedObjectsIds instead)
if ( ! $error && $this -> origin && $this -> origin_id )
{
2018-09-19 10:57:59 +02:00
dol_syslog ( 'Deprecated use of linked object, use ->linkedObjectsIds instead' , LOG_WARNING );
2017-10-19 19:06:48 +02:00
$ret = $this -> add_object_linked ();
if ( ! $ret ) dol_print_error ( $this -> db );
}
2012-03-18 19:23:01 +01:00
/*
* Insertion du detail des produits dans la base
2017-11-18 16:21:54 +01:00
* Insert products detail in database
2017-10-19 19:06:48 +02:00
*/
2012-03-18 19:23:01 +01:00
if ( ! $error )
{
$fk_parent_line = 0 ;
$num = count ( $this -> lines );
2017-10-07 13:09:31 +02:00
for ( $i = 0 ; $i < $num ; $i ++ )
{
2017-11-19 11:46:34 +01:00
if ( ! is_object ( $this -> lines [ $i ])) // If this->lines is not array of objects, coming from REST API
{ // Convert into object this->lines[$i].
2017-11-23 15:06:16 +01:00
$line = ( object ) $this -> lines [ $i ];
2017-11-19 11:46:34 +01:00
}
else
{
$line = $this -> lines [ $i ];
}
2017-10-07 13:09:31 +02:00
// Reset fk_parent_line for line that are not child lines or special product
2017-11-18 16:21:54 +01:00
if (( $line -> product_type != 9 && empty ( $line -> fk_parent_line )) || $line -> product_type == 9 ) {
2017-10-07 13:09:31 +02:00
$fk_parent_line = 0 ;
}
2017-11-13 13:07:31 +01:00
// Complete vat rate with code
2017-11-18 16:21:54 +01:00
$vatrate = $line -> tva_tx ;
if ( $line -> vat_src_code && ! preg_match ( '/\(.*\)/' , $vatrate )) $vatrate .= ' (' . $line -> vat_src_code . ')' ;
2017-11-13 13:07:31 +01:00
2012-08-22 17:42:40 +02:00
$result = $this -> addline (
2017-11-18 16:21:54 +01:00
$line -> desc ,
$line -> subprice ,
$line -> qty ,
2017-11-13 13:07:31 +01:00
$vatrate ,
2017-11-18 16:21:54 +01:00
$line -> localtax1_tx ,
$line -> localtax2_tx ,
$line -> fk_product ,
$line -> remise_percent ,
2012-08-26 23:15:26 +02:00
'HT' ,
0 ,
2017-11-18 16:21:54 +01:00
$line -> info_bits ,
$line -> product_type ,
$line -> rang ,
$line -> special_code ,
2012-08-26 23:15:26 +02:00
$fk_parent_line ,
2017-11-18 16:21:54 +01:00
$line -> fk_fournprice ,
$line -> pa_ht ,
$line -> label ,
$line -> date_start ,
$line -> date_end ,
$line -> array_options ,
$line -> fk_unit ,
2017-10-07 13:09:31 +02:00
$this -> element ,
2017-11-18 16:21:54 +01:00
$line -> id
2012-08-22 17:42:40 +02:00
);
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
if ( $result < 0 )
{
$error ++ ;
$this -> error = $this -> db -> error ;
dol_print_error ( $this -> db );
break ;
}
// Defined the new fk_parent_line
2017-11-18 16:21:54 +01:00
if ( $result > 0 && $line -> product_type == 9 ) {
2017-10-07 13:09:31 +02:00
$fk_parent_line = $result ;
}
}
}
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// Set delivery address
if ( ! $error && $this -> fk_delivery_address )
{
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal " ;
$sql .= " SET fk_delivery_address = " . $this -> fk_delivery_address ;
$sql .= " WHERE ref = ' " . $this -> db -> escape ( $this -> ref ) . " ' " ;
$sql .= " AND entity = " . $conf -> entity ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$result = $this -> db -> query ( $sql );
}
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
if ( ! $error )
{
// Mise a jour infos denormalisees
$resql = $this -> update_price ( 1 );
if ( $resql )
2014-09-15 11:48:50 +02:00
{
2017-10-07 13:09:31 +02:00
$action = 'update' ;
2018-04-10 12:03:01 +02:00
// Actions on extra fields
if ( ! $error )
2017-10-07 13:09:31 +02:00
{
if ( empty ( $conf -> global -> MAIN_EXTRAFIELDS_DISABLED )) // For avoid conflicts if trigger used
{
$result = $this -> insertExtraFields ();
if ( $result < 0 )
{
$error ++ ;
}
}
}
2018-04-10 12:03:01 +02:00
if ( ! $error && ! $notrigger )
2017-10-07 13:09:31 +02:00
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_CREATE' , $user );
if ( $result < 0 ) { $error ++ ; }
// End call triggers
}
}
else
{
$this -> error = $this -> db -> lasterror ();
$error ++ ;
}
}
}
else
{
$this -> error = $this -> db -> lasterror ();
$error ++ ;
}
if ( ! $error )
{
$this -> db -> commit ();
dol_syslog ( get_class ( $this ) . " ::create done id= " . $this -> id );
return $this -> id ;
}
else
{
$this -> db -> rollback ();
return - 2 ;
}
}
else
{
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Insert into DB a proposal object completely defined by its data members ( ex , results from copy ) .
*
* @ param User $user User that create
* @ return int Id of the new object if ok , < 0 if ko
* @ see create
*/
function create_from ( $user )
{
// i love this function because $this->products is not used in create function...
$this -> products = $this -> lines ;
return $this -> create ( $user );
}
/**
* Load an object from its id and create a new one in database
*
* @ param int $socid Id of thirdparty
* @ return int New id of clone
*/
function createFromClone ( $socid = 0 )
{
global $user , $conf , $hookmanager ;
2015-08-13 03:58:32 +02:00
2015-10-13 09:37:33 +02:00
dol_include_once ( '/projet/class/project.class.php' );
2015-08-13 03:58:32 +02:00
2017-10-07 13:09:31 +02:00
$this -> context [ 'createfromclone' ] = 'createfromclone' ;
2015-02-26 13:03:17 +01:00
2017-10-07 13:09:31 +02:00
$error = 0 ;
$now = dol_now ();
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$this -> db -> begin ();
2012-03-18 19:23:01 +01:00
2014-09-24 11:47:34 +02:00
// get extrafields so they will be clone
foreach ( $this -> lines as $line )
2018-02-21 14:48:25 +01:00
$line -> fetch_optionals ();
2014-09-24 11:47:34 +02:00
2017-10-07 13:09:31 +02:00
// Load dest object
$clonedObj = clone $this ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$objsoc = new Societe ( $this -> db );
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// Change socid if needed
if ( ! empty ( $socid ) && $socid != $clonedObj -> socid )
{
if ( $objsoc -> fetch ( $socid ) > 0 )
{
$clonedObj -> socid = $objsoc -> id ;
$clonedObj -> cond_reglement_id = ( ! empty ( $objsoc -> cond_reglement_id ) ? $objsoc -> cond_reglement_id : 0 );
$clonedObj -> mode_reglement_id = ( ! empty ( $objsoc -> mode_reglement_id ) ? $objsoc -> mode_reglement_id : 0 );
$clonedObj -> fk_delivery_address = '' ;
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
/* if ( ! empty ( $conf -> projet -> enabled ))
2015-11-05 03:12:57 +01:00
{
$project = new Project ( $db );
if ( $this -> fk_project > 0 && $project -> fetch ( $this -> fk_project )) {
if ( $project -> socid <= 0 ) $clonedObj -> fk_project = $this -> fk_project ;
else $clonedObj -> fk_project = '' ;
} else {
$clonedObj -> fk_project = '' ;
}
} */
2017-10-07 13:09:31 +02:00
$clonedObj -> fk_project = '' ; // A cloned proposal is set by default to no project.
}
2014-01-16 11:43:59 +01:00
2017-10-07 13:09:31 +02:00
// reset ref_client
$clonedObj -> ref_client = '' ;
// TODO Change product price if multi-prices
}
else
{
$objsoc -> fetch ( $clonedObj -> socid );
}
$clonedObj -> id = 0 ;
$clonedObj -> ref = '' ;
$clonedObj -> statut = self :: STATUS_DRAFT ;
// Clear fields
$clonedObj -> user_author = $user -> id ;
$clonedObj -> user_valid = '' ;
$clonedObj -> date = $now ;
$clonedObj -> datep = $now ; // deprecated
$clonedObj -> fin_validite = $clonedObj -> date + ( $clonedObj -> duree_validite * 24 * 3600 );
if ( empty ( $conf -> global -> MAIN_KEEP_REF_CUSTOMER_ON_CLONING )) $clonedObj -> ref_client = '' ;
// Create clone
$result = $clonedObj -> create ( $user );
if ( $result < 0 ) $error ++ ;
else
{
// copy internal contacts
if ( $clonedObj -> copy_linked_contact ( $this , 'internal' ) < 0 )
$error ++ ;
// copy external contacts if same company
elseif ( $this -> socid == $clonedObj -> socid )
{
if ( $clonedObj -> copy_linked_contact ( $this , 'external' ) < 0 )
$error ++ ;
}
}
if ( ! $error )
{
// Hook of thirdparty module
if ( is_object ( $hookmanager ))
{
$parameters = array ( 'objFrom' => $this , 'clonedObj' => $clonedObj );
$action = '' ;
$reshook = $hookmanager -> executeHooks ( 'createFrom' , $parameters , $clonedObj , $action ); // Note that $action and $object may have been modified by some hooks
if ( $reshook < 0 ) $error ++ ;
}
}
unset ( $this -> context [ 'createfromclone' ]);
// End
if ( ! $error )
{
$this -> db -> commit ();
return $clonedObj -> id ;
}
else
{
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Load a proposal from database and its ligne array
*
* @ param int $rowid id of object to load
* @ param string $ref Ref of proposal
* @ return int > 0 if OK , < 0 if KO
*/
function fetch ( $rowid , $ref = '' )
{
2018-02-24 16:21:16 +01:00
$sql = " SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc " ;
2017-10-07 13:09:31 +02:00
$sql .= " , p.total, p.tva, p.localtax1, p.localtax2, p.total_ht " ;
$sql .= " , p.datec " ;
$sql .= " , p.date_valid as datev " ;
$sql .= " , p.datep as dp " ;
$sql .= " , p.fin_validite as dfv " ;
$sql .= " , p.date_livraison as date_livraison " ;
2017-10-19 11:14:31 +02:00
$sql .= " , p.model_pdf, p.last_main_doc, p.ref_client, p.extraparams " ;
2017-10-07 13:09:31 +02:00
$sql .= " , p.note_private, p.note_public " ;
$sql .= " , p.fk_projet, p.fk_statut " ;
$sql .= " , p.fk_user_author, p.fk_user_valid, p.fk_user_cloture " ;
$sql .= " , p.fk_delivery_address " ;
$sql .= " , p.fk_availability " ;
$sql .= " , p.fk_input_reason " ;
$sql .= " , p.fk_cond_reglement " ;
$sql .= " , p.fk_mode_reglement " ;
$sql .= ', p.fk_account' ;
$sql .= " , p.fk_shipping_method " ;
$sql .= " , p.fk_incoterms, p.location_incoterms " ;
$sql .= " , p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc " ;
2018-08-27 10:19:07 +02:00
$sql .= " , p.tms as date_modification " ;
2017-10-07 13:09:31 +02:00
$sql .= " , i.libelle as libelle_incoterms " ;
$sql .= " , c.label as statut_label " ;
$sql .= " , ca.code as availability_code, ca.label as availability " ;
$sql .= " , dr.code as demand_reason_code, dr.label as demand_reason " ;
$sql .= " , cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc " ;
$sql .= " , cp.code as mode_reglement_code, cp.libelle as mode_reglement " ;
2018-07-02 15:26:01 +02:00
$sql .= " FROM " . MAIN_DB_PREFIX . " propal as p " ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_propalst as c ON p.fk_statut = c.id' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN (' . getEntity ( 'c_paiement' ) . ')' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_payment_term as cr ON p.fk_cond_reglement = cr.rowid AND cr.entity IN (' . getEntity ( 'c_payment_term' ) . ')' ;
2017-10-07 13:09:31 +02:00
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_availability as ca ON p.fk_availability = ca.rowid' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_input_reason as dr ON p.fk_input_reason = dr.rowid' ;
2015-02-10 11:46:35 +01:00
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_incoterms as i ON p.fk_incoterms = i.rowid' ;
2018-07-01 18:49:37 +02:00
if ( $ref ) {
2018-08-17 13:44:07 +02:00
$sql .= " WHERE p.entity IN ( " . getEntity ( 'propal' ) . " ) " ; // Dont't use entity if you use rowid
2018-08-16 01:01:38 +02:00
$sql .= " AND p.ref=' " . $this -> db -> escape ( $ref ) . " ' " ;
2018-07-01 18:49:37 +02:00
}
2018-08-17 13:44:07 +02:00
else $sql .= " WHERE p.rowid= " . $rowid ;
2017-10-07 13:09:31 +02:00
dol_syslog ( get_class ( $this ) . " ::fetch " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
if ( $this -> db -> num_rows ( $resql ))
{
$obj = $this -> db -> fetch_object ( $resql );
$this -> id = $obj -> rowid ;
2018-02-24 16:21:16 +01:00
$this -> entity = $obj -> entity ;
2017-10-07 13:09:31 +02:00
$this -> ref = $obj -> ref ;
$this -> ref_client = $obj -> ref_client ;
$this -> remise = $obj -> remise ;
$this -> remise_percent = $obj -> remise_percent ;
$this -> remise_absolue = $obj -> remise_absolue ;
$this -> total = $obj -> total ; // TODO deprecated
$this -> total_ht = $obj -> total_ht ;
$this -> total_tva = $obj -> tva ;
$this -> total_localtax1 = $obj -> localtax1 ;
$this -> total_localtax2 = $obj -> localtax2 ;
$this -> total_ttc = $obj -> total ;
$this -> socid = $obj -> fk_soc ;
$this -> fk_project = $obj -> fk_projet ;
$this -> modelpdf = $obj -> model_pdf ;
2017-10-19 11:14:31 +02:00
$this -> last_main_doc = $obj -> last_main_doc ;
2017-10-07 13:09:31 +02:00
$this -> note = $obj -> note_private ; // TODO deprecated
$this -> note_private = $obj -> note_private ;
$this -> note_public = $obj -> note_public ;
$this -> statut = ( int ) $obj -> fk_statut ;
$this -> statut_libelle = $obj -> statut_label ;
$this -> datec = $this -> db -> jdate ( $obj -> datec ); // TODO deprecated
$this -> datev = $this -> db -> jdate ( $obj -> datev ); // TODO deprecated
$this -> date_creation = $this -> db -> jdate ( $obj -> datec ); //Creation date
$this -> date_validation = $this -> db -> jdate ( $obj -> datev ); //Validation date
2018-08-27 10:19:07 +02:00
$this -> date_modification = $this -> db -> jdate ( $obj -> date_modification ); // tms
2017-10-07 13:09:31 +02:00
$this -> date = $this -> db -> jdate ( $obj -> dp ); // Proposal date
$this -> datep = $this -> db -> jdate ( $obj -> dp ); // deprecated
$this -> fin_validite = $this -> db -> jdate ( $obj -> dfv );
$this -> date_livraison = $this -> db -> jdate ( $obj -> date_livraison );
$this -> shipping_method_id = ( $obj -> fk_shipping_method > 0 ) ? $obj -> fk_shipping_method : null ;
$this -> availability_id = $obj -> fk_availability ;
$this -> availability_code = $obj -> availability_code ;
$this -> availability = $obj -> availability ;
$this -> demand_reason_id = $obj -> fk_input_reason ;
$this -> demand_reason_code = $obj -> demand_reason_code ;
$this -> demand_reason = $obj -> demand_reason ;
$this -> fk_address = $obj -> fk_delivery_address ;
$this -> mode_reglement_id = $obj -> fk_mode_reglement ;
$this -> mode_reglement_code = $obj -> mode_reglement_code ;
$this -> mode_reglement = $obj -> mode_reglement ;
$this -> fk_account = ( $obj -> fk_account > 0 ) ? $obj -> fk_account : null ;
$this -> cond_reglement_id = $obj -> fk_cond_reglement ;
$this -> cond_reglement_code = $obj -> cond_reglement_code ;
$this -> cond_reglement = $obj -> cond_reglement ;
$this -> cond_reglement_doc = $obj -> cond_reglement_libelle_doc ;
$this -> extraparams = ( array ) json_decode ( $obj -> extraparams , true );
$this -> user_author_id = $obj -> fk_user_author ;
$this -> user_valid_id = $obj -> fk_user_valid ;
$this -> user_close_id = $obj -> fk_user_cloture ;
2012-03-18 19:23:01 +01:00
2015-02-10 11:46:35 +01:00
//Incoterms
$this -> fk_incoterms = $obj -> fk_incoterms ;
2015-04-12 04:01:28 +02:00
$this -> location_incoterms = $obj -> location_incoterms ;
2015-02-10 11:46:35 +01:00
$this -> libelle_incoterms = $obj -> libelle_incoterms ;
2015-04-12 04:01:28 +02:00
2016-01-18 19:45:27 +01:00
// Multicurrency
$this -> fk_multicurrency = $obj -> fk_multicurrency ;
$this -> multicurrency_code = $obj -> multicurrency_code ;
$this -> multicurrency_tx = $obj -> multicurrency_tx ;
$this -> multicurrency_total_ht = $obj -> multicurrency_total_ht ;
$this -> multicurrency_total_tva = $obj -> multicurrency_total_tva ;
$this -> multicurrency_total_ttc = $obj -> multicurrency_total_ttc ;
2017-10-07 13:09:31 +02:00
if ( $obj -> fk_statut == self :: STATUS_DRAFT )
{
$this -> brouillon = 1 ;
}
2012-03-18 19:23:01 +01:00
2018-02-20 19:38:18 +01:00
// Retreive all extrafield
2017-10-07 13:09:31 +02:00
// fetch optionals attributes and labels
2018-02-20 19:38:18 +01:00
$this -> fetch_optionals ();
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$this -> db -> free ( $resql );
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$this -> lines = array ();
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
/*
2017-04-28 14:33:06 +02:00
* Lines
2012-08-01 17:36:15 +02:00
*/
2017-10-07 13:09:31 +02:00
$result = $this -> fetch_lines ();
if ( $result < 0 )
{
return - 3 ;
}
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
return 1 ;
}
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$this -> error = " Record Not Found " ;
return 0 ;
}
else
{
$this -> error = $this -> db -> lasterror ();
return - 1 ;
}
}
2017-06-09 09:25:15 +02:00
2017-12-01 15:39:18 +01:00
/**
* Update database
*
* @ param User $user User that modify
* @ param int $notrigger 0 = launch triggers after , 1 = disable triggers
* @ return int < 0 if KO , > 0 if OK
*/
function update ( User $user , $notrigger = 0 )
{
2018-08-12 16:29:26 +02:00
global $conf ;
2017-12-01 15:39:18 +01:00
$error = 0 ;
// Clean parameters
if ( isset ( $this -> ref )) $this -> ref = trim ( $this -> ref );
if ( isset ( $this -> ref_client )) $this -> ref_client = trim ( $this -> ref_client );
if ( isset ( $this -> note ) || isset ( $this -> note_private )) $this -> note_private = ( isset ( $this -> note_private ) ? trim ( $this -> note_private ) : trim ( $this -> note ));
if ( isset ( $this -> note_public )) $this -> note_public = trim ( $this -> note_public );
if ( isset ( $this -> modelpdf )) $this -> modelpdf = trim ( $this -> modelpdf );
if ( isset ( $this -> import_key )) $this -> import_key = trim ( $this -> import_key );
// Check parameters
// Put here code to add control on parameters values
// Update request
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal SET " ;
$sql .= " ref= " . ( isset ( $this -> ref ) ? " ' " . $this -> db -> escape ( $this -> ref ) . " ' " : " null " ) . " , " ;
$sql .= " ref_client= " . ( isset ( $this -> ref_client ) ? " ' " . $this -> db -> escape ( $this -> ref_client ) . " ' " : " null " ) . " , " ;
$sql .= " ref_ext= " . ( isset ( $this -> ref_ext ) ? " ' " . $this -> db -> escape ( $this -> ref_ext ) . " ' " : " null " ) . " , " ;
$sql .= " fk_soc= " . ( isset ( $this -> socid ) ? $this -> socid : " null " ) . " , " ;
$sql .= " datep= " . ( strval ( $this -> datep ) != '' ? " ' " . $this -> db -> idate ( $this -> datep ) . " ' " : 'null' ) . " , " ;
$sql .= " date_valid= " . ( strval ( $this -> date_validation ) != '' ? " ' " . $this -> db -> idate ( $this -> date_validation ) . " ' " : 'null' ) . " , " ;
$sql .= " tva= " . ( isset ( $this -> total_tva ) ? $this -> total_tva : " null " ) . " , " ;
$sql .= " localtax1= " . ( isset ( $this -> total_localtax1 ) ? $this -> total_localtax1 : " null " ) . " , " ;
$sql .= " localtax2= " . ( isset ( $this -> total_localtax2 ) ? $this -> total_localtax2 : " null " ) . " , " ;
$sql .= " total_ht= " . ( isset ( $this -> total_ht ) ? $this -> total_ht : " null " ) . " , " ;
$sql .= " total= " . ( isset ( $this -> total_ttc ) ? $this -> total_ttc : " null " ) . " , " ;
$sql .= " fk_statut= " . ( isset ( $this -> statut ) ? $this -> statut : " null " ) . " , " ;
$sql .= " fk_user_author= " . ( isset ( $this -> user_author_id ) ? $this -> user_author_id : " null " ) . " , " ;
$sql .= " fk_user_valid= " . ( isset ( $this -> user_valid ) ? $this -> user_valid : " null " ) . " , " ;
$sql .= " fk_projet= " . ( isset ( $this -> fk_project ) ? $this -> fk_project : " null " ) . " , " ;
$sql .= " fk_cond_reglement= " . ( isset ( $this -> cond_reglement_id ) ? $this -> cond_reglement_id : " null " ) . " , " ;
$sql .= " fk_mode_reglement= " . ( isset ( $this -> mode_reglement_id ) ? $this -> mode_reglement_id : " null " ) . " , " ;
$sql .= " note_private= " . ( isset ( $this -> note_private ) ? " ' " . $this -> db -> escape ( $this -> note_private ) . " ' " : " null " ) . " , " ;
$sql .= " note_public= " . ( isset ( $this -> note_public ) ? " ' " . $this -> db -> escape ( $this -> note_public ) . " ' " : " null " ) . " , " ;
$sql .= " model_pdf= " . ( isset ( $this -> modelpdf ) ? " ' " . $this -> db -> escape ( $this -> modelpdf ) . " ' " : " null " ) . " , " ;
$sql .= " import_key= " . ( isset ( $this -> import_key ) ? " ' " . $this -> db -> escape ( $this -> import_key ) . " ' " : " null " ) . " " ;
$sql .= " WHERE rowid= " . $this -> id ;
$this -> db -> begin ();
dol_syslog ( get_class ( $this ) . " ::update " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql ) {
$error ++ ; $this -> errors [] = " Error " . $this -> db -> lasterror ();
}
2018-08-12 16:29:26 +02:00
if ( ! $error && empty ( $conf -> global -> MAIN_EXTRAFIELDS_DISABLED ) && is_array ( $this -> array_options ) && count ( $this -> array_options ) > 0 )
2017-12-01 15:39:18 +01:00
{
2018-08-12 16:29:26 +02:00
$result = $this -> insertExtraFields ();
if ( $result < 0 )
2017-12-01 15:39:18 +01:00
{
2018-08-12 16:29:26 +02:00
$error ++ ;
2017-12-01 15:39:18 +01:00
}
}
2018-08-12 16:29:26 +02:00
if ( ! $error && ! $notrigger )
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
2017-12-01 15:39:18 +01:00
// Commit or rollback
if ( $error )
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( get_class ( $this ) . " ::update " . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
else
{
$this -> db -> commit ();
return 1 ;
}
}
2017-04-28 14:33:06 +02:00
/**
* Load array lines
2017-06-09 09:25:15 +02:00
*
2017-04-28 14:33:06 +02:00
* @ param int $only_product Return only physical products
* @ return int < 0 if KO , > 0 if OK
*/
function fetch_lines ( $only_product = 0 )
{
$this -> lines = array ();
2017-06-09 09:25:15 +02:00
2017-09-24 22:55:27 +02:00
$sql = 'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,' ;
2017-04-28 14:33:06 +02:00
$sql .= ' d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,' ;
$sql .= ' d.fk_unit,' ;
$sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,' ;
2017-12-26 16:12:28 +01:00
$sql .= ' p.weight, p.weight_units, p.volume, p.volume_units,' ;
2017-04-28 14:33:06 +02:00
$sql .= ' d.date_start, d.date_end' ;
$sql .= ' ,d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'propaldet as d' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON (d.fk_product = p.rowid)' ;
$sql .= ' WHERE d.fk_propal = ' . $this -> id ;
if ( $only_product ) $sql .= ' AND p.fk_product_type = 0' ;
$sql .= ' ORDER by d.rang' ;
dol_syslog ( get_class ( $this ) . " ::fetch_lines " , LOG_DEBUG );
$result = $this -> db -> query ( $sql );
if ( $result )
{
require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php' ;
$num = $this -> db -> num_rows ( $result );
2017-06-09 09:25:15 +02:00
2017-04-28 14:33:06 +02:00
$i = 0 ;
while ( $i < $num )
{
$objp = $this -> db -> fetch_object ( $result );
$line = new PropaleLigne ( $this -> db );
$line -> rowid = $objp -> rowid ; //Deprecated
$line -> id = $objp -> rowid ;
$line -> fk_propal = $objp -> fk_propal ;
$line -> fk_parent_line = $objp -> fk_parent_line ;
$line -> product_type = $objp -> product_type ;
$line -> label = $objp -> custom_label ;
$line -> desc = $objp -> description ; // Description ligne
$line -> qty = $objp -> qty ;
2017-05-05 14:49:25 +02:00
$line -> vat_src_code = $objp -> vat_src_code ;
2017-04-28 14:33:06 +02:00
$line -> tva_tx = $objp -> tva_tx ;
$line -> localtax1_tx = $objp -> localtax1_tx ;
$line -> localtax2_tx = $objp -> localtax2_tx ;
2017-09-24 22:55:27 +02:00
$line -> localtax1_type = $objp -> localtax1_type ;
$line -> localtax2_type = $objp -> localtax2_type ;
2017-04-28 14:33:06 +02:00
$line -> subprice = $objp -> subprice ;
$line -> fk_remise_except = $objp -> fk_remise_except ;
$line -> remise_percent = $objp -> remise_percent ;
$line -> price = $objp -> price ; // TODO deprecated
$line -> info_bits = $objp -> info_bits ;
$line -> total_ht = $objp -> total_ht ;
$line -> total_tva = $objp -> total_tva ;
$line -> total_localtax1 = $objp -> total_localtax1 ;
$line -> total_localtax2 = $objp -> total_localtax2 ;
$line -> total_ttc = $objp -> total_ttc ;
$line -> fk_fournprice = $objp -> fk_fournprice ;
$marginInfos = getMarginInfos ( $objp -> subprice , $objp -> remise_percent , $objp -> tva_tx , $objp -> localtax1_tx , $objp -> localtax2_tx , $line -> fk_fournprice , $objp -> pa_ht );
$line -> pa_ht = $marginInfos [ 0 ];
$line -> marge_tx = $marginInfos [ 1 ];
$line -> marque_tx = $marginInfos [ 2 ];
$line -> special_code = $objp -> special_code ;
$line -> rang = $objp -> rang ;
$line -> fk_product = $objp -> fk_product ;
$line -> ref = $objp -> product_ref ; // TODO deprecated
$line -> product_ref = $objp -> product_ref ;
$line -> libelle = $objp -> product_label ; // TODO deprecated
$line -> product_label = $objp -> product_label ;
$line -> product_desc = $objp -> product_desc ; // Description produit
$line -> fk_product_type = $objp -> fk_product_type ;
$line -> fk_unit = $objp -> fk_unit ;
2017-12-26 16:12:28 +01:00
$line -> weight = $objp -> weight ;
$line -> weight_units = $objp -> weight_units ;
$line -> volume = $objp -> volume ;
$line -> volume_units = $objp -> volume_units ;
2017-04-28 14:33:06 +02:00
$line -> date_start = $this -> db -> jdate ( $objp -> date_start );
$line -> date_end = $this -> db -> jdate ( $objp -> date_end );
// Multicurrency
$line -> fk_multicurrency = $objp -> fk_multicurrency ;
$line -> multicurrency_code = $objp -> multicurrency_code ;
$line -> multicurrency_subprice = $objp -> multicurrency_subprice ;
$line -> multicurrency_total_ht = $objp -> multicurrency_total_ht ;
$line -> multicurrency_total_tva = $objp -> multicurrency_total_tva ;
$line -> multicurrency_total_ttc = $objp -> multicurrency_total_ttc ;
$line -> fetch_optionals ();
$this -> lines [ $i ] = $line ;
//dol_syslog("1 ".$line->fk_product);
//print "xx $i ".$this->lines[$i]->fk_product;
$i ++ ;
}
2017-06-09 09:25:15 +02:00
2017-10-07 13:09:31 +02:00
$this -> db -> free ( $result );
2018-04-14 17:04:38 +02:00
return $num ;
2017-10-07 13:09:31 +02:00
}
else
{
$this -> error = $this -> db -> lasterror ();
return - 3 ;
}
}
/**
* Set status to validated
*
* @ param User $user Object user that validate
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , 0 = Nothing done , >= 0 if OK
*/
function valid ( $user , $notrigger = 0 )
{
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
global $conf ;
$error = 0 ;
// Protection
if ( $this -> statut == self :: STATUS_VALIDATED )
{
dol_syslog ( get_class ( $this ) . " ::valid action abandonned: already validated " , LOG_WARNING );
return 0 ;
}
if ( ! (( empty ( $conf -> global -> MAIN_USE_ADVANCED_PERMS ) && ! empty ( $user -> rights -> propal -> creer ))
|| ( ! empty ( $conf -> global -> MAIN_USE_ADVANCED_PERMS ) && ! empty ( $user -> rights -> propal -> propal_advance -> validate ))))
{
$this -> error = 'ErrorPermissionDenied' ;
dol_syslog ( get_class ( $this ) . " ::valid " . $this -> error , LOG_ERR );
return - 1 ;
}
$now = dol_now ();
$this -> db -> begin ();
// Numbering module definition
$soc = new Societe ( $this -> db );
$soc -> fetch ( $this -> socid );
// Define new ref
if ( ! $error && ( preg_match ( '/^[\(]?PROV/i' , $this -> ref ) || empty ( $this -> ref ))) // empty should not happened, but when it occurs, the test save life
{
$num = $this -> getNextNumRef ( $soc );
}
else
{
$num = $this -> ref ;
}
$this -> newref = $num ;
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal " ;
$sql .= " SET ref = ' " . $num . " ', " ;
$sql .= " fk_statut = " . self :: STATUS_VALIDATED . " , date_valid=' " . $this -> db -> idate ( $now ) . " ', fk_user_valid= " . $user -> id ;
$sql .= " WHERE rowid = " . $this -> id . " AND fk_statut = " . self :: STATUS_DRAFT ;
dol_syslog ( get_class ( $this ) . " ::valid " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
dol_print_error ( $this -> db );
$error ++ ;
}
// Trigger calls
if ( ! $error && ! $notrigger )
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_VALIDATE' , $user );
if ( $result < 0 ) { $error ++ ; }
// End call triggers
}
if ( ! $error )
{
$this -> oldref = $this -> ref ;
// Rename directory if dir was a temporary ref
if ( preg_match ( '/^[\(]?PROV/i' , $this -> ref ))
{
// Rename of propal directory ($this->ref = old ref, $num = new ref)
// to not lose the linked files
$oldref = dol_sanitizeFileName ( $this -> ref );
$newref = dol_sanitizeFileName ( $num );
2018-02-25 17:43:19 +01:00
$dirsource = $conf -> propal -> multidir_output [ $this -> entity ] . '/' . $oldref ;
$dirdest = $conf -> propal -> multidir_output [ $this -> entity ] . '/' . $newref ;
2017-10-07 13:09:31 +02:00
if ( file_exists ( $dirsource ))
{
dol_syslog ( get_class ( $this ) . " ::validate rename dir " . $dirsource . " into " . $dirdest );
if ( @ rename ( $dirsource , $dirdest ))
{
dol_syslog ( " Rename ok " );
// Rename docs starting with $oldref with $newref
2018-02-25 17:43:19 +01:00
$listoffiles = dol_dir_list ( $dirdest , 'files' , 1 , '^' . preg_quote ( $oldref , '/' ));
2017-10-07 13:09:31 +02:00
foreach ( $listoffiles as $fileentry )
{
$dirsource = $fileentry [ 'name' ];
$dirdest = preg_replace ( '/^' . preg_quote ( $oldref , '/' ) . '/' , $newref , $dirsource );
$dirsource = $fileentry [ 'path' ] . '/' . $dirsource ;
$dirdest = $fileentry [ 'path' ] . '/' . $dirdest ;
@ rename ( $dirsource , $dirdest );
}
}
}
}
$this -> ref = $num ;
$this -> brouillon = 0 ;
$this -> statut = self :: STATUS_VALIDATED ;
$this -> user_valid_id = $user -> id ;
$this -> datev = $now ;
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Define proposal date
*
* @ param User $user Object user that modify
* @ param int $date Date
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , > 0 if OK
*/
function set_date ( $user , $date , $notrigger = 0 )
{
if ( empty ( $date ))
{
$this -> error = 'ErrorBadParameter' ;
dol_syslog ( get_class ( $this ) . " ::set_date " . $this -> error , LOG_ERR );
return - 1 ;
}
if ( ! empty ( $user -> rights -> propal -> creer ))
{
$error = 0 ;
$this -> db -> begin ();
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal SET datep = ' " . $this -> db -> idate ( $date ) . " ' " ;
$sql .= " WHERE rowid = " . $this -> id . " AND fk_statut = " . self :: STATUS_DRAFT ;
dol_syslog ( __METHOD__ , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> date = $date ;
$this -> datep = $date ; // deprecated
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
}
/**
* Define end validity date
*
* @ param User $user Object user that modify
* @ param int $date_fin_validite End of validity date
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , > 0 if OK
*/
function set_echeance ( $user , $date_fin_validite , $notrigger = 0 )
{
if ( ! empty ( $user -> rights -> propal -> creer ))
{
$error = 0 ;
$this -> db -> begin ();
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal SET fin_validite = " . ( $date_fin_validite != '' ? " ' " . $this -> db -> idate ( $date_fin_validite ) . " ' " : 'null' );
$sql .= " WHERE rowid = " . $this -> id . " AND fk_statut = " . self :: STATUS_DRAFT ;
dol_syslog ( __METHOD__ , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> fin_validite = $date_fin_validite ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
}
/**
* Set delivery date
*
* @ param User $user Object user that modify
* @ param int $date_livraison Delivery date
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if ko , > 0 if ok
*/
function set_date_livraison ( $user , $date_livraison , $notrigger = 0 )
{
if ( ! empty ( $user -> rights -> propal -> creer ))
{
$error = 0 ;
$this -> db -> begin ();
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal " ;
$sql .= " SET date_livraison = " . ( $date_livraison != '' ? " ' " . $this -> db -> idate ( $date_livraison ) . " ' " : 'null' );
$sql .= " WHERE rowid = " . $this -> id ;
dol_syslog ( __METHOD__ , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> date_livraison = $date_livraison ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
}
/**
* Set delivery
*
* @ param User $user Object user that modify
* @ param int $id Availability id
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , > 0 if OK
*/
function set_availability ( $user , $id , $notrigger = 0 )
{
if ( ! empty ( $user -> rights -> propal -> creer ) && $this -> statut >= self :: STATUS_DRAFT )
{
$error = 0 ;
$this -> db -> begin ();
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal " ;
$sql .= " SET fk_availability = ' " . $id . " ' " ;
$sql .= " WHERE rowid = " . $this -> id ;
2017-12-06 23:21:58 +01:00
dol_syslog ( __METHOD__ . ' availability(' . $id . ')' , LOG_DEBUG );
2017-10-07 13:09:31 +02:00
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> fk_availability = $id ;
$this -> availability_id = $id ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
else
{
$error_str = 'Propal status do not meet requirement ' . $this -> statut ;
dol_syslog ( __METHOD__ . $error_str , LOG_ERR );
$this -> error = $error_str ;
$this -> errors [] = $this -> error ;
return - 2 ;
}
}
/**
* Set source of demand
*
* @ param User $user Object user that modify
* @ param int $id Input reason id
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , > 0 if OK
*/
function set_demand_reason ( $user , $id , $notrigger = 0 )
{
if ( ! empty ( $user -> rights -> propal -> creer ) && $this -> statut >= self :: STATUS_DRAFT )
{
$error = 0 ;
$this -> db -> begin ();
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal " ;
$sql .= " SET fk_input_reason = " . $id ;
$sql .= " WHERE rowid = " . $this -> id ;
dol_syslog ( __METHOD__ , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> fk_input_reason = $id ;
$this -> demand_reason_id = $id ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
else
{
$error_str = 'Propal status do not meet requirement ' . $this -> statut ;
dol_syslog ( __METHOD__ . $error_str , LOG_ERR );
$this -> error = $error_str ;
$this -> errors [] = $this -> error ;
return - 2 ;
}
}
/**
* Set customer reference number
*
* @ param User $user Object user that modify
* @ param string $ref_client Customer reference
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if ko , > 0 if ok
*/
function set_ref_client ( $user , $ref_client , $notrigger = 0 )
{
if ( ! empty ( $user -> rights -> propal -> creer ))
{
$error = 0 ;
$this -> db -> begin ();
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'propal SET ref_client = ' . ( empty ( $ref_client ) ? 'NULL' : '\'' . $this -> db -> escape ( $ref_client ) . '\'' );
$sql .= ' WHERE rowid = ' . $this -> id ;
dol_syslog ( __METHOD__ . ' $this->id=' . $this -> id . ', ref_client=' . $ref_client , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> ref_client = $ref_client ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
else
{
return - 1 ;
}
}
/**
* Set an overall discount on the proposal
*
* @ param User $user Object user that modify
* @ param double $remise Amount discount
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if ko , > 0 if ok
*/
function set_remise_percent ( $user , $remise , $notrigger = 0 )
{
$remise = trim ( $remise ) ? trim ( $remise ) : 0 ;
if ( ! empty ( $user -> rights -> propal -> creer ))
{
$remise = price2num ( $remise );
$error = 0 ;
$this -> db -> begin ();
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal SET remise_percent = " . $remise ;
$sql .= " WHERE rowid = " . $this -> id . " AND fk_statut = " . self :: STATUS_DRAFT ;
dol_syslog ( __METHOD__ , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> remise_percent = $remise ;
$this -> update_price ( 1 );
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
}
/**
* Set an absolute overall discount on the proposal
*
* @ param User $user Object user that modify
* @ param double $remise Amount discount
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if ko , > 0 if ok
*/
function set_remise_absolue ( $user , $remise , $notrigger = 0 )
{
$remise = trim ( $remise ) ? trim ( $remise ) : 0 ;
if ( ! empty ( $user -> rights -> propal -> creer ))
{
$remise = price2num ( $remise );
$error = 0 ;
$this -> db -> begin ();
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal " ;
$sql .= " SET remise_absolue = " . $remise ;
$sql .= " WHERE rowid = " . $this -> id . " AND fk_statut = " . self :: STATUS_DRAFT ;
dol_syslog ( __METHOD__ , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> remise_absolue = $remise ;
$this -> update_price ( 1 );
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
}
/**
* Reopen the commercial proposal
*
* @ param User $user Object user that close
* @ param int $statut Statut
* @ param string $note Comment
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , > 0 if OK
*/
function reopen ( $user , $statut , $note = '' , $notrigger = 0 )
{
$this -> statut = $statut ;
$error = 0 ;
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal " ;
$sql .= " SET fk_statut = " . $this -> statut . " , " ;
if ( ! empty ( $note )) $sql .= " note_private = ' " . $this -> db -> escape ( $note ) . " ', " ;
$sql .= " date_cloture=NULL, fk_user_cloture=NULL " ;
$sql .= " WHERE rowid = " . $this -> id ;
$this -> db -> begin ();
dol_syslog ( get_class ( $this ) . " ::reopen " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql ) {
$error ++ ; $this -> errors [] = " Error " . $this -> db -> lasterror ();
}
if ( ! $error )
{
if ( ! $notrigger )
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_REOPEN' , $user );
if ( $result < 0 ) { $error ++ ; }
// End call triggers
}
}
// Commit or rollback
if ( $error )
{
if ( ! empty ( $this -> errors ))
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( get_class ( $this ) . " ::update " . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
}
$this -> db -> rollback ();
return - 1 * $error ;
}
else
{
$this -> db -> commit ();
return 1 ;
}
}
/**
* Close the commercial proposal
*
* @ param User $user Object user that close
* @ param int $statut Statut
2017-10-18 11:23:16 +02:00
* @ param string $note Complete private note with this note
2017-10-18 11:10:08 +02:00
* @ param int $notrigger 1 = Does not execute triggers , 0 = Execute triggers
2017-10-07 13:09:31 +02:00
* @ return int < 0 if KO , > 0 if OK
*/
function cloture ( $user , $statut , $note , $notrigger = 0 )
{
global $langs , $conf ;
$error = 0 ;
$now = dol_now ();
$this -> db -> begin ();
2017-10-18 11:23:16 +02:00
$newprivatenote = dol_concatdesc ( $this -> note_private , $note );
2017-10-07 13:09:31 +02:00
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal " ;
2017-10-18 11:23:16 +02:00
$sql .= " SET fk_statut = " . $statut . " , note_private = ' " . $this -> db -> escape ( $newprivatenote ) . " ', date_cloture=' " . $this -> db -> idate ( $now ) . " ', fk_user_cloture= " . $user -> id ;
2017-10-07 13:09:31 +02:00
$sql .= " WHERE rowid = " . $this -> id ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$modelpdf = $conf -> global -> PROPALE_ADDON_PDF_ODT_CLOSED ? $conf -> global -> PROPALE_ADDON_PDF_ODT_CLOSED : $this -> modelpdf ;
$trigger_name = 'PROPAL_CLOSE_REFUSED' ;
if ( $statut == self :: STATUS_SIGNED )
{
$trigger_name = 'PROPAL_CLOSE_SIGNED' ;
$modelpdf = $conf -> global -> PROPALE_ADDON_PDF_ODT_TOBILL ? $conf -> global -> PROPALE_ADDON_PDF_ODT_TOBILL : $this -> modelpdf ;
// The connected company is classified as a client
$soc = new Societe ( $this -> db );
$soc -> id = $this -> socid ;
$result = $soc -> set_as_client ();
if ( $result < 0 )
{
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return - 2 ;
}
}
2017-10-18 11:10:08 +02:00
if ( $statut == self :: STATUS_BILLED ) // Why this ?
2017-10-07 13:09:31 +02:00
{
$trigger_name = 'PROPAL_CLASSIFY_BILLED' ;
}
if ( empty ( $conf -> global -> MAIN_DISABLE_PDF_AUTOUPDATE ))
{
2018-10-08 18:15:46 +02:00
// Define output language
$outputlangs = $langs ;
if ( ! empty ( $conf -> global -> MAIN_MULTILANGS ))
{
$outputlangs = new Translate ( " " , $conf );
$newlang = ( GETPOST ( 'lang_id' , 'aZ09' ) ? GETPOST ( 'lang_id' , 'aZ09' ) : $this -> thirdparty -> default_lang );
$outputlangs -> setDefaultLang ( $newlang );
}
//$ret=$object->fetch($id); // Reload to get new records
$this -> generateDocument ( $modelpdf , $outputlangs );
2017-10-07 13:09:31 +02:00
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> statut = $statut ;
$this -> date_cloture = $now ;
2018-10-08 18:15:46 +02:00
$this -> note_private = $newprivatenote ;
2017-10-07 13:09:31 +02:00
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( $trigger_name , $user );
if ( $result < 0 ) { $error ++ ; }
// End call triggers
}
2018-10-08 18:15:46 +02:00
if ( ! $error )
2017-10-07 13:09:31 +02:00
{
$this -> db -> commit ();
return 1 ;
}
else
{
2018-10-08 18:15:46 +02:00
$this -> statut = $this -> oldcopy -> statut ;
$this -> date_cloture = $this -> oldcopy -> date_cloture ;
$this -> note_private = $this -> oldcopy -> note_private ;
2017-10-07 13:09:31 +02:00
$this -> db -> rollback ();
return - 1 ;
}
}
else
{
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Class invoiced the Propal
*
* @ param User $user Object user
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 si ko , > 0 si ok
*/
function classifyBilled ( User $user , $notrigger = 0 )
{
$error = 0 ;
$this -> db -> begin ();
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'propal SET fk_statut = ' . self :: STATUS_BILLED ;
$sql .= ' WHERE rowid = ' . $this -> id . ' AND fk_statut > ' . self :: STATUS_DRAFT ;
dol_syslog ( __METHOD__ , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> statut = self :: STATUS_BILLED ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
/**
* Set draft status
*
* @ param User $user Object user that modify
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , > 0 if OK
*/
function set_draft ( $user , $notrigger = 0 )
{
$error = 0 ;
$this -> db -> begin ();
$sql = " UPDATE " . MAIN_DB_PREFIX . " propal SET fk_statut = " . self :: STATUS_DRAFT ;
$sql .= " WHERE rowid = " . $this -> id ;
dol_syslog ( __METHOD__ , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> statut = self :: STATUS_DRAFT ;
$this -> brouillon = 1 ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
/**
* Return list of proposal ( eventually filtered on user ) into an array
*
* @ param int $shortlist 0 = Return array [ id ] = ref , 1 = Return array []( id => id , ref => ref , name => name )
* @ param int $draft 0 = not draft , 1 = draft
* @ param int $notcurrentuser 0 = all user , 1 = not current user
* @ param int $socid Id third pary
* @ param int $limit For pagination
* @ param int $offset For pagination
* @ param string $sortfield Sort criteria
* @ param string $sortorder Sort order
* @ return int - 1 if KO , array with result if OK
*/
function liste_array ( $shortlist = 0 , $draft = 0 , $notcurrentuser = 0 , $socid = 0 , $limit = 0 , $offset = 0 , $sortfield = 'p.datep' , $sortorder = 'DESC' )
{
global $user ;
$ga = array ();
$sql = " SELECT s.rowid, s.nom as name, s.client, " ;
$sql .= " p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, " ;
$sql .= " p.datep as dp, p.fin_validite as datelimite " ;
if ( ! $user -> rights -> societe -> client -> voir && ! $socid ) $sql .= " , sc.fk_soc, sc.fk_user " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " societe as s, " . MAIN_DB_PREFIX . " propal as p, " . MAIN_DB_PREFIX . " c_propalst as c " ;
if ( ! $user -> rights -> societe -> client -> voir && ! $socid ) $sql .= " , " . MAIN_DB_PREFIX . " societe_commerciaux as sc " ;
$sql .= " WHERE p.entity IN ( " . getEntity ( 'propal' ) . " ) " ;
$sql .= " AND p.fk_soc = s.rowid " ;
$sql .= " AND p.fk_statut = c.id " ;
if ( ! $user -> rights -> societe -> client -> voir && ! $socid ) //restriction
{
$sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " . $user -> id ;
}
if ( $socid ) $sql .= " AND s.rowid = " . $socid ;
if ( $draft ) $sql .= " AND p.fk_statut = " . self :: STATUS_DRAFT ;
if ( $notcurrentuser > 0 ) $sql .= " AND p.fk_user_author <> " . $user -> id ;
$sql .= $this -> db -> order ( $sortfield , $sortorder );
$sql .= $this -> db -> plimit ( $limit , $offset );
$result = $this -> db -> query ( $sql );
if ( $result )
{
$num = $this -> db -> num_rows ( $result );
if ( $num )
{
$i = 0 ;
while ( $i < $num )
{
$obj = $this -> db -> fetch_object ( $result );
if ( $shortlist == 1 )
{
$ga [ $obj -> propalid ] = $obj -> ref ;
}
else if ( $shortlist == 2 )
{
$ga [ $obj -> propalid ] = $obj -> ref . ' (' . $obj -> name . ')' ;
}
else
{
$ga [ $i ][ 'id' ] = $obj -> propalid ;
$ga [ $i ][ 'ref' ] = $obj -> ref ;
$ga [ $i ][ 'name' ] = $obj -> name ;
}
$i ++ ;
}
}
return $ga ;
}
else
{
dol_print_error ( $this -> db );
return - 1 ;
}
}
/**
* Returns an array with the numbers of related invoices
*
* @ return array Array of invoices
*/
function getInvoiceArrayList ()
{
return $this -> InvoiceArrayList ( $this -> id );
}
/**
* Returns an array with id and ref of related invoices
*
* @ param int $id Id propal
* @ return array Array of invoices id
*/
function InvoiceArrayList ( $id )
{
$ga = array ();
$linkedInvoices = array ();
$this -> fetchObjectLinked ( $id , $this -> element );
foreach ( $this -> linkedObjectsIds as $objecttype => $objectid )
{
// Nouveau système du comon object renvoi des rowid et non un id linéaire de 1 à n
// On parcourt donc une liste d'objets en tant qu'objet unique
foreach ( $objectid as $key => $object )
{
// Cas des factures liees directement
if ( $objecttype == 'facture' )
{
$linkedInvoices [] = $object ;
}
// Cas des factures liees par un autre objet (ex: commande)
else
{
$this -> fetchObjectLinked ( $object , $objecttype );
foreach ( $this -> linkedObjectsIds as $subobjecttype => $subobjectid )
{
foreach ( $subobjectid as $subkey => $subobject )
{
if ( $subobjecttype == 'facture' )
{
$linkedInvoices [] = $subobject ;
}
}
}
}
}
}
if ( count ( $linkedInvoices ) > 0 )
{
$sql = " SELECT rowid as facid, facnumber, total, datef as df, fk_user_author, fk_statut, paye " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " facture " ;
$sql .= " WHERE rowid IN ( " . implode ( ',' , $linkedInvoices ) . " ) " ;
dol_syslog ( get_class ( $this ) . " ::InvoiceArrayList " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$tab_sqlobj = array ();
$nump = $this -> db -> num_rows ( $resql );
for ( $i = 0 ; $i < $nump ; $i ++ )
{
$sqlobj = $this -> db -> fetch_object ( $resql );
$tab_sqlobj [] = $sqlobj ;
}
$this -> db -> free ( $resql );
$nump = count ( $tab_sqlobj );
if ( $nump )
{
$i = 0 ;
while ( $i < $nump )
{
$obj = array_shift ( $tab_sqlobj );
$ga [ $i ] = $obj ;
$i ++ ;
}
}
return $ga ;
}
else
{
return - 1 ;
}
}
else return $ga ;
}
/**
* Delete proposal
*
* @ param User $user Object user that delete
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int 1 if ok , otherwise if error
*/
function delete ( $user , $notrigger = 0 )
{
global $conf ;
require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php' ;
$error = 0 ;
$this -> db -> begin ();
if ( ! $notrigger )
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_DELETE' , $user );
if ( $result < 0 ) { $error ++ ; }
// End call triggers
}
if ( ! $error )
{
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " propaldet WHERE fk_propal = " . $this -> id ;
if ( $this -> db -> query ( $sql ))
{
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " propal WHERE rowid = " . $this -> id ;
if ( $this -> db -> query ( $sql ))
{
// Delete linked object
$res = $this -> deleteObjectLinked ();
if ( $res < 0 ) $error ++ ;
// Delete linked contacts
$res = $this -> delete_linked_contact ();
if ( $res < 0 ) $error ++ ;
if ( ! $error )
{
// We remove directory
$ref = dol_sanitizeFileName ( $this -> ref );
2018-02-25 17:43:19 +01:00
if ( $conf -> propal -> multidir_output [ $this -> entity ] && ! empty ( $this -> ref ))
2017-10-07 13:09:31 +02:00
{
2018-02-25 17:43:19 +01:00
$dir = $conf -> propal -> multidir_output [ $this -> entity ] . " / " . $ref ;
2017-10-07 13:09:31 +02:00
$file = $dir . " / " . $ref . " .pdf " ;
if ( file_exists ( $file ))
{
dol_delete_preview ( $this );
if ( ! dol_delete_file ( $file , 0 , 0 , 0 , $this )) // For triggers
{
$this -> error = 'ErrorFailToDeleteFile' ;
$this -> errors = array ( 'ErrorFailToDeleteFile' );
$this -> db -> rollback ();
return 0 ;
}
}
if ( file_exists ( $dir ))
{
$res =@ dol_delete_dir_recursive ( $dir );
if ( ! $res )
{
$this -> error = 'ErrorFailToDeleteDir' ;
$this -> errors = array ( 'ErrorFailToDeleteDir' );
$this -> db -> rollback ();
return 0 ;
}
}
}
}
// Removed extrafields
if ( ! $error )
{
if ( empty ( $conf -> global -> MAIN_EXTRAFIELDS_DISABLED )) // For avoid conflicts if trigger used
{
$result = $this -> deleteExtraFields ();
if ( $result < 0 )
{
$error ++ ;
$errorflag =- 4 ;
dol_syslog ( get_class ( $this ) . " ::delete erreur " . $errorflag . " " . $this -> error , LOG_ERR );
}
}
}
if ( ! $error )
{
dol_syslog ( get_class ( $this ) . " ::delete " . $this -> id . " by " . $user -> id , LOG_DEBUG );
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return 0 ;
}
}
else
{
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return - 3 ;
}
}
else
{
$this -> error = $this -> db -> lasterror ();
$this -> db -> rollback ();
return - 2 ;
}
}
else
{
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Change the delivery time
*
* @ param int $availability_id Id of new delivery time
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int > 0 if OK , < 0 if KO
* @ deprecated use set_availability
*/
function availability ( $availability_id , $notrigger = 0 )
{
global $user ;
if ( $this -> statut >= self :: STATUS_DRAFT )
{
$error = 0 ;
$this -> db -> begin ();
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'propal' ;
$sql .= ' SET fk_availability = ' . $availability_id ;
$sql .= ' WHERE rowid=' . $this -> id ;
dol_syslog ( __METHOD__ . ' availability(' . $availability_id . ')' , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> availability_id = $availability_id ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
else
{
$error_str = 'Propal status do not meet requirement ' . $this -> statut ;
dol_syslog ( __METHOD__ . $error_str , LOG_ERR );
$this -> error = $error_str ;
$this -> errors [] = $this -> error ;
return - 2 ;
}
}
/**
* Change source demand
*
* @ param int $demand_reason_id Id of new source demand
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int > 0 si ok , < 0 si ko
* @ deprecated use set_demand_reason
*/
function demand_reason ( $demand_reason_id , $notrigger = 0 )
{
2017-12-02 15:03:14 +01:00
global $user ;
2017-10-07 13:09:31 +02:00
if ( $this -> statut >= self :: STATUS_DRAFT )
{
$error = 0 ;
$this -> db -> begin ();
$sql = 'UPDATE ' . MAIN_DB_PREFIX . 'propal' ;
$sql .= ' SET fk_input_reason = ' . $demand_reason_id ;
$sql .= ' WHERE rowid=' . $this -> id ;
dol_syslog ( __METHOD__ . ' demand_reason(' . $demand_reason_id . ')' , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( ! $resql )
{
$this -> errors [] = $this -> db -> error ();
$error ++ ;
}
if ( ! $error )
{
$this -> oldcopy = clone $this ;
$this -> demand_reason_id = $demand_reason_id ;
}
if ( ! $notrigger && empty ( $error ))
{
// Call trigger
$result = $this -> call_trigger ( 'PROPAL_MODIFY' , $user );
if ( $result < 0 ) $error ++ ;
// End call triggers
}
if ( ! $error )
{
$this -> db -> commit ();
return 1 ;
}
else
{
foreach ( $this -> errors as $errmsg )
{
dol_syslog ( __METHOD__ . ' Error: ' . $errmsg , LOG_ERR );
$this -> error .= ( $this -> error ? ', ' . $errmsg : $errmsg );
}
$this -> db -> rollback ();
return - 1 * $error ;
}
}
else
{
$error_str = 'Propal status do not meet requirement ' . $this -> statut ;
dol_syslog ( __METHOD__ . $error_str , LOG_ERR );
$this -> error = $error_str ;
$this -> errors [] = $this -> error ;
return - 2 ;
}
}
/**
* Object Proposal Information
*
* @ param int $id Proposal id
* @ return void
*/
function info ( $id )
{
$sql = " SELECT c.rowid, " ;
$sql .= " c.datec, c.date_valid as datev, c.date_cloture as dateo, " ;
$sql .= " c.fk_user_author, c.fk_user_valid, c.fk_user_cloture " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " propal as c " ;
$sql .= " WHERE c.rowid = " . $id ;
$result = $this -> db -> query ( $sql );
if ( $result )
{
if ( $this -> db -> num_rows ( $result ))
{
$obj = $this -> db -> fetch_object ( $result );
$this -> id = $obj -> rowid ;
$this -> date_creation = $this -> db -> jdate ( $obj -> datec );
$this -> date_validation = $this -> db -> jdate ( $obj -> datev );
$this -> date_cloture = $this -> db -> jdate ( $obj -> dateo );
$cuser = new User ( $this -> db );
$cuser -> fetch ( $obj -> fk_user_author );
$this -> user_creation = $cuser ;
if ( $obj -> fk_user_valid )
{
$vuser = new User ( $this -> db );
$vuser -> fetch ( $obj -> fk_user_valid );
$this -> user_validation = $vuser ;
}
if ( $obj -> fk_user_cloture )
{
$cluser = new User ( $this -> db );
$cluser -> fetch ( $obj -> fk_user_cloture );
$this -> user_cloture = $cluser ;
}
}
$this -> db -> free ( $result );
}
else
{
dol_print_error ( $this -> db );
}
}
/**
* Return label of status of proposal ( draft , validated , ... )
*
2017-11-18 01:48:16 +01:00
* @ param int $mode 0 = Long label , 1 = Short label , 2 = Picto + Short label , 3 = Picto , 4 = Picto + Long label , 5 = Short label + Picto , 6 = Long label + Picto
2017-10-07 13:09:31 +02:00
* @ return string Label
*/
function getLibStatut ( $mode = 0 )
{
return $this -> LibStatut ( $this -> statut , $mode );
}
/**
* Return label of a status ( draft , validated , ... )
*
* @ param int $statut id statut
* @ 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
* @ return string Label
*/
2018-04-21 15:08:46 +02:00
function LibStatut ( $statut , $mode = 1 )
2017-10-07 13:09:31 +02:00
{
2018-05-16 15:23:52 +02:00
global $conf ;
2018-04-21 15:08:46 +02:00
// Init/load array of translation of status
if ( empty ( $this -> labelstatut ) || empty ( $this -> labelstatut_short ))
{
global $langs ;
$langs -> load ( " propal " );
2018-05-16 15:23:52 +02:00
$this -> labelstatut [ 0 ] = $langs -> trans ( " PropalStatusDraft " );
$this -> labelstatut [ 1 ] = $langs -> trans ( " PropalStatusValidated " );
$this -> labelstatut [ 2 ] = $langs -> trans ( " PropalStatusSigned " );
$this -> labelstatut [ 3 ] = $langs -> trans ( " PropalStatusNotSigned " );
$this -> labelstatut [ 4 ] = $langs -> trans ( " PropalStatusBilled " );
$this -> labelstatut_short [ 0 ] = $langs -> trans ( " PropalStatusDraftShort " );
2018-10-09 14:06:45 +02:00
$this -> labelstatut_short [ 1 ] = $langs -> trans ( " PropalStatusValidatedShort " );
2018-05-16 15:23:52 +02:00
$this -> labelstatut_short [ 2 ] = $langs -> trans ( " PropalStatusSignedShort " );
$this -> labelstatut_short [ 3 ] = $langs -> trans ( " PropalStatusNotSignedShort " );
$this -> labelstatut_short [ 4 ] = $langs -> trans ( " PropalStatusBilledShort " );
2018-04-21 15:08:46 +02:00
}
2017-10-07 13:09:31 +02:00
2017-12-06 23:21:58 +01:00
$statuttrans = '' ;
2017-10-07 13:09:31 +02:00
if ( $statut == self :: STATUS_DRAFT ) $statuttrans = 'statut0' ;
if ( $statut == self :: STATUS_VALIDATED ) $statuttrans = 'statut1' ;
if ( $statut == self :: STATUS_SIGNED ) $statuttrans = 'statut3' ;
if ( $statut == self :: STATUS_NOTSIGNED ) $statuttrans = 'statut5' ;
if ( $statut == self :: STATUS_BILLED ) $statuttrans = 'statut6' ;
if ( $mode == 0 ) return $this -> labelstatut [ $statut ];
if ( $mode == 1 ) return $this -> labelstatut_short [ $statut ];
if ( $mode == 2 ) return img_picto ( $this -> labelstatut_short [ $statut ], $statuttrans ) . ' ' . $this -> labelstatut_short [ $statut ];
if ( $mode == 3 ) return img_picto ( $this -> labelstatut [ $statut ], $statuttrans );
if ( $mode == 4 ) return img_picto ( $this -> labelstatut [ $statut ], $statuttrans ) . ' ' . $this -> labelstatut [ $statut ];
if ( $mode == 5 ) return '<span class="hideonsmartphone">' . $this -> labelstatut_short [ $statut ] . ' </span>' . img_picto ( $this -> labelstatut [ $statut ], $statuttrans );
if ( $mode == 6 ) return '<span class="hideonsmartphone">' . $this -> labelstatut [ $statut ] . ' </span>' . img_picto ( $this -> labelstatut [ $statut ], $statuttrans );
}
/**
* Load indicators for dashboard ( this -> nbtodo and this -> nbtodolate )
*
* @ param User $user Object user
* @ param int $mode " opened " for proposal to close , " signed " for proposal to invoice
* @ return WorkboardResponse | int < 0 if KO , WorkboardResponse if OK
*/
function load_board ( $user , $mode )
{
global $conf , $langs ;
$clause = " WHERE " ;
$sql = " SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " propal as p " ;
if ( ! $user -> rights -> societe -> client -> voir && ! $user -> societe_id )
{
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " societe_commerciaux as sc ON p.fk_soc = sc.fk_soc " ;
$sql .= " WHERE sc.fk_user = " . $user -> id ;
$clause = " AND " ;
}
$sql .= $clause . " p.entity IN ( " . getEntity ( 'propal' ) . " ) " ;
if ( $mode == 'opened' ) $sql .= " AND p.fk_statut = " . self :: STATUS_VALIDATED ;
if ( $mode == 'signed' ) $sql .= " AND p.fk_statut = " . self :: STATUS_SIGNED ;
if ( $user -> societe_id ) $sql .= " AND p.fk_soc = " . $user -> societe_id ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$langs -> load ( " propal " );
$now = dol_now ();
2017-12-06 23:21:58 +01:00
$delay_warning = 0 ;
$statut = 0 ;
$label = '' ;
2017-10-07 13:09:31 +02:00
if ( $mode == 'opened' ) {
$delay_warning = $conf -> propal -> cloture -> warning_delay ;
$statut = self :: STATUS_VALIDATED ;
$label = $langs -> trans ( " PropalsToClose " );
}
if ( $mode == 'signed' ) {
$delay_warning = $conf -> propal -> facturation -> warning_delay ;
$statut = self :: STATUS_SIGNED ;
$label = $langs -> trans ( " PropalsToBill " ); // We set here bill but may be billed or ordered
}
$response = new WorkboardResponse ();
$response -> warning_delay = $delay_warning / 60 / 60 / 24 ;
$response -> label = $label ;
$response -> url = DOL_URL_ROOT . '/comm/propal/list.php?viewstatut=' . $statut . '&mainmenu=commercial&leftmenu=propals' ;
$response -> url_late = DOL_URL_ROOT . '/comm/propal/list.php?viewstatut=' . $statut . '&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc' ;
$response -> img = img_object ( '' , " propal " );
// This assignment in condition is not a bug. It allows walking the results.
while ( $obj = $this -> db -> fetch_object ( $resql ))
{
$response -> nbtodo ++ ;
if ( $mode == 'opened' )
{
$datelimit = $this -> db -> jdate ( $obj -> datefin );
if ( $datelimit < ( $now - $delay_warning ))
{
$response -> nbtodolate ++ ;
}
}
// TODO Definir regle des propales a facturer en retard
// if ($mode == 'signed' && ! count($this->FactureListeArray($obj->rowid))) $this->nbtodolate++;
}
return $response ;
}
else
{
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
/**
* Initialise an instance with random values .
* Used to build previews or test instances .
* id must be 0 if object instance is a specimen .
*
* @ return void
*/
function initAsSpecimen ()
{
global $langs ;
// Load array of products prodids
$num_prods = 0 ;
$prodids = array ();
$sql = " SELECT rowid " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " product " ;
$sql .= " WHERE entity IN ( " . getEntity ( 'product' ) . " ) " ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$num_prods = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num_prods )
{
$i ++ ;
$row = $this -> db -> fetch_row ( $resql );
$prodids [ $i ] = $row [ 0 ];
}
}
// Initialise parametres
$this -> id = 0 ;
$this -> ref = 'SPECIMEN' ;
$this -> ref_client = 'NEMICEPS' ;
$this -> specimen = 1 ;
$this -> socid = 1 ;
$this -> date = time ();
$this -> fin_validite = $this -> date + 3600 * 24 * 30 ;
$this -> cond_reglement_id = 1 ;
$this -> cond_reglement_code = 'RECEP' ;
$this -> mode_reglement_id = 7 ;
$this -> mode_reglement_code = 'CHQ' ;
$this -> availability_id = 1 ;
$this -> availability_code = 'AV_NOW' ;
$this -> demand_reason_id = 1 ;
$this -> demand_reason_code = 'SRC_00' ;
$this -> note_public = 'This is a comment (public)' ;
$this -> note_private = 'This is a comment (private)' ;
// Lines
$nbp = 5 ;
$xnbp = 0 ;
while ( $xnbp < $nbp )
{
$line = new PropaleLigne ( $this -> db );
$line -> desc = $langs -> trans ( " Description " ) . " " . $xnbp ;
$line -> qty = 1 ;
$line -> subprice = 100 ;
$line -> price = 100 ;
$line -> tva_tx = 20 ;
$line -> localtax1_tx = 0 ;
$line -> localtax2_tx = 0 ;
if ( $xnbp == 2 )
{
$line -> total_ht = 50 ;
$line -> total_ttc = 60 ;
$line -> total_tva = 10 ;
$line -> remise_percent = 50 ;
}
else
{
$line -> total_ht = 100 ;
$line -> total_ttc = 120 ;
$line -> total_tva = 20 ;
$line -> remise_percent = 00 ;
}
if ( $num_prods > 0 )
{
$prodid = mt_rand ( 1 , $num_prods );
$line -> fk_product = $prodids [ $prodid ];
$line -> product_ref = 'SPECIMEN' ;
}
$this -> lines [ $xnbp ] = $line ;
$this -> total_ht += $line -> total_ht ;
$this -> total_tva += $line -> total_tva ;
$this -> total_ttc += $line -> total_ttc ;
$xnbp ++ ;
}
}
/**
* Charge indicateurs this -> nb de tableau de bord
*
* @ return int < 0 if ko , > 0 if ok
*/
function load_state_board ()
{
global $user ;
$this -> nb = array ();
$clause = " WHERE " ;
$sql = " SELECT count(p.rowid) as nb " ;
$sql .= " FROM " . MAIN_DB_PREFIX . " propal as p " ;
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " societe as s ON p.fk_soc = s.rowid " ;
if ( ! $user -> rights -> societe -> client -> voir && ! $user -> societe_id )
{
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . " societe_commerciaux as sc ON s.rowid = sc.fk_soc " ;
$sql .= " WHERE sc.fk_user = " . $user -> id ;
$clause = " AND " ;
}
$sql .= " " . $clause . " p.entity IN ( " . getEntity ( 'propal' ) . " ) " ;
2017-06-09 09:25:15 +02:00
2017-10-07 13:09:31 +02:00
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
// This assignment in condition is not a bug. It allows walking the results.
while ( $obj = $this -> db -> fetch_object ( $resql ))
{
$this -> nb [ " proposals " ] = $obj -> nb ;
}
$this -> db -> free ( $resql );
2017-04-28 14:33:06 +02:00
return 1 ;
}
else
{
2017-10-07 13:09:31 +02:00
dol_print_error ( $this -> db );
$this -> error = $this -> db -> error ();
return - 1 ;
2017-04-28 14:33:06 +02:00
}
}
2013-04-27 15:08:35 +02:00
2017-10-07 13:09:31 +02:00
/**
* Returns the reference to the following non used Proposal used depending on the active numbering module
* defined into PROPALE_ADDON
*
* @ param Societe $soc Object thirdparty
* @ return string Reference libre pour la propale
*/
function getNextNumRef ( $soc )
{
global $conf , $langs ;
$langs -> load ( " propal " );
2014-06-12 15:56:38 +02:00
2018-07-01 17:06:19 +02:00
$constant = 'PROPALE_ADDON_' . $this -> entity ;
if ( ! empty ( $conf -> global -> $constant )) {
$classname = $conf -> global -> $constant ; // for multicompany proposal sharing
} else {
$classname = $conf -> global -> PROPALE_ADDON ;
}
if ( ! empty ( $classname ))
2016-09-22 12:53:44 +02:00
{
2017-10-07 13:09:31 +02:00
$mybool = false ;
2012-03-18 19:23:01 +01:00
2018-07-01 17:06:19 +02:00
$file = $classname . " .php " ;
2013-07-15 09:33:26 +02:00
2017-10-07 13:09:31 +02:00
// Include file with class
$dirmodels = array_merge ( array ( '/' ), ( array ) $conf -> modules_parts [ 'models' ]);
foreach ( $dirmodels as $reldir ) {
$dir = dol_buildpath ( $reldir . " core/modules/propale/ " );
// Load file with numbering class (if found)
$mybool |=@ include_once $dir . $file ;
}
if ( ! $mybool )
2013-07-15 09:33:26 +02:00
{
2017-10-07 13:09:31 +02:00
dol_print_error ( '' , " Failed to include file " . $file );
return '' ;
2013-07-15 09:33:26 +02:00
}
2017-10-07 13:09:31 +02:00
$obj = new $classname ();
$numref = " " ;
$numref = $obj -> getNextValue ( $soc , $this );
if ( $numref != " " )
{
return $numref ;
}
else
{
$this -> error = $obj -> error ;
//dol_print_error($db,"Propale::getNextNumRef ".$obj->error);
return " " ;
}
2013-07-15 09:33:26 +02:00
}
else
{
2017-10-07 13:09:31 +02:00
$langs -> load ( " errors " );
print $langs -> trans ( " Error " ) . " " . $langs -> trans ( " ErrorModuleSetupNotComplete " );
return " " ;
2013-07-15 09:33:26 +02:00
}
2017-10-07 13:09:31 +02:00
}
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
/**
* Return clicable link of object ( with eventually picto )
*
* @ param int $withpicto Add picto into link
* @ param string $option Where point the link ( 'expedition' , 'document' , ... )
* @ param string $get_params Parametres added to url
* @ param int $notooltip 1 = Disable tooltip
* @ param int $save_lastsearch_value - 1 = Auto , 0 = No save of lastsearch_values when clicking , 1 = Save lastsearch_values whenclicking
* @ return string String with URL
*/
function getNomUrl ( $withpicto = 0 , $option = '' , $get_params = '' , $notooltip = 0 , $save_lastsearch_value =- 1 )
{
global $langs , $conf , $user ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
if ( ! empty ( $conf -> dol_no_mouse_hover )) $notooltip = 1 ; // Force disable tooltips
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$result = '' ;
$label = '' ;
$url = '' ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
if ( $user -> rights -> propal -> lire )
{
$label = '<u>' . $langs -> trans ( " ShowPropal " ) . '</u>' ;
if ( ! empty ( $this -> ref ))
$label .= '<br><b>' . $langs -> trans ( 'Ref' ) . ':</b> ' . $this -> ref ;
if ( ! empty ( $this -> ref_client ))
$label .= '<br><b>' . $langs -> trans ( 'RefCustomer' ) . ':</b> ' . $this -> ref_client ;
if ( ! empty ( $this -> total_ht ))
$label .= '<br><b>' . $langs -> trans ( 'AmountHT' ) . ':</b> ' . price ( $this -> total_ht , 0 , $langs , 0 , - 1 , - 1 , $conf -> currency );
if ( ! empty ( $this -> total_tva ))
$label .= '<br><b>' . $langs -> trans ( 'VAT' ) . ':</b> ' . price ( $this -> total_tva , 0 , $langs , 0 , - 1 , - 1 , $conf -> currency );
if ( ! empty ( $this -> total_ttc ))
$label .= '<br><b>' . $langs -> trans ( 'AmountTTC' ) . ':</b> ' . price ( $this -> total_ttc , 0 , $langs , 0 , - 1 , - 1 , $conf -> currency );
if ( $option == '' ) {
$url = DOL_URL_ROOT . '/comm/propal/card.php?id=' . $this -> id . $get_params ;
}
if ( $option == 'compta' ) { // deprecated
$url = DOL_URL_ROOT . '/comm/propal/card.php?id=' . $this -> id . $get_params ;
}
if ( $option == 'expedition' ) {
$url = DOL_URL_ROOT . '/expedition/propal.php?id=' . $this -> id . $get_params ;
}
if ( $option == 'document' ) {
$url = DOL_URL_ROOT . '/comm/propal/document.php?id=' . $this -> id . $get_params ;
}
2014-11-03 16:20:55 +01:00
2017-10-07 13:09:31 +02:00
if ( $option != 'nolink' )
{
// Add param to save lastsearch_values or not
$add_save_lastsearch_values = ( $save_lastsearch_value == 1 ? 1 : 0 );
if ( $save_lastsearch_value == - 1 && preg_match ( '/list\.php/' , $_SERVER [ " PHP_SELF " ])) $add_save_lastsearch_values = 1 ;
if ( $add_save_lastsearch_values ) $url .= '&save_lastsearch_values=1' ;
}
}
2014-11-03 16:20:55 +01:00
2017-10-07 13:09:31 +02:00
$linkclose = '' ;
if ( empty ( $notooltip ) && $user -> rights -> propal -> lire )
{
if ( ! empty ( $conf -> global -> MAIN_OPTIMIZEFORTEXTBROWSER ))
{
$label = $langs -> trans ( " ShowPropal " );
$linkclose .= ' alt="' . dol_escape_htmltag ( $label , 1 ) . '"' ;
}
$linkclose .= ' title="' . dol_escape_htmltag ( $label , 1 ) . '"' ;
$linkclose .= ' class="classfortooltip"' ;
}
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$linkstart = '<a href="' . $url . '"' ;
$linkstart .= $linkclose . '>' ;
$linkend = '</a>' ;
2015-04-23 23:21:06 +02:00
2017-11-02 15:03:09 +01:00
$result .= $linkstart ;
if ( $withpicto ) $result .= img_object (( $notooltip ? '' : $label ), $this -> picto , ( $notooltip ? (( $withpicto != 2 ) ? 'class="paddingright"' : '' ) : 'class="' . (( $withpicto != 2 ) ? 'paddingright ' : '' ) . 'classfortooltip"' ), 0 , 0 , $notooltip ? 0 : 1 );
if ( $withpicto != 2 ) $result .= $this -> ref ;
$result .= $linkend ;
2017-10-07 13:09:31 +02:00
return $result ;
}
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
/**
* Retrieve an array of propal lines
*
* @ return int > 0 if OK , < 0 if KO
*/
function getLinesArray ()
{
// TODO Duplicate with fetch_lines ? Wich one to keep ?
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$this -> lines = array ();
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,' ;
$sql .= ' pt.qty, pt.vat_src_code, pt.tva_tx, pt.localtax1_tx, pt.localtax2_tx, pt.localtax1_type, pt.localtax2_type, pt.remise_percent, pt.subprice, pt.info_bits,' ;
$sql .= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.total_localtax1, pt.total_localtax2, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code,' ;
$sql .= ' pt.date_start, pt.date_end, pt.product_type, pt.rang, pt.fk_parent_line,' ;
$sql .= ' pt.fk_unit,' ;
$sql .= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid, p.description as product_desc, p.tobatch as product_tobatch,' ;
$sql .= ' p.entity,' ;
$sql .= ' pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc' ;
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'propaldet as pt' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON pt.fk_product=p.rowid' ;
$sql .= ' WHERE pt.fk_propal = ' . $this -> id ;
$sql .= ' ORDER BY pt.rang ASC, pt.rowid' ;
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
dol_syslog ( get_class ( $this ) . '::getLinesArray' , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
while ( $i < $num )
{
$obj = $this -> db -> fetch_object ( $resql );
$this -> lines [ $i ] = new PropaleLigne ( $this -> db );
$this -> lines [ $i ] -> id = $obj -> rowid ; // for backward compatibility
$this -> lines [ $i ] -> rowid = $obj -> rowid ;
$this -> lines [ $i ] -> label = $obj -> custom_label ;
$this -> lines [ $i ] -> desc = $obj -> description ;
$this -> lines [ $i ] -> description = $obj -> description ;
$this -> lines [ $i ] -> fk_product = $obj -> fk_product ;
$this -> lines [ $i ] -> ref = $obj -> ref ;
$this -> lines [ $i ] -> product_ref = $obj -> ref ;
$this -> lines [ $i ] -> entity = $obj -> entity ; // Product entity
$this -> lines [ $i ] -> product_label = $obj -> product_label ;
$this -> lines [ $i ] -> product_desc = $obj -> product_desc ;
$this -> lines [ $i ] -> product_tobatch = $obj -> product_tobatch ;
$this -> lines [ $i ] -> fk_product_type = $obj -> fk_product_type ; // deprecated
$this -> lines [ $i ] -> product_type = $obj -> product_type ;
$this -> lines [ $i ] -> qty = $obj -> qty ;
$this -> lines [ $i ] -> subprice = $obj -> subprice ;
$this -> lines [ $i ] -> fk_remise_except = $obj -> fk_remise_except ;
$this -> lines [ $i ] -> remise_percent = $obj -> remise_percent ;
$this -> lines [ $i ] -> vat_src_code = $obj -> vat_src_code ;
$this -> lines [ $i ] -> tva_tx = $obj -> tva_tx ;
$this -> lines [ $i ] -> localtax1_tx = $obj -> localtax1_tx ;
$this -> lines [ $i ] -> localtax2_tx = $obj -> localtax2_tx ;
$this -> lines [ $i ] -> localtax1_type = $obj -> localtax1_type ;
$this -> lines [ $i ] -> localtax2_type = $obj -> localtax2_type ;
$this -> lines [ $i ] -> info_bits = $obj -> info_bits ;
$this -> lines [ $i ] -> total_ht = $obj -> total_ht ;
$this -> lines [ $i ] -> total_tva = $obj -> total_tva ;
$this -> lines [ $i ] -> total_ttc = $obj -> total_ttc ;
$this -> lines [ $i ] -> total_localtax1 = $obj -> total_localtax1 ;
$this -> lines [ $i ] -> total_localtax2 = $obj -> total_localtax2 ;
$this -> lines [ $i ] -> fk_fournprice = $obj -> fk_fournprice ;
2012-08-01 17:36:15 +02:00
$marginInfos = getMarginInfos ( $obj -> subprice , $obj -> remise_percent , $obj -> tva_tx , $obj -> localtax1_tx , $obj -> localtax2_tx , $this -> lines [ $i ] -> fk_fournprice , $obj -> pa_ht );
$this -> lines [ $i ] -> pa_ht = $marginInfos [ 0 ];
2012-07-29 09:54:58 +02:00
$this -> lines [ $i ] -> marge_tx = $marginInfos [ 1 ];
$this -> lines [ $i ] -> marque_tx = $marginInfos [ 2 ];
2012-08-01 17:36:15 +02:00
$this -> lines [ $i ] -> fk_parent_line = $obj -> fk_parent_line ;
2017-10-07 13:09:31 +02:00
$this -> lines [ $i ] -> special_code = $obj -> special_code ;
$this -> lines [ $i ] -> rang = $obj -> rang ;
$this -> lines [ $i ] -> date_start = $this -> db -> jdate ( $obj -> date_start );
$this -> lines [ $i ] -> date_end = $this -> db -> jdate ( $obj -> date_end );
$this -> lines [ $i ] -> fk_unit = $obj -> fk_unit ;
2016-07-08 20:40:25 +02:00
2016-01-18 19:45:27 +01:00
// Multicurrency
$this -> lines [ $i ] -> fk_multicurrency = $obj -> fk_multicurrency ;
$this -> lines [ $i ] -> multicurrency_code = $obj -> multicurrency_code ;
$this -> lines [ $i ] -> multicurrency_subprice = $obj -> multicurrency_subprice ;
$this -> lines [ $i ] -> multicurrency_total_ht = $obj -> multicurrency_total_ht ;
$this -> lines [ $i ] -> multicurrency_total_tva = $obj -> multicurrency_total_tva ;
$this -> lines [ $i ] -> multicurrency_total_ttc = $obj -> multicurrency_total_ttc ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$i ++ ;
}
$this -> db -> free ( $resql );
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
return - 1 ;
}
}
2007-05-05 00:37:06 +02:00
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
/**
* Create a document onto disk according to template module .
*
* @ param string $modele Force model to use ( '' to not force )
* @ param Translate $outputlangs Object langs to use for output
* @ param int $hidedetails Hide details of lines
* @ param int $hidedesc Hide description
* @ param int $hideref Hide ref
2018-06-15 09:47:28 +02:00
* @ param null | array $moreparams Array to provide more information
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
* @ return int 0 if KO , 1 if OK
*/
2018-06-15 09:47:28 +02:00
public function generateDocument ( $modele , $outputlangs , $hidedetails = 0 , $hidedesc = 0 , $hideref = 0 , $moreparams = null )
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
{
2016-05-06 22:11:05 +02:00
global $conf , $langs ;
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
$langs -> load ( " propale " );
2017-01-16 21:16:05 +01:00
if ( ! dol_strlen ( $modele )) {
$modele = 'azur' ;
if ( $this -> modelpdf ) {
$modele = $this -> modelpdf ;
} elseif ( ! empty ( $conf -> global -> PROPALE_ADDON_PDF )) {
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
$modele = $conf -> global -> PROPALE_ADDON_PDF ;
}
}
2014-09-21 18:16:14 +02:00
$modelpath = " core/modules/propale/doc/ " ;
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
2018-06-15 09:47:28 +02:00
return $this -> commonGenerateDocument ( $modelpath , $modele , $outputlangs , $hidedetails , $hidedesc , $hideref , $moreparams );
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
}
2015-04-18 18:11:01 +02:00
/**
* Function used to replace a thirdparty id with another one .
*
* @ param DoliDB $db Database handler
* @ param int $origin_id Old thirdparty id
* @ param int $dest_id New thirdparty id
* @ return bool
*/
public static function replaceThirdparty ( DoliDB $db , $origin_id , $dest_id )
{
$tables = array (
'propal'
);
Created a method generateDocument for several classes
Which are: Commande, Contrat, Livraison, Facture, Projet, Propal, Task, Expedition, CommandeFournisseur, FactureFournisseur and therefore deprecated the following methods supplier_order_pdf_create, supplier_invoice_pdf_create, delivery_order_pdf_create, task_pdf_create, propale_pdf_create, project_pdf_create, facture_pdf_create, expedition_pdf_create, commande_pdf_create
2014-09-16 12:30:37 +02:00
2015-04-18 18:11:01 +02:00
return CommonObject :: commonReplaceThirdparty ( $db , $origin_id , $dest_id , $tables );
}
2005-08-11 22:01:25 +02:00
}
/**
2015-12-16 19:26:50 +01:00
* Class to manage commercial proposal lines
2008-08-28 01:00:37 +02:00
*/
2017-07-13 23:46:01 +02:00
class PropaleLigne extends CommonObjectLine
2003-09-11 18:00:49 +02:00
{
2017-10-07 13:09:31 +02:00
public $element = 'propaldet' ;
public $table_element = 'propaldet' ;
2013-06-10 16:05:41 +02:00
2017-10-07 13:09:31 +02:00
var $oldline ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// From llx_propaldet
var $fk_propal ;
var $fk_parent_line ;
var $desc ; // Description ligne
var $fk_product ; // Id produit predefini
2015-04-23 23:21:06 +02:00
/**
* @ deprecated
* @ see product_type
*/
var $fk_product_type ;
2015-04-03 05:18:47 +02:00
/**
* Product type .
* @ var int
2015-04-23 23:21:06 +02:00
* @ see Product :: TYPE_PRODUCT , Product :: TYPE_SERVICE
2015-04-03 05:18:47 +02:00
*/
2017-10-07 13:09:31 +02:00
var $product_type = Product :: TYPE_PRODUCT ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
var $qty ;
var $tva_tx ;
var $subprice ;
var $remise_percent ;
var $fk_remise_except ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
var $rang = 0 ;
2012-07-20 09:57:50 +02:00
2012-08-01 17:36:15 +02:00
var $fk_fournprice ;
var $pa_ht ;
var $marge_tx ;
var $marque_tx ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
var $special_code ; // Tag for special lines (exlusive tags)
// 1: frais de port
// 2: ecotaxe
// 3: option line (when qty = 0)
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
var $info_bits = 0 ; // Liste d'options cumulables:
// Bit 0: 0 si TVA normal - 1 si TVA NPR
// Bit 1: 0 ligne normale - 1 si ligne de remise fixe
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
var $total_ht ; // Total HT de la ligne toute quantite et incluant la remise ligne
var $total_tva ; // Total TVA de la ligne toute quantite et incluant la remise ligne
var $total_ttc ; // Total TTC de la ligne toute quantite et incluant la remise ligne
2012-03-18 19:23:01 +01:00
2015-04-23 23:21:06 +02:00
/**
* @ deprecated
* @ see $remise_percent , $fk_remise_except
*/
2017-10-07 13:09:31 +02:00
var $remise ;
2015-04-23 23:21:06 +02:00
/**
* @ deprecated
* @ see subprice
*/
2017-10-07 13:09:31 +02:00
var $price ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// From llx_product
2015-04-23 23:21:06 +02:00
/**
* @ deprecated
* @ see product_ref
*/
2017-10-07 13:09:31 +02:00
var $ref ;
2015-04-23 23:21:06 +02:00
/**
* Product reference
* @ var string
*/
public $product_ref ;
/**
* @ deprecated
* @ see product_label
*/
2017-10-07 13:09:31 +02:00
var $libelle ;
2015-04-23 23:21:06 +02:00
/**
* Product label
* @ var string
*/
public $product_label ;
/**
* Product description
* @ var string
*/
2017-10-07 13:09:31 +02:00
public $product_desc ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
var $localtax1_tx ; // Local tax 1
var $localtax2_tx ; // Local tax 2
var $localtax1_type ; // Local tax 1 type
2013-09-10 18:45:16 +02:00
var $localtax2_type ; // Local tax 2 type
2017-10-07 13:09:31 +02:00
var $total_localtax1 ; // Line total local tax 1
var $total_localtax2 ; // Line total local tax 2
2013-04-27 15:08:35 +02:00
2017-10-07 13:09:31 +02:00
var $date_start ;
var $date_end ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
var $skip_update_total ; // Skip update price total for special lines
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// Multicurrency
2016-01-18 19:45:27 +01:00
var $fk_multicurrency ;
var $multicurrency_code ;
var $multicurrency_subprice ;
var $multicurrency_total_ht ;
var $multicurrency_total_tva ;
var $multicurrency_total_ttc ;
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
/**
* Class line Contructor
*
* @ param DoliDB $db Database handler
*/
function __construct ( $db )
{
$this -> db = $db ;
}
/**
* Retrieve the propal line object
*
* @ param int $rowid Propal line id
* @ return int < 0 if KO , > 0 if OK
*/
2012-07-29 09:54:58 +02:00
function fetch ( $rowid )
{
2017-05-03 12:34:57 +02:00
$sql = 'SELECT pd.rowid, pd.fk_propal, pd.fk_parent_line, pd.fk_product, pd.label as custom_label, pd.description, pd.price, pd.qty, pd.vat_src_code, pd.tva_tx,' ;
2012-07-29 09:54:58 +02:00
$sql .= ' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,' ;
$sql .= ' pd.info_bits, pd.total_ht, pd.total_tva, pd.total_ttc, pd.fk_product_fournisseur_price as fk_fournprice, pd.buy_price_ht as pa_ht, pd.special_code, pd.rang,' ;
2015-02-26 14:15:33 +01:00
$sql .= ' pd.fk_unit,' ;
2012-07-29 09:54:58 +02:00
$sql .= ' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,' ;
2016-01-18 19:45:27 +01:00
$sql .= ' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,' ;
2013-04-15 15:31:12 +02:00
$sql .= ' p.ref as product_ref, p.label as product_label, p.description as product_desc,' ;
2014-05-28 01:07:27 +02:00
$sql .= ' pd.date_start, pd.date_end, pd.product_type' ;
2012-07-29 09:54:58 +02:00
$sql .= ' FROM ' . MAIN_DB_PREFIX . 'propaldet as pd' ;
$sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'product as p ON pd.fk_product = p.rowid' ;
$sql .= ' WHERE pd.rowid = ' . $rowid ;
$result = $this -> db -> query ( $sql );
if ( $result )
{
$objp = $this -> db -> fetch_object ( $result );
2017-10-06 15:01:31 +02:00
if ( $objp )
{
$this -> id = $objp -> rowid ;
$this -> rowid = $objp -> rowid ; // deprecated
$this -> fk_propal = $objp -> fk_propal ;
$this -> fk_parent_line = $objp -> fk_parent_line ;
$this -> label = $objp -> custom_label ;
$this -> desc = $objp -> description ;
$this -> qty = $objp -> qty ;
$this -> price = $objp -> price ; // deprecated
$this -> subprice = $objp -> subprice ;
$this -> vat_src_code = $objp -> vat_src_code ;
$this -> tva_tx = $objp -> tva_tx ;
$this -> remise = $objp -> remise ; // deprecated
$this -> remise_percent = $objp -> remise_percent ;
$this -> fk_remise_except = $objp -> fk_remise_except ;
$this -> fk_product = $objp -> fk_product ;
$this -> info_bits = $objp -> info_bits ;
$this -> total_ht = $objp -> total_ht ;
$this -> total_tva = $objp -> total_tva ;
$this -> total_ttc = $objp -> total_ttc ;
$this -> fk_fournprice = $objp -> fk_fournprice ;
$marginInfos = getMarginInfos ( $objp -> subprice , $objp -> remise_percent , $objp -> tva_tx , $objp -> localtax1_tx , $objp -> localtax2_tx , $this -> fk_fournprice , $objp -> pa_ht );
$this -> pa_ht = $marginInfos [ 0 ];
$this -> marge_tx = $marginInfos [ 1 ];
$this -> marque_tx = $marginInfos [ 2 ];
$this -> special_code = $objp -> special_code ;
$this -> product_type = $objp -> product_type ;
$this -> rang = $objp -> rang ;
$this -> ref = $objp -> product_ref ; // deprecated
$this -> product_ref = $objp -> product_ref ;
$this -> libelle = $objp -> product_label ; // deprecated
$this -> product_label = $objp -> product_label ;
$this -> product_desc = $objp -> product_desc ;
$this -> fk_unit = $objp -> fk_unit ;
$this -> date_start = $this -> db -> jdate ( $objp -> date_start );
2017-10-07 13:09:31 +02:00
$this -> date_end = $this -> db -> jdate ( $objp -> date_end );
2012-07-29 09:54:58 +02:00
2017-10-06 15:01:31 +02:00
// Multicurrency
$this -> fk_multicurrency = $objp -> fk_multicurrency ;
$this -> multicurrency_code = $objp -> multicurrency_code ;
$this -> multicurrency_subprice = $objp -> multicurrency_subprice ;
$this -> multicurrency_total_ht = $objp -> multicurrency_total_ht ;
$this -> multicurrency_total_tva = $objp -> multicurrency_total_tva ;
$this -> multicurrency_total_ttc = $objp -> multicurrency_total_ttc ;
2016-07-08 20:40:25 +02:00
2018-04-14 17:04:38 +02:00
$this -> fetch_optionals ();
2017-10-06 15:01:31 +02:00
$this -> db -> free ( $result );
2015-08-09 13:52:02 +02:00
2017-10-07 13:09:31 +02:00
return 1 ;
2017-10-06 15:01:31 +02:00
}
else
{
return 0 ;
}
2012-07-29 09:54:58 +02:00
}
else
{
2015-08-09 13:52:02 +02:00
return - 1 ;
2012-07-29 09:54:58 +02:00
}
}
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
/**
* Insert object line propal in database
*
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if KO , > 0 if OK
*/
function insert ( $notrigger = 0 )
{
global $conf , $user ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$error = 0 ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
dol_syslog ( get_class ( $this ) . " ::insert rang= " . $this -> rang );
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$pa_ht_isemptystring = ( empty ( $this -> pa_ht ) && $this -> pa_ht == '' ); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'.
2016-07-08 20:40:25 +02:00
2017-10-07 13:09:31 +02:00
// Clean parameters
if ( empty ( $this -> tva_tx )) $this -> tva_tx = 0 ;
if ( empty ( $this -> localtax1_tx )) $this -> localtax1_tx = 0 ;
if ( empty ( $this -> localtax2_tx )) $this -> localtax2_tx = 0 ;
if ( empty ( $this -> localtax1_type )) $this -> localtax1_type = 0 ;
2013-09-10 18:45:16 +02:00
if ( empty ( $this -> localtax2_type )) $this -> localtax2_type = 0 ;
2017-10-07 13:09:31 +02:00
if ( empty ( $this -> total_localtax1 )) $this -> total_localtax1 = 0 ;
if ( empty ( $this -> total_localtax2 )) $this -> total_localtax2 = 0 ;
if ( empty ( $this -> rang )) $this -> rang = 0 ;
if ( empty ( $this -> remise )) $this -> remise = 0 ;
if ( empty ( $this -> remise_percent ) || ! is_numeric ( $this -> remise_percent )) $this -> remise_percent = 0 ;
if ( empty ( $this -> info_bits )) $this -> info_bits = 0 ;
if ( empty ( $this -> special_code )) $this -> special_code = 0 ;
if ( empty ( $this -> fk_parent_line )) $this -> fk_parent_line = 0 ;
if ( empty ( $this -> fk_fournprice )) $this -> fk_fournprice = 0 ;
2015-07-21 10:50:07 +02:00
if ( ! is_numeric ( $this -> qty )) $this -> qty = 0 ;
2017-10-07 13:09:31 +02:00
if ( empty ( $this -> pa_ht )) $this -> pa_ht = 0 ;
if ( empty ( $this -> multicurrency_subprice )) $this -> multicurrency_subprice = 0 ;
if ( empty ( $this -> multicurrency_total_ht )) $this -> multicurrency_total_ht = 0 ;
if ( empty ( $this -> multicurrency_total_tva )) $this -> multicurrency_total_tva = 0 ;
if ( empty ( $this -> multicurrency_total_ttc )) $this -> multicurrency_total_ttc = 0 ;
2016-12-10 12:21:48 +01:00
2017-10-07 13:09:31 +02:00
// if buy price not defined, define buyprice as configured in margin admin
2016-07-08 20:40:25 +02:00
if ( $this -> pa_ht == 0 && $pa_ht_isemptystring )
2015-10-26 20:33:42 +01:00
{
if (( $result = $this -> defineBuyPrice ( $this -> subprice , $this -> remise_percent , $this -> fk_product )) < 0 )
{
return $result ;
}
else
{
$this -> pa_ht = $result ;
}
}
2012-07-20 09:57:50 +02:00
2017-10-07 13:09:31 +02:00
// Check parameters
if ( $this -> product_type < 0 ) return - 1 ;
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
$this -> db -> begin ();
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// Insert line into database
$sql = 'INSERT INTO ' . MAIN_DB_PREFIX . 'propaldet' ;
$sql .= ' (fk_propal, fk_parent_line, label, description, fk_product, product_type,' ;
2016-10-29 21:02:08 +02:00
$sql .= ' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,' ;
2017-10-07 13:09:31 +02:00
$sql .= ' subprice, remise_percent, ' ;
$sql .= ' info_bits, ' ;
$sql .= ' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,' ;
$sql .= ' fk_unit,' ;
$sql .= ' date_start, date_end' ;
2016-01-18 19:45:27 +01:00
$sql .= ', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)' ;
2017-10-07 13:09:31 +02:00
$sql .= " VALUES ( " . $this -> fk_propal . " , " ;
$sql .= " " . ( $this -> fk_parent_line > 0 ? " ' " . $this -> db -> escape ( $this -> fk_parent_line ) . " ' " : " null " ) . " , " ;
$sql .= " " . ( ! empty ( $this -> label ) ? " ' " . $this -> db -> escape ( $this -> label ) . " ' " : " null " ) . " , " ;
$sql .= " ' " . $this -> db -> escape ( $this -> desc ) . " ', " ;
$sql .= " " . ( $this -> fk_product ? " ' " . $this -> db -> escape ( $this -> fk_product ) . " ' " : " null " ) . " , " ;
$sql .= " ' " . $this -> db -> escape ( $this -> product_type ) . " ', " ;
$sql .= " " . ( $this -> fk_remise_except ? " ' " . $this -> db -> escape ( $this -> fk_remise_except ) . " ' " : " null " ) . " , " ;
$sql .= " " . price2num ( $this -> qty ) . " , " ;
$sql .= " " . ( empty ( $this -> vat_src_code ) ? " '' " : " ' " . $this -> db -> escape ( $this -> vat_src_code ) . " ' " ) . " , " ;
$sql .= " " . price2num ( $this -> tva_tx ) . " , " ;
$sql .= " " . price2num ( $this -> localtax1_tx ) . " , " ;
$sql .= " " . price2num ( $this -> localtax2_tx ) . " , " ;
2017-09-15 15:41:07 +02:00
$sql .= " ' " . $this -> db -> escape ( $this -> localtax1_type ) . " ', " ;
$sql .= " ' " . $this -> db -> escape ( $this -> localtax2_type ) . " ', " ;
2018-07-10 11:09:08 +02:00
$sql .= " " . ( price2num ( $this -> subprice ) !== '' ? price2num ( $this -> subprice ) : " null " ) . " , " ;
2017-10-07 13:09:31 +02:00
$sql .= " " . price2num ( $this -> remise_percent ) . " , " ;
$sql .= " " . ( isset ( $this -> info_bits ) ? " ' " . $this -> db -> escape ( $this -> info_bits ) . " ' " : " null " ) . " , " ;
$sql .= " " . price2num ( $this -> total_ht ) . " , " ;
$sql .= " " . price2num ( $this -> total_tva ) . " , " ;
$sql .= " " . price2num ( $this -> total_localtax1 ) . " , " ;
$sql .= " " . price2num ( $this -> total_localtax2 ) . " , " ;
$sql .= " " . price2num ( $this -> total_ttc ) . " , " ;
$sql .= " " . ( ! empty ( $this -> fk_fournprice ) ? " ' " . $this -> db -> escape ( $this -> fk_fournprice ) . " ' " : " null " ) . " , " ;
$sql .= " " . ( isset ( $this -> pa_ht ) ? " ' " . price2num ( $this -> pa_ht ) . " ' " : " null " ) . " , " ;
$sql .= ' ' . $this -> special_code . ',' ;
$sql .= ' ' . $this -> rang . ',' ;
$sql .= ' ' . ( ! $this -> fk_unit ? 'NULL' : $this -> fk_unit ) . ',' ;
$sql .= " " . ( ! empty ( $this -> date_start ) ? " ' " . $this -> db -> idate ( $this -> date_start ) . " ' " : " null " ) . ',' ;
$sql .= " " . ( ! empty ( $this -> date_end ) ? " ' " . $this -> db -> idate ( $this -> date_end ) . " ' " : " null " );
2016-02-16 15:36:54 +01:00
$sql .= " , " . ( $this -> fk_multicurrency > 0 ? $this -> fk_multicurrency : 'null' );
2016-01-18 19:45:27 +01:00
$sql .= " , ' " . $this -> db -> escape ( $this -> multicurrency_code ) . " ' " ;
$sql .= " , " . $this -> multicurrency_subprice ;
$sql .= " , " . $this -> multicurrency_total_ht ;
$sql .= " , " . $this -> multicurrency_total_tva ;
$sql .= " , " . $this -> multicurrency_total_ttc ;
2017-10-07 13:09:31 +02:00
$sql .= ')' ;
dol_syslog ( get_class ( $this ) . '::insert' , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> rowid = $this -> db -> last_insert_id ( MAIN_DB_PREFIX . 'propaldet' );
if ( empty ( $conf -> global -> MAIN_EXTRAFIELDS_DISABLED )) // For avoid conflicts if trigger used
{
$this -> id = $this -> rowid ;
$result = $this -> insertExtraFields ();
if ( $result < 0 )
{
$error ++ ;
}
}
2018-04-10 12:03:01 +02:00
if ( ! $error && ! $notrigger )
2017-10-07 13:09:31 +02:00
{
// Call trigger
$result = $this -> call_trigger ( 'LINEPROPAL_INSERT' , $user );
if ( $result < 0 )
{
$this -> db -> rollback ();
return - 1 ;
}
// End call triggers
}
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Delete line in database
*
2017-12-03 20:51:26 +01:00
* @ param User $user Object user
2017-10-07 13:09:31 +02:00
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
2017-12-03 20:51:26 +01:00
* @ return int < 0 if ko , > 0 if ok
2017-10-07 13:09:31 +02:00
*/
2017-12-06 23:21:58 +01:00
function delete ( User $user , $notrigger = 0 )
2017-10-07 13:09:31 +02:00
{
2017-12-06 23:21:58 +01:00
global $conf ;
2017-10-07 13:09:31 +02:00
$error = 0 ;
$this -> db -> begin ();
$sql = " DELETE FROM " . MAIN_DB_PREFIX . " propaldet WHERE rowid = " . $this -> rowid ;
dol_syslog ( " PropaleLigne::delete " , LOG_DEBUG );
if ( $this -> db -> query ( $sql ) )
{
// Remove extrafields
if (( ! $error ) && ( empty ( $conf -> global -> MAIN_EXTRAFIELDS_DISABLED ))) // For avoid conflicts if trigger used
{
$this -> id = $this -> rowid ;
$result = $this -> deleteExtraFields ();
if ( $result < 0 )
{
$error ++ ;
dol_syslog ( get_class ( $this ) . " ::delete error -4 " . $this -> error , LOG_ERR );
}
}
if ( ! $error && ! $notrigger )
{
// Call trigger
$result = $this -> call_trigger ( 'LINEPROPAL_DELETE' , $user );
if ( $result < 0 )
{
$this -> db -> rollback ();
return - 1 ;
}
}
// End call triggers
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> error () . " sql= " . $sql ;
$this -> db -> rollback ();
return - 1 ;
}
}
/**
* Update propal line object into DB
*
* @ param int $notrigger 1 = Does not execute triggers , 0 = execute triggers
* @ return int < 0 if ko , > 0 if ok
*/
function update ( $notrigger = 0 )
{
global $conf , $user ;
$error = 0 ;
$pa_ht_isemptystring = ( empty ( $this -> pa_ht ) && $this -> pa_ht == '' ); // If true, we can use a default value. If this->pa_ht = '0', we must use '0'.
// Clean parameters
if ( empty ( $this -> tva_tx )) $this -> tva_tx = 0 ;
if ( empty ( $this -> localtax1_tx )) $this -> localtax1_tx = 0 ;
if ( empty ( $this -> localtax2_tx )) $this -> localtax2_tx = 0 ;
if ( empty ( $this -> total_localtax1 )) $this -> total_localtax1 = 0 ;
if ( empty ( $this -> total_localtax2 )) $this -> total_localtax2 = 0 ;
2013-09-10 18:45:16 +02:00
if ( empty ( $this -> localtax1_type )) $this -> localtax1_type = 0 ;
if ( empty ( $this -> localtax2_type )) $this -> localtax2_type = 0 ;
2017-10-07 13:09:31 +02:00
if ( empty ( $this -> marque_tx )) $this -> marque_tx = 0 ;
if ( empty ( $this -> marge_tx )) $this -> marge_tx = 0 ;
if ( empty ( $this -> price )) $this -> price = 0 ; // TODO A virer
if ( empty ( $this -> remise )) $this -> remise = 0 ; // TODO A virer
if ( empty ( $this -> remise_percent )) $this -> remise_percent = 0 ;
if ( empty ( $this -> info_bits )) $this -> info_bits = 0 ;
if ( empty ( $this -> special_code )) $this -> special_code = 0 ;
if ( empty ( $this -> fk_parent_line )) $this -> fk_parent_line = 0 ;
if ( empty ( $this -> fk_fournprice )) $this -> fk_fournprice = 0 ;
if ( empty ( $this -> subprice )) $this -> subprice = 0 ;
2012-08-01 17:36:15 +02:00
if ( empty ( $this -> pa_ht )) $this -> pa_ht = 0 ;
2012-07-20 09:57:50 +02:00
2015-10-26 20:33:42 +01:00
// if buy price not defined, define buyprice as configured in margin admin
2016-07-08 20:40:25 +02:00
if ( $this -> pa_ht == 0 && $pa_ht_isemptystring )
2015-10-26 20:33:42 +01:00
{
if (( $result = $this -> defineBuyPrice ( $this -> subprice , $this -> remise_percent , $this -> fk_product )) < 0 )
{
return $result ;
}
else
{
$this -> pa_ht = $result ;
}
2012-08-01 17:36:15 +02:00
}
2012-07-18 15:15:54 +02:00
2017-10-07 13:09:31 +02:00
$this -> db -> begin ();
2012-03-18 19:23:01 +01:00
2017-10-07 13:09:31 +02:00
// Mise a jour ligne en base
$sql = " UPDATE " . MAIN_DB_PREFIX . " propaldet SET " ;
$sql .= " description=' " . $this -> db -> escape ( $this -> desc ) . " ' " ;
$sql .= " , label= " . ( ! empty ( $this -> label ) ? " ' " . $this -> db -> escape ( $this -> label ) . " ' " : " null " );
$sql .= " , product_type= " . $this -> product_type ;
2016-10-29 21:02:08 +02:00
$sql .= " , vat_src_code = ' " . ( empty ( $this -> vat_src_code ) ? '' : $this -> vat_src_code ) . " ' " ;
2017-10-07 13:09:31 +02:00
$sql .= " , tva_tx=' " . price2num ( $this -> tva_tx ) . " ' " ;
$sql .= " , localtax1_tx= " . price2num ( $this -> localtax1_tx );
$sql .= " , localtax2_tx= " . price2num ( $this -> localtax2_tx );
2017-05-12 15:44:09 +02:00
$sql .= " , localtax1_type=' " . $this -> db -> escape ( $this -> localtax1_type ) . " ' " ;
$sql .= " , localtax2_type=' " . $this -> db -> escape ( $this -> localtax2_type ) . " ' " ;
2017-10-07 13:09:31 +02:00
$sql .= " , qty=' " . price2num ( $this -> qty ) . " ' " ;
$sql .= " , subprice= " . price2num ( $this -> subprice ) . " " ;
$sql .= " , remise_percent= " . price2num ( $this -> remise_percent ) . " " ;
$sql .= " , price= " . price2num ( $this -> price ) . " " ; // TODO A virer
$sql .= " , remise= " . price2num ( $this -> remise ) . " " ; // TODO A virer
$sql .= " , info_bits=' " . $this -> db -> escape ( $this -> info_bits ) . " ' " ;
if ( empty ( $this -> skip_update_total ))
{
$sql .= " , total_ht= " . price2num ( $this -> total_ht ) . " " ;
$sql .= " , total_tva= " . price2num ( $this -> total_tva ) . " " ;
$sql .= " , total_ttc= " . price2num ( $this -> total_ttc ) . " " ;
$sql .= " , total_localtax1= " . price2num ( $this -> total_localtax1 ) . " " ;
$sql .= " , total_localtax2= " . price2num ( $this -> total_localtax2 ) . " " ;
}
2017-09-15 15:41:07 +02:00
$sql .= " , fk_product_fournisseur_price= " . ( ! empty ( $this -> fk_fournprice ) ? " ' " . $this -> db -> escape ( $this -> fk_fournprice ) . " ' " : " null " );
2016-10-29 21:02:08 +02:00
$sql .= " , buy_price_ht= " . price2num ( $this -> pa_ht );
2017-10-07 13:09:31 +02:00
if ( strlen ( $this -> special_code )) $sql .= " , special_code= " . $this -> special_code ;
$sql .= " , fk_parent_line= " . ( $this -> fk_parent_line > 0 ? $this -> fk_parent_line : " null " );
if ( ! empty ( $this -> rang )) $sql .= " , rang= " . $this -> rang ;
$sql .= " , date_start= " . ( ! empty ( $this -> date_start ) ? " ' " . $this -> db -> idate ( $this -> date_start ) . " ' " : " null " );
$sql .= " , date_end= " . ( ! empty ( $this -> date_end ) ? " ' " . $this -> db -> idate ( $this -> date_end ) . " ' " : " null " );
$sql .= " , fk_unit= " . ( ! $this -> fk_unit ? 'NULL' : $this -> fk_unit );
2016-07-08 20:40:25 +02:00
2016-01-21 22:40:07 +01:00
// Multicurrency
2016-10-29 21:02:08 +02:00
$sql .= " , multicurrency_subprice= " . price2num ( $this -> multicurrency_subprice ) . " " ;
2017-10-07 13:09:31 +02:00
$sql .= " , multicurrency_total_ht= " . price2num ( $this -> multicurrency_total_ht ) . " " ;
$sql .= " , multicurrency_total_tva= " . price2num ( $this -> multicurrency_total_tva ) . " " ;
$sql .= " , multicurrency_total_ttc= " . price2num ( $this -> multicurrency_total_ttc ) . " " ;
$sql .= " WHERE rowid = " . $this -> rowid ;
dol_syslog ( get_class ( $this ) . " ::update " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
if ( empty ( $conf -> global -> MAIN_EXTRAFIELDS_DISABLED )) // For avoid conflicts if trigger used
{
$this -> id = $this -> rowid ;
$result = $this -> insertExtraFields ();
if ( $result < 0 )
{
$error ++ ;
}
}
2018-04-10 12:03:01 +02:00
if ( ! $error && ! $notrigger )
2017-10-07 13:09:31 +02:00
{
// Call trigger
$result = $this -> call_trigger ( 'LINEPROPAL_UPDATE' , $user );
if ( $result < 0 )
{
$this -> db -> rollback ();
return - 1 ;
}
// End call triggers
}
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
$this -> db -> rollback ();
return - 2 ;
}
}
/**
* Update DB line fields total_xxx
* Used by migration
*
2018-09-03 17:05:44 +02:00
* @ return int < 0 if KO , > 0 if OK
2017-10-07 13:09:31 +02:00
*/
function update_total ()
{
$this -> db -> begin ();
// Mise a jour ligne en base
$sql = " UPDATE " . MAIN_DB_PREFIX . " propaldet SET " ;
$sql .= " total_ht= " . price2num ( $this -> total_ht , 'MT' ) . " " ;
$sql .= " ,total_tva= " . price2num ( $this -> total_tva , 'MT' ) . " " ;
$sql .= " ,total_ttc= " . price2num ( $this -> total_ttc , 'MT' ) . " " ;
$sql .= " WHERE rowid = " . $this -> rowid ;
dol_syslog ( " PropaleLigne::update_total " , LOG_DEBUG );
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$this -> db -> commit ();
return 1 ;
}
else
{
$this -> error = $this -> db -> error ();
$this -> db -> rollback ();
return - 2 ;
}
}
2008-08-28 01:00:37 +02:00
2003-09-11 18:00:49 +02:00
}
2005-08-11 22:01:25 +02:00