41 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
 
   42 require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobjectline.class.php";
 
   43 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
 
   44 require_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
 
   45 require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
 
   46 require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
 
   47 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
 
   64   public $element = 
'propal';
 
   69   public $table_element = 
'propal';
 
   74   public $table_element_line = 
'propaldet';
 
   79   public $fk_element = 
'fk_propal';
 
   84   public $picto = 
'propal';
 
   90   public $ismultientitymanaged = 1;
 
   96   public $restrictiononfksoc = 1;
 
  145   public $date_creation;
 
  156   public $date_validation;
 
  161   public $date_signature;
 
  166   public $user_signature;
 
  183   public $date_livraison; 
 
  188   public $delivery_date; 
 
  191   public $fin_validite;
 
  193   public $user_author_id;
 
  194   public $user_valid_id;
 
  195   public $user_close_id;
 
  213   public $cond_reglement_code;
 
  214   public $deposit_percent;
 
  215   public $mode_reglement_code;
 
  216   public $remise_percent;
 
  233   public $address_type;
 
  236   public $availability_id;
 
  237   public $availability_code;
 
  239   public $duree_validite;
 
  241   public $demand_reason_id;
 
  242   public $demand_reason_code;
 
  244   public $warehouse_id;
 
  246   public $extraparams = array();
 
  251   public $lines = array();
 
  254   public $labelStatus = array();
 
  255   public $labelStatusShort = array();
 
  261   public $fk_multicurrency;
 
  263   public $multicurrency_code;
 
  264   public $multicurrency_tx;
 
  265   public $multicurrency_total_ht;
 
  266   public $multicurrency_total_tva;
 
  267   public $multicurrency_total_ttc;
 
  298   public $fields = array(
 
  299     'rowid' =>array(
'type'=>
'integer', 
'label'=>
'TechnicalID', 
'enabled'=>1, 
'visible'=>-1, 
'notnull'=>1, 
'position'=>10),
 
  300     'entity' =>array(
'type'=>
'integer', 
'label'=>
'Entity', 
'default'=>1, 
'enabled'=>1, 
'visible'=>-2, 
'notnull'=>1, 
'position'=>15, 
'index'=>1),
 
  301     'ref' =>array(
'type'=>
'varchar(30)', 
'label'=>
'Ref', 
'enabled'=>1, 
'visible'=>-1, 
'notnull'=>1, 
'showoncombobox'=>1, 
'position'=>20),
 
  302     'ref_client' =>array(
'type'=>
'varchar(255)', 
'label'=>
'RefCustomer', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>22),
 
  303     'ref_ext' =>array(
'type'=>
'varchar(255)', 
'label'=>
'RefExt', 
'enabled'=>1, 
'visible'=>0, 
'position'=>40),
 
  304     'fk_soc' =>array(
'type'=>
'integer:Societe:societe/class/societe.class.php', 
'label'=>
'ThirdParty', 
'enabled'=>
'$conf->societe->enabled', 
'visible'=>-1, 
'position'=>23),
 
  305     'fk_projet' =>array(
'type'=>
'integer:Project:projet/class/project.class.php:1:fk_statut=1', 
'label'=>
'Fk projet', 
'enabled'=>
"isModEnabled('project')", 
'visible'=>-1, 
'position'=>24),
 
  306     'tms' =>array(
'type'=>
'timestamp', 
'label'=>
'DateModification', 
'enabled'=>1, 
'visible'=>-1, 
'notnull'=>1, 
'position'=>25),
 
  307     'datec' =>array(
'type'=>
'datetime', 
'label'=>
'DateCreation', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>55),
 
  308     'datep' =>array(
'type'=>
'date', 
'label'=>
'Date', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>60),
 
  309     'fin_validite' =>array(
'type'=>
'datetime', 
'label'=>
'DateEnd', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>65),
 
  310     'date_valid' =>array(
'type'=>
'datetime', 
'label'=>
'DateValidation', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>70),
 
  311     'date_cloture' =>array(
'type'=>
'datetime', 
'label'=>
'DateClosing', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>75),
 
  312     'fk_user_author' =>array(
'type'=>
'integer:User:user/class/user.class.php', 
'label'=>
'Fk user author', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>80),
 
  313     'fk_user_modif' =>array(
'type'=>
'integer:User:user/class/user.class.php', 
'label'=>
'UserModif', 
'enabled'=>1, 
'visible'=>-2, 
'notnull'=>-1, 
'position'=>85),
 
  314     'fk_user_valid' =>array(
'type'=>
'integer:User:user/class/user.class.php', 
'label'=>
'UserValidation', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>90),
 
  315     'fk_user_cloture' =>array(
'type'=>
'integer:User:user/class/user.class.php', 
'label'=>
'Fk user cloture', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>95),
 
  316     'price' =>array(
'type'=>
'double', 
'label'=>
'Price', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>105),
 
  317     'remise_percent' =>array(
'type'=>
'double', 
'label'=>
'RelativeDiscount', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>110),
 
  320     'total_ht' =>array(
'type'=>
'double(24,8)', 
'label'=>
'TotalHT', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>125, 
'isameasure'=>1),
 
  321     'total_tva' =>array(
'type'=>
'double(24,8)', 
'label'=>
'VAT', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>130, 
'isameasure'=>1),
 
  322     'localtax1' =>array(
'type'=>
'double(24,8)', 
'label'=>
'LocalTax1', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>135, 
'isameasure'=>1),
 
  323     'localtax2' =>array(
'type'=>
'double(24,8)', 
'label'=>
'LocalTax2', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>140, 
'isameasure'=>1),
 
  324     'total_ttc' =>array(
'type'=>
'double(24,8)', 
'label'=>
'TotalTTC', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>145, 
'isameasure'=>1),
 
  325     'fk_account' =>array(
'type'=>
'integer', 
'label'=>
'BankAccount', 
'enabled'=>
'$conf->banque->enabled', 
'visible'=>-1, 
'position'=>150),
 
  326     'fk_currency' =>array(
'type'=>
'varchar(3)', 
'label'=>
'Currency', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>155),
 
  327     'fk_cond_reglement' =>array(
'type'=>
'integer', 
'label'=>
'PaymentTerm', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>160),
 
  328     'deposit_percent' =>array(
'type'=>
'varchar(63)', 
'label'=>
'DepositPercent', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>161),
 
  329     'fk_mode_reglement' =>array(
'type'=>
'integer', 
'label'=>
'PaymentMode', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>165),
 
  330     'note_private' =>array(
'type'=>
'text', 
'label'=>
'NotePrivate', 
'enabled'=>1, 
'visible'=>0, 
'position'=>170),
 
  331     'note_public' =>array(
'type'=>
'text', 
'label'=>
'NotePublic', 
'enabled'=>1, 
'visible'=>0, 
'position'=>175),
 
  332     'model_pdf' =>array(
'type'=>
'varchar(255)', 
'label'=>
'PDFTemplate', 
'enabled'=>1, 
'visible'=>0, 
'position'=>180),
 
  333     'date_livraison' =>array(
'type'=>
'date', 
'label'=>
'DateDeliveryPlanned', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>185),
 
  334     'fk_shipping_method' =>array(
'type'=>
'integer', 
'label'=>
'ShippingMethod', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>190),
 
  335     'fk_warehouse' =>array(
'type'=>
'integer:Entrepot:product/stock/class/entrepot.class.php', 
'label'=>
'Fk warehouse', 
'enabled'=>
'$conf->stock->enabled', 
'visible'=>-1, 
'position'=>191),
 
  336     'fk_availability' =>array(
'type'=>
'integer', 
'label'=>
'Availability', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>195),
 
  337     'fk_delivery_address' =>array(
'type'=>
'integer', 
'label'=>
'DeliveryAddress', 
'enabled'=>1, 
'visible'=>0, 
'position'=>200), 
 
  338     'fk_input_reason' =>array(
'type'=>
'integer', 
'label'=>
'InputReason', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>205),
 
  339     'extraparams' =>array(
'type'=>
'varchar(255)', 
'label'=>
'Extraparams', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>215),
 
  340     'fk_incoterms' =>array(
'type'=>
'integer', 
'label'=>
'IncotermCode', 
'enabled'=>
'$conf->incoterm->enabled', 
'visible'=>-1, 
'position'=>220),
 
  341     'location_incoterms' =>array(
'type'=>
'varchar(255)', 
'label'=>
'IncotermLabel', 
'enabled'=>
'$conf->incoterm->enabled', 
'visible'=>-1, 
'position'=>225),
 
  342     'fk_multicurrency' =>array(
'type'=>
'integer', 
'label'=>
'MulticurrencyID', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>230),
 
  343     'multicurrency_code' =>array(
'type'=>
'varchar(255)', 
'label'=>
'MulticurrencyCurrency', 
'enabled'=>
'isModEnabled("multicurrency")', 
'visible'=>-1, 
'position'=>235),
 
  344     'multicurrency_tx' =>array(
'type'=>
'double(24,8)', 
'label'=>
'MulticurrencyRate', 
'enabled'=>
'isModEnabled("multicurrency")', 
'visible'=>-1, 
'position'=>240, 
'isameasure'=>1),
 
  345     'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)', 
'label'=>
'MulticurrencyAmountHT', 
'enabled'=>
'isModEnabled("multicurrency")', 
'visible'=>-1, 
'position'=>245, 
'isameasure'=>1),
 
  346     'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)', 
'label'=>
'MulticurrencyAmountVAT', 
'enabled'=>
'isModEnabled("multicurrency")', 
'visible'=>-1, 
'position'=>250, 
'isameasure'=>1),
 
  347     'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)', 
'label'=>
'MulticurrencyAmountTTC', 
'enabled'=>
'isModEnabled("multicurrency")', 
'visible'=>-1, 
'position'=>255, 
'isameasure'=>1),
 
  348     'last_main_doc' =>array(
'type'=>
'varchar(255)', 
'label'=>
'LastMainDoc', 
'enabled'=>1, 
'visible'=>-1, 
'position'=>260),
 
  349     'fk_statut' =>array(
'type'=>
'smallint(6)', 
'label'=>
'Status', 
'enabled'=>1, 
'visible'=>-1, 
'notnull'=>1, 
'position'=>500),
 
  350     'import_key' =>array(
'type'=>
'varchar(14)', 
'label'=>
'ImportId', 
'enabled'=>1, 
'visible'=>-2, 
'position'=>900),
 
  385     global $conf, $langs;
 
  389     $this->socid = $socid;
 
  390     $this->
id = $propalid;
 
  392     $this->duree_validite = 
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
 
  408   public function add_product($idproduct, $qty, $remise_percent = 0)
 
  411     global $conf, $mysoc;
 
  417     dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
 
  418     if ($idproduct > 0) {
 
  420       $prod->fetch($idproduct);
 
  422       $productdesc = $prod->description;
 
  426       if (empty($tva_tx)) {
 
  431       $localtax1_tx = 
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
 
  432       $localtax2_tx = 
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
 
  435       if ($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
 
  436         $price = $prod->multiprices[$this->thirdparty->price_level];
 
  443       $line->fk_product = $idproduct;
 
  444       $line->desc = $productdesc;
 
  447       $line->remise_percent = $remise_percent;
 
  448       $line->vat_src_code = $vat_src_code;
 
  449       $line->tva_tx = $tva_tx;
 
  450       $line->fk_unit = $prod->fk_unit;
 
  452         $line->info_bits = 1;
 
  455       $this->lines[] = $line;
 
  473     include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
 
  474     include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
 
  479     $result = 
$remise->fetch($idremise);
 
  483         $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
 
  484         $this->
db->rollback();
 
  490       $this->line->context = $this->context;
 
  492       $line->fk_propal = $this->id;
 
  493       $line->fk_remise_except = 
$remise->id;
 
  494       $line->desc = 
$remise->description; 
 
  495       $line->vat_src_code = 
$remise->vat_src_code;
 
  496       $line->tva_tx = 
$remise->tva_tx;
 
  497       $line->subprice = -
$remise->amount_ht;
 
  498       $line->fk_product = 0; 
 
  500       $line->remise_percent = 0;
 
  502       $line->info_bits = 2;
 
  505       $line->price = -
$remise->amount_ht;
 
  507       $line->total_ht  = -
$remise->amount_ht;
 
  508       $line->total_tva = -
$remise->amount_tva;
 
  509       $line->total_ttc = -
$remise->amount_ttc;
 
  511       $result = $line->insert();
 
  518           $this->
db->rollback();
 
  522         $this->error = $line->error;
 
  523         $this->errors = $line->errors;
 
  524         $this->
db->rollback();
 
  528       $this->
db->rollback();
 
  570   public 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, $noupdateafterinsertline = 0)
 
  572     global $mysoc, $conf, $langs;
 
  574     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);
 
  576     if ($this->statut == self::STATUS_DRAFT) {
 
  577       include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
 
  580       if (empty($remise_percent)) {
 
  586       if (empty($info_bits)) {
 
  592       if (empty($fk_parent_line) || $fk_parent_line < 0) {
 
  596       $remise_percent = 
price2num($remise_percent);
 
  599       $pu_ht_devise = 
price2num($pu_ht_devise);
 
  601       if (!preg_match(
'/\((.*)\)/', $txtva)) {
 
  607       if ($price_base_type == 
'HT') {
 
  618       if ($date_start && $date_end && $date_start > $date_end) {
 
  619         $langs->load(
"errors");
 
  620         $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
 
  626       $product_type = $type;
 
  627       if (!empty($fk_product) && $fk_product > 0) {
 
  629         $result = $product->fetch($fk_product);
 
  630         $product_type = $product->type;
 
  632         if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL) && $product_type == 0 && $product->stock_reel < $qty) {
 
  633           $langs->load(
"errors");
 
  634           $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
 
  635           $this->
db->rollback();
 
  651       if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
 
  652         $vat_src_code = $reg[1];
 
  653         $txtva = preg_replace(
'/\s*\(.*\)/', 
'', $txtva); 
 
  656       $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);
 
  658       $total_ht  = $tabprice[0];
 
  659       $total_tva = $tabprice[1];
 
  660       $total_ttc = $tabprice[2];
 
  661       $total_localtax1 = $tabprice[9];
 
  662       $total_localtax2 = $tabprice[10];
 
  663       $pu_ht  = $tabprice[3];
 
  664       $pu_tva = $tabprice[4];
 
  665       $pu_ttc = $tabprice[5];
 
  668       $multicurrency_total_ht  = $tabprice[16];
 
  669       $multicurrency_total_tva = $tabprice[17];
 
  670       $multicurrency_total_ttc = $tabprice[18];
 
  671       $pu_ht_devise = $tabprice[19];
 
  675       if ($ranktouse == -1) {
 
  676         $rangmax = $this->
line_max($fk_parent_line);
 
  677         $ranktouse = $rangmax + 1;
 
  684       if ($remise_percent > 0) {
 
  685         $remise = round(($pu * $remise_percent / 100), 2);
 
  692       $this->line->context = $this->context;
 
  694       $this->line->fk_propal = $this->id;
 
  695       $this->line->label = $label;
 
  696       $this->line->desc = $desc;
 
  697       $this->line->qty = $qty;
 
  699       $this->line->vat_src_code = $vat_src_code;
 
  700       $this->line->tva_tx = $txtva;
 
  701       $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
 
  702       $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
 
  703       $this->line->localtax1_type = empty($localtaxes_type[0]) ? 
'' : $localtaxes_type[0];
 
  704       $this->line->localtax2_type = empty($localtaxes_type[2]) ? 
'' : $localtaxes_type[2];
 
  705       $this->line->fk_product = $fk_product;
 
  706       $this->line->product_type = $type;
 
  707       $this->line->fk_remise_except = $fk_remise_except;
 
  708       $this->line->remise_percent = $remise_percent;
 
  709       $this->line->subprice = $pu_ht;
 
  710       $this->line->rang = $ranktouse;
 
  711       $this->line->info_bits = $info_bits;
 
  712       $this->line->total_ht = $total_ht;
 
  713       $this->line->total_tva = $total_tva;
 
  714       $this->line->total_localtax1 = $total_localtax1;
 
  715       $this->line->total_localtax2 = $total_localtax2;
 
  716       $this->line->total_ttc = $total_ttc;
 
  717       $this->line->special_code = $special_code;
 
  718       $this->line->fk_parent_line = $fk_parent_line;
 
  719       $this->line->fk_unit = $fk_unit;
 
  721       $this->line->date_start = $date_start;
 
  722       $this->line->date_end = $date_end;
 
  724       $this->line->fk_fournprice = $fk_fournprice;
 
  725       $this->line->pa_ht = $pa_ht;
 
  727       $this->line->origin_id = $origin_id;
 
  728       $this->line->origin = $origin;
 
  731       $this->line->fk_multicurrency = $this->fk_multicurrency;
 
  732       $this->line->multicurrency_code = $this->multicurrency_code;
 
  733       $this->line->multicurrency_subprice   = $pu_ht_devise;
 
  734       $this->line->multicurrency_total_ht   = $multicurrency_total_ht;
 
  735       $this->line->multicurrency_total_tva  = $multicurrency_total_tva;
 
  736       $this->line->multicurrency_total_ttc  = $multicurrency_total_ttc;
 
  739       if (empty($qty) && empty($special_code)) {
 
  740         $this->line->special_code = 3;
 
  744       $this->line->price = 
$price;
 
  746       if (is_array($array_options) && count($array_options) > 0) {
 
  747         $this->line->array_options = $array_options;
 
  750       $result = $this->line->insert();
 
  753         if (!empty($fk_parent_line)) {
 
  755         } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) { 
 
  756           $linecount = count($this->lines);
 
  757           for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
 
  763         if (empty($noupdateafterinsertline)) {
 
  769           return $this->line->id;
 
  771           $this->error = $this->
db->error();
 
  772           $this->
db->rollback();
 
  776         $this->error = $this->line->error;
 
  777         $this->errors = $this->line->errors;
 
  778         $this->
db->rollback();
 
  782       dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
 
  817   public 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, $rang = 0)
 
  819     global $mysoc, $langs;
 
  821     dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent, 
  822         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");
 
  823     include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
 
  826     $remise_percent = 
price2num($remise_percent);
 
  829     $pu_ht_devise = 
price2num($pu_ht_devise);
 
  830     if (!preg_match(
'/\((.*)\)/', $txtva)) {
 
  836     if (empty($qty) && empty($special_code)) {
 
  839     if (!empty($qty) && $special_code == 3) {
 
  846     if ($date_start && $date_end && $date_start > $date_end) {
 
  847       $langs->load(
"errors");
 
  848       $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
 
  852     if ($this->statut == self::STATUS_DRAFT) {
 
  865       if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
 
  866         $vat_src_code = $reg[1];
 
  867         $txtva = preg_replace(
'/\s*\(.*\)/', 
'', $txtva); 
 
  870       $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);
 
  871       $total_ht  = $tabprice[0];
 
  872       $total_tva = $tabprice[1];
 
  873       $total_ttc = $tabprice[2];
 
  874       $total_localtax1 = $tabprice[9];
 
  875       $total_localtax2 = $tabprice[10];
 
  876       $pu_ht  = $tabprice[3];
 
  877       $pu_tva = $tabprice[4];
 
  878       $pu_ttc = $tabprice[5];
 
  881       $multicurrency_total_ht  = $tabprice[16];
 
  882       $multicurrency_total_tva = $tabprice[17];
 
  883       $multicurrency_total_ttc = $tabprice[18];
 
  884       $pu_ht_devise = $tabprice[19];
 
  889       if ($remise_percent > 0) {
 
  890         $remise = round(($pu * $remise_percent / 100), 2);
 
  896       $line->fetch($rowid);
 
  898       $staticline = clone $line;
 
  900       $line->oldline = $staticline;
 
  902       $this->line->context = $this->context;
 
  903       $this->line->rang = $rang;
 
  906       if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
 
  907         $rangmax = $this->
line_max($fk_parent_line);
 
  908         $this->line->rang = $rangmax + 1;
 
  911       $this->line->id = $rowid;
 
  912       $this->line->label = $label;
 
  913       $this->line->desc = $desc;
 
  914       $this->line->qty = $qty;
 
  915       $this->line->product_type   = $type;
 
  916       $this->line->vat_src_code   = $vat_src_code;
 
  917       $this->line->tva_tx = $txtva;
 
  918       $this->line->localtax1_tx   = $txlocaltax1;
 
  919       $this->line->localtax2_tx   = $txlocaltax2;
 
  920       $this->line->localtax1_type   = $localtaxes_type[0];
 
  921       $this->line->localtax2_type   = $localtaxes_type[2];
 
  922       $this->line->remise_percent   = $remise_percent;
 
  923       $this->line->subprice     = $pu_ht;
 
  924       $this->line->info_bits      = $info_bits;
 
  926       $this->line->total_ht     = $total_ht;
 
  927       $this->line->total_tva      = $total_tva;
 
  928       $this->line->total_localtax1  = $total_localtax1;
 
  929       $this->line->total_localtax2  = $total_localtax2;
 
  930       $this->line->total_ttc      = $total_ttc;
 
  931       $this->line->special_code = $special_code;
 
  932       $this->line->fk_parent_line   = $fk_parent_line;
 
  933       $this->line->skip_update_total = $skip_update_total;
 
  934       $this->line->fk_unit = $fk_unit;
 
  936       $this->line->fk_fournprice = $fk_fournprice;
 
  937       $this->line->pa_ht = $pa_ht;
 
  939       $this->line->date_start = $date_start;
 
  940       $this->line->date_end = $date_end;
 
  942       if (is_array($array_options) && count($array_options) > 0) {
 
  944         foreach ($array_options as $key => $value) {
 
  945           $this->line->array_options[$key] = $array_options[$key];
 
  950       $this->line->multicurrency_subprice   = $pu_ht_devise;
 
  951       $this->line->multicurrency_total_ht   = $multicurrency_total_ht;
 
  952       $this->line->multicurrency_total_tva  = $multicurrency_total_tva;
 
  953       $this->line->multicurrency_total_ttc  = $multicurrency_total_ttc;
 
  955       $result = $this->line->update($notrigger);
 
  958         if (!empty($fk_parent_line)) {
 
  964         $this->fk_propal = $this->id;
 
  965         $this->
rowid = $rowid;
 
  970         $this->error = $this->line->error;
 
  971         $this->errors = $this->line->errors;
 
  972         $this->
db->rollback();
 
  976       dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
 
  993     if ($this->statut == self::STATUS_DRAFT) {
 
  998       $line->context = $this->context;
 
 1001       $line->fetch($lineid);
 
 1003       if ($id > 0 && $line->fk_propal != $id) {
 
 1004         $this->error = 
'ErrorLineIDDoesNotMatchWithObjectID';
 
 1009       $staticline = clone $line;
 
 1010       $line->oldline = $staticline;
 
 1012       if ($line->delete($user) > 0) {
 
 1015         $this->
db->commit();
 
 1018         $this->error = $line->error;
 
 1019         $this->errors = $line->errors;
 
 1020         $this->
db->rollback();
 
 1024       $this->error = 
'ErrorDeleteLineNotAllowedByObjectStatus';
 
 1038   public function create($user, $notrigger = 0)
 
 1040     global $conf, $hookmanager, $mysoc;
 
 1046     if (empty($this->date)) {
 
 1049     $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
 
 1050     if (empty($this->availability_id)) {
 
 1051       $this->availability_id = 0;
 
 1053     if (empty($this->demand_reason_id)) {
 
 1054       $this->demand_reason_id = 0;
 
 1058     if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
 
 1063     if (empty($this->fk_multicurrency)) {
 
 1064       $this->multicurrency_code = $conf->currency;
 
 1065       $this->fk_multicurrency = 0;
 
 1066       $this->multicurrency_tx = 1;
 
 1070     $delivery_date = empty($this->delivery_date) ? $this->date_livraison : $this->delivery_date;
 
 1077       $this->error = 
"Failed to fetch company";
 
 1078       dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
 
 1083     if (!empty($this->
ref)) { 
 
 1086         $this->error = 
'ErrorRefAlreadyExists';
 
 1087         dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
 
 1088         $this->
db->rollback();
 
 1093     if (empty($this->date)) {
 
 1094       $this->error = 
"Date of proposal is required";
 
 1095       dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
 
 1103     $sql = 
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
 
 1107     $sql .= 
", remise_percent";
 
 1108     $sql .= 
", remise_absolue";
 
 1109     $sql .= 
", total_tva";
 
 1110     $sql .= 
", total_ttc";
 
 1114     $sql .= 
", fk_user_author";
 
 1115     $sql .= 
", note_private";
 
 1116     $sql .= 
", note_public";
 
 1117     $sql .= 
", model_pdf";
 
 1118     $sql .= 
", fin_validite";
 
 1119     $sql .= 
", fk_cond_reglement";
 
 1120     $sql .= 
", deposit_percent";
 
 1121     $sql .= 
", fk_mode_reglement";
 
 1122     $sql .= 
", fk_account";
 
 1123     $sql .= 
", ref_client";
 
 1124     $sql .= 
", ref_ext";
 
 1125     $sql .= 
", date_livraison";
 
 1126     $sql .= 
", fk_shipping_method";
 
 1127     $sql .= 
", fk_warehouse";
 
 1128     $sql .= 
", fk_availability";
 
 1129     $sql .= 
", fk_input_reason";
 
 1130     $sql .= 
", fk_projet";
 
 1131     $sql .= 
", fk_incoterms";
 
 1132     $sql .= 
", location_incoterms";
 
 1134     $sql .= 
", fk_multicurrency";
 
 1135     $sql .= 
", multicurrency_code";
 
 1136     $sql .= 
", multicurrency_tx";
 
 1138     $sql .= 
" VALUES (";
 
 1139     $sql .= $this->socid;
 
 1141     $sql .= 
", ".((float) $this->remise);                       
 
 1142     $sql .= 
", ".($this->remise_percent ? ((
float) $this->remise_percent) : 
'NULL');
 
 1143     $sql .= 
", ".($this->remise_absolue ? ((
float) $this->remise_absolue) : 
'NULL');  
 
 1146     $sql .= 
", '".$this->db->idate($this->date).
"'";
 
 1147     $sql .= 
", '".$this->db->idate($now).
"'";
 
 1148     $sql .= 
", '(PROV)'";
 
 1149     $sql .= 
", ".($user->id > 0 ? ((int) $user->id) : 
"NULL");
 
 1150     $sql .= 
", '".$this->db->escape($this->note_private).
"'";
 
 1151     $sql .= 
", '".$this->db->escape($this->note_public).
"'";
 
 1152     $sql .= 
", '".$this->db->escape($this->model_pdf).
"'";
 
 1153     $sql .= 
", ".($this->fin_validite != 
'' ? 
"'".$this->db->idate($this->fin_validite).
"'" : 
"NULL");
 
 1154     $sql .= 
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) : 
'NULL');
 
 1155     $sql .= 
", ".(!empty($this->deposit_percent) ? 
"'".$this->db->escape($this->deposit_percent).
"'" : 
'NULL');
 
 1156     $sql .= 
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) : 
'NULL');
 
 1157     $sql .= 
", ".($this->fk_account > 0 ? ((int) $this->fk_account) : 
'NULL');
 
 1158     $sql .= 
", '".$this->db->escape($this->ref_client).
"'";
 
 1159     $sql .= 
", '".$this->db->escape($this->ref_ext).
"'";
 
 1160     $sql .= 
", ".(empty($delivery_date) ? 
"NULL" : 
"'".$this->db->idate($delivery_date).
"'");
 
 1161     $sql .= 
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id : 
'NULL');
 
 1162     $sql .= 
", ".($this->warehouse_id > 0 ? $this->warehouse_id : 
'NULL');
 
 1163     $sql .= 
", ".$this->availability_id;
 
 1164     $sql .= 
", ".$this->demand_reason_id;
 
 1165     $sql .= 
", ".($this->fk_project ? $this->fk_project : 
"null");
 
 1166     $sql .= 
", ".(int) $this->fk_incoterms;
 
 1167     $sql .= 
", '".$this->db->escape($this->location_incoterms).
"'";
 
 1168     $sql .= 
", ".setEntity($this);
 
 1169     $sql .= 
", ".(int) $this->fk_multicurrency;
 
 1170     $sql .= 
", '".$this->db->escape($this->multicurrency_code).
"'";
 
 1171     $sql .= 
", ".(double) $this->multicurrency_tx;
 
 1174     dol_syslog(get_class($this).
"::create", LOG_DEBUG);
 
 1177       $this->
id = $this->
db->last_insert_id(MAIN_DB_PREFIX.
"propal");
 
 1180         $this->
ref = 
'(PROV'.$this->id.
')';
 
 1181         $sql = 
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->
db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
 
 1183         dol_syslog(get_class($this).
"::create", LOG_DEBUG);
 
 1189         if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {  
 
 1190           $this->linked_objects = $this->linkedObjectsIds; 
 
 1194         if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
 
 1195           foreach ($this->linked_objects as $origin => $tmp_origin_id) {
 
 1196             if (is_array($tmp_origin_id)) {       
 
 1197               foreach ($tmp_origin_id as $origin_id) {
 
 1200                   $this->error = $this->
db->lasterror();
 
 1206               $origin_id = $tmp_origin_id;
 
 1209                 $this->error = $this->
db->lasterror();
 
 1221           $fk_parent_line = 0;
 
 1222           $num = count($this->lines);
 
 1224           for ($i = 0; $i < $num; $i++) {
 
 1225             if (!is_object($this->lines[$i])) { 
 
 1227               $line = (object) $this->lines[$i];
 
 1229               $line = $this->lines[$i];
 
 1232             if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
 
 1233               $fk_parent_line = 0;
 
 1236             $vatrate = $line->tva_tx;
 
 1237             if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
 
 1238               $vatrate .= 
' ('.$line->vat_src_code.
')';
 
 1241             if (!empty($conf->global->MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION)) {
 
 1242               $originid = $line->origin_id;
 
 1243               $origintype = $line->origin;
 
 1245               $originid = $line->id;
 
 1246               $origintype = $this->element;
 
 1254               $line->localtax1_tx,
 
 1255               $line->localtax2_tx,
 
 1257               $line->remise_percent,
 
 1261               $line->product_type,
 
 1263               $line->special_code,
 
 1265               $line->fk_fournprice,
 
 1270               $line->array_options,
 
 1281               $this->error = $this->
db->error;
 
 1286             if ($result > 0 && $line->product_type == 9) {
 
 1287               $fk_parent_line = $result;
 
 1317             if (!$error && !$notrigger) {
 
 1326             $this->error = $this->
db->lasterror();
 
 1331         $this->error = $this->
db->lasterror();
 
 1336         $this->
db->commit();
 
 1337         dol_syslog(get_class($this).
"::create done id=".$this->
id);
 
 1340         $this->
db->rollback();
 
 1344       $this->error = $this->
db->lasterror();
 
 1345       $this->
db->rollback();
 
 1361     global $conf, $hookmanager, $mysoc;
 
 1370     $object = 
new self($this->db);
 
 1375     $object->fetch($this->
id);
 
 1380     if (!empty($socid) && $socid != $object->socid) {
 
 1381       if ($objsoc->fetch($socid) > 0) {
 
 1382         $object->socid = $objsoc->id;
 
 1383         $object->cond_reglement_id  = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
 
 1384         $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent : 
null);
 
 1385         $object->mode_reglement_id  = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
 
 1386         $object->fk_delivery_address = 
'';
 
 1398         $object->fk_project = 
''; 
 
 1402       $object->ref_client = 
'';
 
 1406       $objsoc->fetch($object->socid);
 
 1410     if ($update_prices === 
true) {
 
 1411       if ($objsoc->id > 0 && !empty($object->lines)) {
 
 1412         if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
 
 1414           require_once DOL_DOCUMENT_ROOT . 
'/product/class/productcustomerprice.class.php';
 
 1417         foreach ($object->lines as $line) {
 
 1418           if ($line->fk_product > 0) {
 
 1420             $res = $prod->fetch($line->fk_product);
 
 1422               $pu_ht = $prod->price;
 
 1424               $remise_percent = $objsoc->remise_percent;
 
 1426               if (!empty($conf->global->PRODUIT_MULTIPRICES) && $objsoc->price_level > 0) {
 
 1427                 $pu_ht = $prod->multiprices[$objsoc->price_level];
 
 1428                 if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) {  
 
 1429                   if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
 
 1430                     $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
 
 1433               } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
 
 1435                 $filter = array(
't.fk_product' => $prod->id, 
't.fk_soc' => $objsoc->id);
 
 1436                 $result = $prodcustprice->fetchAll(
'', 
'', 0, 0, $filter);
 
 1439                   if (count($prodcustprice->lines) > 0) {
 
 1440                     $pu_ht = 
price($prodcustprice->lines[0]->price);
 
 1441                     $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
 
 1442                     if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
 
 1443                       $tva_tx .= 
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
 
 1449               $line->subprice = $pu_ht;
 
 1450               $line->tva_tx = $tva_tx;
 
 1451               $line->remise_percent = $remise_percent;
 
 1460     $object->entity = (!empty($forceentity) ? $forceentity : $object->entity);
 
 1464     $object->user_author = $user->id;
 
 1465     $object->user_valid = 0;
 
 1466     $object->date = $now;
 
 1467     $object->datep = $now; 
 
 1468     $object->fin_validite = $object->date + ($object->duree_validite * 24 * 3600);
 
 1469     if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) {
 
 1470       $object->ref_client = 
'';
 
 1472     if ($conf->global->MAIN_DONT_KEEP_NOTE_ON_CLONING == 1) {
 
 1473       $object->note_private = 
'';
 
 1474       $object->note_public = 
'';
 
 1477     $object->context[
'createfromclone'] = 
'createfromclone';
 
 1478     $result = $object->create($user);
 
 1480       $this->error = $object->error;
 
 1481       $this->errors = array_merge($this->errors, $object->errors);
 
 1487       if ($object->copy_linked_contact($this, 
'internal') < 0) {
 
 1494       if ($this->socid == $object->socid) {
 
 1495         if ($object->copy_linked_contact($this, 
'external') < 0) {
 
 1503       if (is_object($hookmanager)) {
 
 1504         $parameters = array(
'objFrom'=>$this, 
'clonedObj'=>$object);
 
 1506         $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action); 
 
 1513     unset($object->context[
'createfromclone']);
 
 1517       $this->
db->commit();
 
 1520       $this->
db->rollback();
 
 1534   public function fetch($rowid, $ref = 
'', $ref_ext = 
'', $forceentity = 0)
 
 1536     $sql = 
"SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc";
 
 1537     $sql .= 
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
 
 1538     $sql .= 
", p.datec";
 
 1539     $sql .= 
", p.date_signature as dates";
 
 1540     $sql .= 
", p.date_valid as datev";
 
 1541     $sql .= 
", p.datep as dp";
 
 1542     $sql .= 
", p.fin_validite as dfv";
 
 1543     $sql .= 
", p.date_livraison as delivery_date";
 
 1544     $sql .= 
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
 
 1545     $sql .= 
", p.note_private, p.note_public";
 
 1546     $sql .= 
", p.fk_projet as fk_project, p.fk_statut";
 
 1547     $sql .= 
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
 
 1548     $sql .= 
", p.fk_delivery_address";
 
 1549     $sql .= 
", p.fk_availability";
 
 1550     $sql .= 
", p.fk_input_reason";
 
 1551     $sql .= 
", p.fk_cond_reglement";
 
 1552     $sql .= 
", p.fk_mode_reglement";
 
 1553     $sql .= 
', p.fk_account';
 
 1554     $sql .= 
", p.fk_shipping_method";
 
 1555     $sql .= 
", p.fk_warehouse";
 
 1556     $sql .= 
", p.fk_incoterms, p.location_incoterms";
 
 1557     $sql .= 
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
 
 1558     $sql .= 
", p.tms as date_modification";
 
 1559     $sql .= 
", i.libelle as label_incoterms";
 
 1560     $sql .= 
", c.label as statut_label";
 
 1561     $sql .= 
", ca.code as availability_code, ca.label as availability";
 
 1562     $sql .= 
", dr.code as demand_reason_code, dr.label as demand_reason";
 
 1563     $sql .= 
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
 
 1564     $sql .= 
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
 
 1565     $sql .= 
" FROM ".MAIN_DB_PREFIX.
"propal as p";
 
 1566     $sql .= 
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
 
 1567     $sql .= 
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
 
 1568     $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').
')';
 
 1569     $sql .= 
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
 
 1570     $sql .= 
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
 
 1571     $sql .= 
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
 
 1574       if (!empty($forceentity)) {
 
 1575         $sql .= 
" WHERE p.entity = ".(int) $forceentity; 
 
 1577         $sql .= 
" WHERE p.entity IN (".getEntity(
'propal').
")";
 
 1579       $sql .= 
" AND p.ref='".$this->db->escape($ref).
"'";
 
 1582       $sql .= 
" WHERE p.rowid = ".((int) $rowid);
 
 1585     dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
 
 1589         $obj = $this->
db->fetch_object(
$resql);
 
 1591         $this->
id                   = $obj->rowid;
 
 1592         $this->entity               = $obj->entity;
 
 1594         $this->
ref                  = $obj->ref;
 
 1595         $this->ref_client           = $obj->ref_client;
 
 1596         $this->ref_ext           = $obj->ref_ext;
 
 1597         $this->remise               = $obj->remise;
 
 1598         $this->remise_percent       = $obj->remise_percent;
 
 1599         $this->remise_absolue       = $obj->remise_absolue;
 
 1600         $this->total                = $obj->total_ttc; 
 
 1601         $this->total_ttc            = $obj->total_ttc;
 
 1602         $this->total_ht             = $obj->total_ht;
 
 1603         $this->total_tva            = $obj->total_tva;
 
 1604         $this->total_localtax1    = $obj->localtax1;
 
 1605         $this->total_localtax2    = $obj->localtax2;
 
 1607         $this->socid = $obj->fk_soc;
 
 1608         $this->thirdparty = 
null; 
 
 1610         $this->fk_project = $obj->fk_project;
 
 1611         $this->project = 
null; 
 
 1613         $this->model_pdf            = $obj->model_pdf;
 
 1614         $this->modelpdf             = $obj->model_pdf; 
 
 1615         $this->last_main_doc = $obj->last_main_doc;
 
 1616         $this->note                 = $obj->note_private; 
 
 1617         $this->note_private         = $obj->note_private;
 
 1618         $this->note_public          = $obj->note_public;
 
 1620         $this->status               = (int) $obj->fk_statut;
 
 1621         $this->statut               = $this->status; 
 
 1622         $this->statut_libelle       = $obj->statut_label;
 
 1624         $this->datec                = $this->db->jdate($obj->datec); 
 
 1625         $this->datev                = $this->
db->jdate($obj->datev); 
 
 1626         $this->date_creation = $this->
db->jdate($obj->datec); 
 
 1627         $this->date_validation = $this->
db->jdate($obj->datev); 
 
 1628         $this->date_modification = $this->
db->jdate($obj->date_modification); 
 
 1629         $this->date_signature = $this->
db->jdate($obj->dates); 
 
 1630         $this->date                 = $this->
db->jdate($obj->dp); 
 
 1631         $this->datep                = $this->
db->jdate($obj->dp); 
 
 1632         $this->fin_validite         = $this->
db->jdate($obj->dfv);
 
 1633         $this->date_livraison       = $this->
db->jdate($obj->delivery_date); 
 
 1634         $this->delivery_date        = $this->
db->jdate($obj->delivery_date);
 
 1635         $this->shipping_method_id   = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method : 
null;
 
 1636         $this->warehouse_id         = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse : 
null;
 
 1637         $this->availability_id      = $obj->fk_availability;
 
 1638         $this->availability_code    = $obj->availability_code;
 
 1640         $this->demand_reason_id     = $obj->fk_input_reason;
 
 1641         $this->demand_reason_code   = $obj->demand_reason_code;
 
 1643         $this->fk_address = $obj->fk_delivery_address;
 
 1645         $this->mode_reglement_id    = $obj->fk_mode_reglement;
 
 1646         $this->mode_reglement_code  = $obj->mode_reglement_code;
 
 1647         $this->mode_reglement       = $obj->mode_reglement;
 
 1648         $this->fk_account           = ($obj->fk_account > 0) ? $obj->fk_account : 
null;
 
 1649         $this->cond_reglement_id    = $obj->fk_cond_reglement;
 
 1650         $this->cond_reglement_code  = $obj->cond_reglement_code;
 
 1651         $this->cond_reglement       = $obj->cond_reglement;
 
 1652         $this->cond_reglement_doc   = $obj->cond_reglement_libelle_doc;
 
 1653         $this->deposit_percent      = $obj->deposit_percent;
 
 1655         $this->extraparams = (array) json_decode($obj->extraparams, 
true);
 
 1657         $this->user_author_id = $obj->fk_user_author;
 
 1658         $this->user_valid_id = $obj->fk_user_valid;
 
 1659         $this->user_close_id = $obj->fk_user_cloture;
 
 1662         $this->fk_incoterms = $obj->fk_incoterms;
 
 1663         $this->location_incoterms = $obj->location_incoterms;
 
 1664         $this->label_incoterms = $obj->label_incoterms;
 
 1667         $this->fk_multicurrency     = $obj->fk_multicurrency;
 
 1668         $this->multicurrency_code = $obj->multicurrency_code;
 
 1669         $this->multicurrency_tx     = $obj->multicurrency_tx;
 
 1670         $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
 
 1671         $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
 
 1672         $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
 
 1674         if ($obj->fk_statut == self::STATUS_DRAFT) {
 
 1675           $this->brouillon = 1;
 
 1684         $this->lines = array();
 
 1695       $this->error = 
"Record Not Found";
 
 1698       $this->error = $this->
db->lasterror();
 
 1717     if (isset($this->
ref)) {
 
 1718       $this->
ref = trim($this->
ref);
 
 1720     if (isset($this->ref_client)) {
 
 1721       $this->ref_client = trim($this->ref_client);
 
 1723     if (isset($this->note) || isset($this->note_private)) {
 
 1724       $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
 
 1726     if (isset($this->note_public)) {
 
 1727       $this->note_public = trim($this->note_public);
 
 1729     if (isset($this->model_pdf)) {
 
 1730       $this->model_pdf = trim($this->model_pdf);
 
 1732     if (isset($this->import_key)) {
 
 1733       $this->import_key = trim($this->import_key);
 
 1735     if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
 
 1736       $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
 
 1743     $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
 
 1744     $sql .= 
" ref=".(isset($this->
ref) ? 
"'".$this->db->escape($this->
ref).
"'" : 
"null").
",";
 
 1745     $sql .= 
" ref_client=".(isset($this->ref_client) ? 
"'".$this->db->escape($this->ref_client).
"'" : 
"null").
",";
 
 1746     $sql .= 
" ref_ext=".(isset($this->ref_ext) ? 
"'".$this->db->escape($this->ref_ext).
"'" : 
"null").
",";
 
 1747     $sql .= 
" fk_soc=".(isset($this->socid) ? $this->socid : 
"null").
",";
 
 1748     $sql .= 
" datep=".(strval($this->date) != 
'' ? 
"'".$this->db->idate($this->date).
"'" : 
'null').
",";
 
 1749     if (!empty($this->fin_validite)) {
 
 1750       $sql .= 
" fin_validite=".(strval($this->fin_validite) != 
'' ? 
"'".$this->db->idate($this->fin_validite).
"'" : 
'null').
",";
 
 1752     $sql .= 
" date_valid=".(strval($this->date_validation) != 
'' ? 
"'".$this->db->idate($this->date_validation).
"'" : 
'null').
",";
 
 1753     $sql .= 
" total_tva=".(isset($this->total_tva) ? $this->total_tva : 
"null").
",";
 
 1754     $sql .= 
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 : 
"null").
",";
 
 1755     $sql .= 
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 : 
"null").
",";
 
 1756     $sql .= 
" total_ht=".(isset($this->total_ht) ? $this->total_ht : 
"null").
",";
 
 1757     $sql .= 
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc : 
"null").
",";
 
 1758     $sql .= 
" fk_statut=".(isset($this->statut) ? $this->statut : 
"null").
",";
 
 1759     $sql .= 
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id : 
"null").
",";
 
 1760     $sql .= 
" fk_user_valid=".(isset($this->user_valid) ? $this->user_valid : 
"null").
",";
 
 1761     $sql .= 
" fk_projet=".(isset($this->fk_project) ? $this->fk_project : 
"null").
",";
 
 1762     $sql .= 
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id : 
"null").
",";
 
 1763     $sql .= 
" deposit_percent=".(!empty($this->deposit_percent) ? 
"'".$this->db->escape($this->deposit_percent).
"'" : 
"null").
",";
 
 1764     $sql .= 
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id : 
"null").
",";
 
 1765     $sql .= 
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id : 
"null").
",";
 
 1766     $sql .= 
" note_private=".(isset($this->note_private) ? 
"'".$this->db->escape($this->note_private).
"'" : 
"null").
",";
 
 1767     $sql .= 
" note_public=".(isset($this->note_public) ? 
"'".$this->db->escape($this->note_public).
"'" : 
"null").
",";
 
 1768     $sql .= 
" model_pdf=".(isset($this->model_pdf) ? 
"'".$this->db->escape($this->model_pdf).
"'" : 
"null").
",";
 
 1769     $sql .= 
" import_key=".(isset($this->import_key) ? 
"'".$this->db->escape($this->import_key).
"'" : 
"null");
 
 1770     $sql .= 
" WHERE rowid=".((int) $this->
id);
 
 1774     dol_syslog(get_class($this).
"::update", LOG_DEBUG);
 
 1778       $this->errors[] = 
"Error ".$this->db->lasterror();
 
 1788     if (!$error && !$notrigger) {
 
 1799       foreach ($this->errors as $errmsg) {
 
 1800         dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
 
 1801         $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 1803       $this->
db->rollback();
 
 1806       $this->
db->commit();
 
 1822   public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $filters = 
'')
 
 1825     global $langs, $conf;
 
 1827     $this->lines = array();
 
 1829     $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,';
 
 1830     $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,';
 
 1831     $sql .= 
' d.fk_unit,';
 
 1832     $sql .= 
' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch, p.barcode as product_barcode,';
 
 1833     $sql .= 
' p.weight, p.weight_units, p.volume, p.volume_units,';
 
 1834     $sql .= 
' d.date_start, d.date_end,';
 
 1835     $sql .= 
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
 
 1836     $sql .= 
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
 
 1837     $sql .= 
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
 
 1838     $sql .= 
' WHERE d.fk_propal = '.((int) $this->
id);
 
 1839     if ($only_product) {
 
 1840       $sql .= 
' AND p.fk_product_type = 0';
 
 1845     $sql .= 
' ORDER by d.rang';
 
 1847     dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
 
 1848     $result = $this->
db->query($sql);
 
 1850       require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
 
 1852       $num = $this->
db->num_rows($result);
 
 1856         $objp                   = $this->
db->fetch_object($result);
 
 1860         $line->rowid = $objp->rowid; 
 
 1861         $line->id = $objp->rowid;
 
 1862         $line->fk_propal = $objp->fk_propal;
 
 1863         $line->fk_parent_line = $objp->fk_parent_line;
 
 1864         $line->product_type     = $objp->product_type;
 
 1865         $line->label            = $objp->custom_label;
 
 1866         $line->desc             = $objp->description; 
 
 1867         $line->description      = $objp->description; 
 
 1868         $line->qty              = $objp->qty;
 
 1869         $line->vat_src_code     = $objp->vat_src_code;
 
 1870         $line->tva_tx           = $objp->tva_tx;
 
 1871         $line->localtax1_tx   = $objp->localtax1_tx;
 
 1872         $line->localtax2_tx   = $objp->localtax2_tx;
 
 1873         $line->localtax1_type = $objp->localtax1_type;
 
 1874         $line->localtax2_type = $objp->localtax2_type;
 
 1875         $line->subprice         = $objp->subprice;
 
 1876         $line->fk_remise_except = $objp->fk_remise_except;
 
 1877         $line->remise_percent   = $objp->remise_percent;
 
 1878         $line->price            = $objp->price; 
 
 1880         $line->info_bits        = $objp->info_bits;
 
 1881         $line->total_ht         = $objp->total_ht;
 
 1882         $line->total_tva        = $objp->total_tva;
 
 1883         $line->total_localtax1  = $objp->total_localtax1;
 
 1884         $line->total_localtax2  = $objp->total_localtax2;
 
 1885         $line->total_ttc        = $objp->total_ttc;
 
 1886         $line->fk_fournprice = $objp->fk_fournprice;
 
 1887         $marginInfos = 
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
 
 1888         $line->pa_ht = $marginInfos[0];
 
 1889         $line->marge_tx     = $marginInfos[1];
 
 1890         $line->marque_tx    = $marginInfos[2];
 
 1891         $line->special_code     = $objp->special_code;
 
 1892         $line->rang             = $objp->rang;
 
 1894         $line->fk_product       = $objp->fk_product;
 
 1896         $line->ref = $objp->product_ref; 
 
 1897         $line->libelle = $objp->product_label; 
 
 1899         $line->product_ref = $objp->product_ref;
 
 1900         $line->product_label = $objp->product_label;
 
 1901         $line->product_desc     = $objp->product_desc; 
 
 1902         $line->product_tobatch  = $objp->product_tobatch;
 
 1903         $line->product_barcode  = $objp->product_barcode;
 
 1905         $line->fk_product_type  = $objp->fk_product_type; 
 
 1906         $line->fk_unit          = $objp->fk_unit;
 
 1907         $line->weight = $objp->weight;
 
 1908         $line->weight_units = $objp->weight_units;
 
 1909         $line->volume = $objp->volume;
 
 1910         $line->volume_units = $objp->volume_units;
 
 1912         $line->date_start = $this->
db->jdate($objp->date_start);
 
 1913         $line->date_end = $this->
db->jdate($objp->date_end);
 
 1916         $line->fk_multicurrency = $objp->fk_multicurrency;
 
 1917         $line->multicurrency_code = $objp->multicurrency_code;
 
 1918         $line->multicurrency_subprice   = $objp->multicurrency_subprice;
 
 1919         $line->multicurrency_total_ht   = $objp->multicurrency_total_ht;
 
 1920         $line->multicurrency_total_tva  = $objp->multicurrency_total_tva;
 
 1921         $line->multicurrency_total_ttc  = $objp->multicurrency_total_ttc;
 
 1923         $line->fetch_optionals();
 
 1926         if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
 
 1928           $tmpproduct->fetch($objp->fk_product);
 
 1929           $tmpproduct->getMultiLangs();
 
 1931           $line->multilangs = $tmpproduct->multilangs;
 
 1934         $this->lines[$i] = $line;
 
 1939       $this->
db->free($result);
 
 1943       $this->error = $this->
db->lasterror();
 
 1955   public function valid($user, $notrigger = 0)
 
 1959     require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
 
 1964     if ($this->statut == self::STATUS_VALIDATED) {
 
 1965       dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
 
 1969     if (!((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->creer))
 
 1970     || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->validate)))) {
 
 1971       $this->error = 
'ErrorPermissionDenied';
 
 1972       dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
 
 1982     $soc->fetch($this->socid);
 
 1985     if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) { 
 
 1992     $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal";
 
 1993     $sql .= 
" SET ref = '".$this->db->escape($num).
"',";
 
 1994     $sql .= 
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->
db->idate($now).
"', fk_user_valid=".((int) $user->id);
 
 1997     dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
 
 2005     if (!$error && !$notrigger) {
 
 2007       $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
 
 2015       $this->oldref = $this->ref;
 
 2018       if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
 
 2020         $sql = 
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->
db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'propale/".$this->
db->escape($this->newref).
"'";
 
 2021         $sql .= 
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->
db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
 
 2025           $this->error = $this->
db->lasterror();
 
 2031         $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
 
 2032         $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
 
 2033         if (!$error && file_exists($dirsource)) {
 
 2034           dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
 
 2035           if (@rename($dirsource, $dirdest)) {
 
 2038             $listoffiles = 
dol_dir_list($dirdest, 
'files', 1, 
'^'.preg_quote($oldref, 
'/'));
 
 2039             foreach ($listoffiles as $fileentry) {
 
 2040               $dirsource = $fileentry[
'name'];
 
 2041               $dirdest = preg_replace(
'/^'.preg_quote($oldref, 
'/').
'/', $newref, $dirsource);
 
 2042               $dirsource = $fileentry[
'path'].
'/'.$dirsource;
 
 2043               $dirdest = $fileentry[
'path'].
'/'.$dirdest;
 
 2044               @rename($dirsource, $dirdest);
 
 2051       $this->brouillon = 0;
 
 2053       $this->user_valid_id = $user->id;
 
 2054       $this->datev = $now;
 
 2056       $this->
db->commit();
 
 2059       $this->
db->rollback();
 
 2078       $this->error = 
'ErrorBadParameter';
 
 2079       dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
 
 2083     if (!empty($user->rights->propal->creer)) {
 
 2088       $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->
db->idate($date).
"'";
 
 2094         $this->errors[] = $this->
db->error();
 
 2099         $this->oldcopy = clone $this;
 
 2100         $this->date = $date;
 
 2101         $this->datep = $date; 
 
 2104       if (!$notrigger && empty($error)) {
 
 2114         $this->
db->commit();
 
 2117         foreach ($this->errors as $errmsg) {
 
 2118           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2119           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2121         $this->
db->rollback();
 
 2141     if (!empty($user->rights->propal->creer)) {
 
 2146       $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity != 
'' ? 
"'".$this->db->idate($date_end_validity).
"'" : 
'null');
 
 2147       $sql .= 
" WHERE rowid = ".((int) $this->
id).
" AND fk_statut = ".((int) self::STATUS_DRAFT);
 
 2152         $this->errors[] = $this->
db->error();
 
 2158         $this->oldcopy = clone $this;
 
 2159         $this->fin_validite = $date_end_validity;
 
 2162       if (!$notrigger && empty($error)) {
 
 2172         $this->
db->commit();
 
 2175         foreach ($this->errors as $errmsg) {
 
 2176           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2177           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2179         $this->
db->rollback();
 
 2213     if (!empty($user->rights->propal->creer)) {
 
 2218       $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
 
 2219       $sql .= 
" SET date_livraison = ".($delivery_date != 
'' ? 
"'".$this->db->idate($delivery_date).
"'" : 
'null');
 
 2220       $sql .= 
" WHERE rowid = ".((int) $this->
id);
 
 2225         $this->errors[] = $this->
db->error();
 
 2230         $this->oldcopy = clone $this;
 
 2231         $this->date_livraison = $delivery_date;
 
 2232         $this->delivery_date = $delivery_date;
 
 2235       if (!$notrigger && empty($error)) {
 
 2245         $this->
db->commit();
 
 2248         foreach ($this->errors as $errmsg) {
 
 2249           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2250           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2252         $this->
db->rollback();
 
 2272     if (!empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) {
 
 2277       $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal";
 
 2278       $sql .= 
" SET fk_availability = ".((int) $id);
 
 2279       $sql .= 
" WHERE rowid = ".((int) $this->
id);
 
 2281       dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
 
 2284         $this->errors[] = $this->
db->error();
 
 2289         $this->oldcopy = clone $this;
 
 2290         $this->fk_availability = $id;
 
 2291         $this->availability_id = $id;
 
 2294       if (!$notrigger && empty($error)) {
 
 2304         $this->
db->commit();
 
 2307         foreach ($this->errors as $errmsg) {
 
 2308           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2309           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2311         $this->
db->rollback();
 
 2315       $error_str = 
'Propal status do not meet requirement '.$this->statut;
 
 2317       $this->error = $error_str;
 
 2318       $this->errors[] = $this->error;
 
 2335     if (!empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) {
 
 2340       $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
 
 2341       $sql .= 
" SET fk_input_reason = ".((int) $id);
 
 2342       $sql .= 
" WHERE rowid = ".((int) $this->
id);
 
 2347         $this->errors[] = $this->
db->error();
 
 2353         $this->oldcopy = clone $this;
 
 2354         $this->fk_input_reason = $id;
 
 2355         $this->demand_reason_id = $id;
 
 2359       if (!$notrigger && empty($error)) {
 
 2369         $this->
db->commit();
 
 2372         foreach ($this->errors as $errmsg) {
 
 2373           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2374           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2376         $this->
db->rollback();
 
 2380       $error_str = 
'Propal status do not meet requirement '.$this->statut;
 
 2382       $this->error = $error_str;
 
 2383       $this->errors[] = $this->error;
 
 2400     if (!empty($user->rights->propal->creer)) {
 
 2405       $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ? 
'NULL' : 
"'".$this->db->escape($ref_client).
"'");
 
 2406       $sql .= 
" WHERE rowid = ".((int) $this->
id);
 
 2408       dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
 
 2411         $this->errors[] = $this->
db->error();
 
 2416         $this->oldcopy = clone $this;
 
 2417         $this->ref_client = $ref_client;
 
 2420       if (!$notrigger && empty($error)) {
 
 2430         $this->
db->commit();
 
 2433         foreach ($this->errors as $errmsg) {
 
 2434           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2435           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2437         $this->
db->rollback();
 
 2459     if (!empty($user->rights->propal->creer)) {
 
 2466       $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal SET remise_percent = ".((
float) 
$remise);
 
 2472         $this->errors[] = $this->
db->error();
 
 2477         $this->oldcopy = clone $this;
 
 2478         $this->remise_percent = 
$remise;
 
 2482       if (!$notrigger && empty($error)) {
 
 2492         $this->
db->commit();
 
 2495         foreach ($this->errors as $errmsg) {
 
 2496           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2497           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2499         $this->
db->rollback();
 
 2525     if (!empty($user->rights->propal->creer)) {
 
 2530       $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal";
 
 2531       $sql .= 
" SET remise_absolue = ".((float) 
$remise);
 
 2537         $this->errors[] = $this->
db->error();
 
 2542         $this->oldcopy = clone $this;
 
 2546       if (!$notrigger && empty($error)) {
 
 2556         $this->
db->commit();
 
 2559         foreach ($this->errors as $errmsg) {
 
 2560           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2561           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2563         $this->
db->rollback();
 
 2586     $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal";
 
 2587     $sql .= 
" SET fk_statut = ".((int) $status).
",";
 
 2588     if (!empty(
$note)) {
 
 2589       $sql .= 
" note_private = '".$this->db->escape(
$note).
"',";
 
 2591     $sql .= 
" date_cloture=NULL, fk_user_cloture=NULL";
 
 2592     $sql .= 
" WHERE rowid = ".((int) $this->
id);
 
 2596     dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
 
 2600       $this->errors[] = 
"Error ".$this->db->lasterror();
 
 2615       if (!empty($this->errors)) {
 
 2616         foreach ($this->errors as $errmsg) {
 
 2617           dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
 
 2618           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2621       $this->
db->rollback();
 
 2624       $this->statut = $status;
 
 2625       $this->status = $status;
 
 2627       $this->
db->commit();
 
 2643     global $langs,$conf;
 
 2652     if (empty($conf->global->PROPALE_KEEP_OLD_SIGNATURE_INFO)) {
 
 2653       $date_signature = $now;
 
 2654       $fk_user_signature = $user->id;
 
 2656       $this->
info($this->
id);
 
 2657       if (!isset($this->date_signature) || $this->date_signature == 
'') {
 
 2658         $date_signature = $now;
 
 2659         $fk_user_signature = $user->id;
 
 2661         $date_signature = $this->date_signature;
 
 2662         $fk_user_signature = $this->user_signature->id;
 
 2666     $sql  = 
"UPDATE ".MAIN_DB_PREFIX.
"propal";
 
 2667     $sql .= 
" SET fk_statut = ".((int) $status).
", note_private = '".$this->
db->escape($newprivatenote).
"', date_signature='".$this->
db->idate($date_signature).
"', fk_user_signature=".$fk_user_signature;
 
 2668     $sql .= 
" WHERE rowid = ".((int) $this->
id);
 
 2673       $modelpdf = !empty($conf->global->PROPALE_ADDON_PDF_ODT_CLOSED) ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
 
 2674       $trigger_name = 
'PROPAL_CLOSE_REFUSED';   
 
 2676       if ($status == self::STATUS_SIGNED) { 
 
 2677         $trigger_name = 
'PROPAL_CLOSE_SIGNED';  
 
 2678         $modelpdf = !empty($conf->global->PROPALE_ADDON_PDF_ODT_TOBILL) ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
 
 2682         $soc->id = $this->socid;
 
 2683         $result = $soc->set_as_client();
 
 2686           $this->error=$this->
db->lasterror();
 
 2687           $this->
db->rollback();
 
 2692       if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
 
 2694         $outputlangs = $langs;
 
 2696           $outputlangs = 
new Translate(
"", $conf);
 
 2697           $newlang = (
GETPOST(
'lang_id', 
'aZ09') ? 
GETPOST(
'lang_id', 
'aZ09') : $this->thirdparty->default_lang);
 
 2698           $outputlangs->setDefaultLang($newlang);
 
 2702         $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0);
 
 2703         $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0);
 
 2704         $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0);
 
 2707         $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 
 2711         $this->oldcopy= clone $this;
 
 2712         $this->statut = $status;
 
 2713         $this->status = $status;
 
 2714         $this->date_signature = $date_signature;
 
 2715         $this->note_private = $newprivatenote;
 
 2718       if (!$notrigger && empty($error)) {
 
 2728         $this->
db->commit();
 
 2731         $this->statut = $this->oldcopy->statut;
 
 2732         $this->status = $this->oldcopy->statut;
 
 2733         $this->date_signature = $this->oldcopy->date_signature;
 
 2734         $this->note_private = $this->oldcopy->note_private;
 
 2736         $this->
db->rollback();
 
 2740       $this->error = $this->
db->lasterror();
 
 2741       $this->
db->rollback();
 
 2756     global $conf, $langs;
 
 2763     $triggerName = 
'PROPAL_CLASSIFY_BILLED';
 
 2769     $sql = 
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
 
 2770     $sql .= 
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->
db->idate($now).
"', fk_user_cloture=".((int) $user->id);
 
 2771     $sql .= 
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
 
 2776       $this->errors[] = $this->
db->error();
 
 2779       $num = $this->
db->affected_rows(
$resql);
 
 2783       $modelpdf = $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
 
 2785       if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
 
 2787         $outputlangs = $langs;
 
 2789           $outputlangs = 
new Translate(
"", $conf);
 
 2790           $newlang = (
GETPOST(
'lang_id', 
'aZ09') ? 
GETPOST(
'lang_id', 
'aZ09') : $this->thirdparty->default_lang);
 
 2791           $outputlangs->setDefaultLang($newlang);
 
 2795         $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0);
 
 2796         $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0);
 
 2797         $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0);
 
 2800         $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
 
 2803       $this->oldcopy = clone $this;
 
 2805       $this->date_cloture = $now;
 
 2806       $this->note_private = $newprivatenote;
 
 2809     if (!$notrigger && empty($error)) {
 
 2819       $this->
db->commit();
 
 2822       foreach ($this->errors as $errmsg) {
 
 2823         dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2824         $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2826       $this->
db->rollback();
 
 2845     if ($this->statut <= self::STATUS_DRAFT) {
 
 2849     dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
 
 2853     $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propal";
 
 2854     $sql .= 
" SET fk_statut = ".self::STATUS_DRAFT;
 
 2855     $sql .= 
",  online_sign_ip = NULL , online_sign_name = NULL";
 
 2856     $sql .= 
" WHERE rowid = ".((int) $this->
id);
 
 2860       $this->errors[] = $this->
db->error();
 
 2865       $this->oldcopy = clone $this;
 
 2868     if (!$notrigger && empty($error)) {
 
 2879       $this->brouillon = 1;
 
 2881       $this->
db->commit();
 
 2884       foreach ($this->errors as $errmsg) {
 
 2885         dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 2886         $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 2888       $this->
db->rollback();
 
 2908   public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield = 
'p.datep', $sortorder = 
'DESC')
 
 2915     $sql = 
"SELECT s.rowid, s.nom as name, s.client,";
 
 2916     $sql .= 
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
 
 2917     $sql .= 
" p.datep as dp, p.fin_validite as datelimite";
 
 2918     if (empty($user->rights->societe->client->voir) && !$socid) {
 
 2919       $sql .= 
", sc.fk_soc, sc.fk_user";
 
 2921     $sql .= 
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
 
 2922     if (empty($user->rights->societe->client->voir) && !$socid) {
 
 2923       $sql .= 
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
 
 2925     $sql .= 
" WHERE p.entity IN (".getEntity(
'propal').
")";
 
 2926     $sql .= 
" AND p.fk_soc = s.rowid";
 
 2927     $sql .= 
" AND p.fk_statut = c.id";
 
 2928     if (empty($user->rights->societe->client->voir) && !$socid) { 
 
 2929       $sql .= 
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
 
 2932       $sql .= 
" AND s.rowid = ".((int) $socid);
 
 2935       $sql .= 
" AND p.fk_statut = ".self::STATUS_DRAFT;
 
 2937     if ($notcurrentuser > 0) {
 
 2938       $sql .= 
" AND p.fk_user_author <> ".((int) $user->id);
 
 2940     $sql .= $this->
db->order($sortfield, $sortorder);
 
 2941     $sql .= $this->
db->plimit($limit, $offset);
 
 2943     $result = $this->
db->query($sql);
 
 2945       $num = $this->
db->num_rows($result);
 
 2949           $obj = $this->
db->fetch_object($result);
 
 2951           if ($shortlist == 1) {
 
 2952             $ga[$obj->propalid] = $obj->ref;
 
 2953           } elseif ($shortlist == 2) {
 
 2954             $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
 
 2956             $ga[$i][
'id'] = $obj->propalid;
 
 2957             $ga[$i][
'ref']  = $obj->ref;
 
 2958             $ga[$i][
'name'] = $obj->name;
 
 2992     $linkedInvoices = array();
 
 2995     foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
 
 2998       foreach ($objectid as $key => $object) {
 
 3000         if ($objecttype == 
'facture') {
 
 3001           $linkedInvoices[] = $object;
 
 3005           foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
 
 3006             foreach ($subobjectid as $subkey => $subobject) {
 
 3007               if ($subobjecttype == 
'facture') {
 
 3008                 $linkedInvoices[] = $subobject;
 
 3016     if (count($linkedInvoices) > 0) {
 
 3017       $sql = 
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
 
 3018       $sql .= 
" FROM ".MAIN_DB_PREFIX.
"facture";
 
 3019       $sql .= 
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
 
 3021       dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
 
 3025         $tab_sqlobj = array();
 
 3026         $nump = $this->
db->num_rows(
$resql);
 
 3027         for ($i = 0; $i < $nump; $i++) {
 
 3028           $sqlobj = $this->
db->fetch_object(
$resql);
 
 3029           $tab_sqlobj[] = $sqlobj;
 
 3033         $nump = count($tab_sqlobj);
 
 3037           while ($i < $nump) {
 
 3038             $obj = array_shift($tab_sqlobj);
 
 3061   public function delete($user, $notrigger = 0)
 
 3064     require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
 
 3080     if (!$error && !empty($this->table_element_line)) {
 
 3081       $tabletodelete = $this->table_element_line;
 
 3082       $sqlef = 
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
"_extrafields WHERE fk_object IN (SELECT rowid FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id).
")";
 
 3083       $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
 
 3084       if (!$this->
db->query($sqlef) || !$this->
db->query($sql)) {
 
 3086         $this->error = $this->
db->lasterror();
 
 3087         $this->errors[] = $this->error;
 
 3088         dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
 
 3113         dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
 
 3119       $sql = 
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
 
 3120       $res = $this->
db->query($sql);
 
 3123         $this->error = $this->
db->lasterror();
 
 3124         $this->errors[] = $this->error;
 
 3125         dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
 
 3140       if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
 
 3141         $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
 
 3142         $file = $dir.
"/".$ref.
".pdf";
 
 3143         if (file_exists($file)) {
 
 3147             $this->error = 
'ErrorFailToDeleteFile';
 
 3148             $this->errors[] = $this->error;
 
 3149             $this->
db->rollback();
 
 3153         if (file_exists($dir)) {
 
 3156             $this->error = 
'ErrorFailToDeleteDir';
 
 3157             $this->errors[] = $this->error;
 
 3158             $this->
db->rollback();
 
 3166       dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
 
 3167       $this->
db->commit();
 
 3170       $this->
db->rollback();
 
 3187     if ($this->statut >= self::STATUS_DRAFT) {
 
 3192       $sql = 
'UPDATE '.MAIN_DB_PREFIX.
'propal';
 
 3193       $sql .= 
' SET fk_availability = '.((int) $availability_id);
 
 3194       $sql .= 
' WHERE rowid='.((int) $this->
id);
 
 3196       dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
 
 3199         $this->errors[] = $this->
db->error();
 
 3204         $this->oldcopy = clone $this;
 
 3205         $this->availability_id = $availability_id;
 
 3208       if (!$notrigger && empty($error)) {
 
 3218         $this->
db->commit();
 
 3221         foreach ($this->errors as $errmsg) {
 
 3222           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 3223           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 3225         $this->
db->rollback();
 
 3229       $error_str = 
'Propal status do not meet requirement '.$this->statut;
 
 3231       $this->error = $error_str;
 
 3232       $this->errors[] = $this->error;
 
 3251     if ($this->statut >= self::STATUS_DRAFT) {
 
 3256       $sql = 
'UPDATE '.MAIN_DB_PREFIX.
'propal';
 
 3257       $sql .= 
' SET fk_input_reason = '.((int) $demand_reason_id);
 
 3258       $sql .= 
' WHERE rowid='.((int) $this->
id);
 
 3260       dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
 
 3263         $this->errors[] = $this->
db->error();
 
 3268         $this->oldcopy = clone $this;
 
 3269         $this->demand_reason_id = $demand_reason_id;
 
 3272       if (!$notrigger && empty($error)) {
 
 3282         $this->
db->commit();
 
 3285         foreach ($this->errors as $errmsg) {
 
 3286           dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
 
 3287           $this->error .= ($this->error ? 
', '.$errmsg : $errmsg);
 
 3289         $this->
db->rollback();
 
 3293       $error_str = 
'Propal status do not meet requirement '.$this->statut;
 
 3295       $this->error = $error_str;
 
 3296       $this->errors[] = $this->error;
 
 3310     $sql = 
"SELECT c.rowid, ";
 
 3311     $sql .= 
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
 
 3312     $sql .= 
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
 
 3313     $sql .= 
" FROM ".MAIN_DB_PREFIX.
"propal as c";
 
 3314     $sql .= 
" WHERE c.rowid = ".((int) $id);
 
 3316     $result = $this->
db->query($sql);
 
 3319       if ($this->
db->num_rows($result)) {
 
 3320         $obj = $this->
db->fetch_object($result);
 
 3322         $this->
id                = $obj->rowid;
 
 3324         $this->date_creation     = $this->
db->jdate($obj->datec);
 
 3325         $this->date_validation   = $this->
db->jdate($obj->datev);
 
 3326         $this->date_signature    = $this->
db->jdate($obj->date_signature);
 
 3327         $this->date_cloture      = $this->
db->jdate($obj->date_cloture);
 
 3329         $cuser = 
new User($this->
db);
 
 3330         $cuser->fetch($obj->fk_user_author);
 
 3331         $this->user_creation = $cuser;
 
 3333         if ($obj->fk_user_valid) {
 
 3334           $vuser = 
new User($this->
db);
 
 3335           $vuser->fetch($obj->fk_user_valid);
 
 3336           $this->user_validation = $vuser;
 
 3339         if ($obj->fk_user_signature) {
 
 3340           $user_signature = 
new User($this->
db);
 
 3341           $user_signature->fetch($obj->fk_user_signature);
 
 3342           $this->user_signature = $user_signature;
 
 3345         if ($obj->fk_user_cloture) {
 
 3346           $cluser = 
new User($this->
db);
 
 3347           $cluser->fetch($obj->fk_user_cloture);
 
 3348           $this->user_cloture = $cluser;
 
 3351       $this->
db->free($result);
 
 3366     return $this->
LibStatut($this->statut, $mode);
 
 3380     global $conf, $hookmanager;
 
 3383     if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
 
 3385       $langs->load(
"propal");
 
 3386       $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
 
 3387       $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
 
 3388       $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
 
 3389       $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
 
 3390       $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
 
 3391       $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
 
 3392       $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
 
 3393       $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
 
 3394       $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
 
 3395       $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
 
 3399     if ($status == self::STATUS_DRAFT) {
 
 3400       $statusType = 
'status0';
 
 3401     } elseif ($status == self::STATUS_VALIDATED) {
 
 3402       $statusType = 
'status1';
 
 3403     } elseif ($status == self::STATUS_SIGNED) {
 
 3404       $statusType = 
'status4';
 
 3405     } elseif ($status == self::STATUS_NOTSIGNED) {
 
 3406       $statusType = 
'status9';
 
 3407     } elseif ($status == self::STATUS_BILLED) {
 
 3408       $statusType = 
'status6';
 
 3412     $parameters = array(
'status' => $status, 
'mode' => $mode);
 
 3413     $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this); 
 
 3416       return $hookmanager->resPrint;
 
 3419     return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], 
'', $statusType, $mode);
 
 3434     global $conf, $langs;
 
 3438     $sql = 
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
 
 3439     $sql .= 
" FROM ".MAIN_DB_PREFIX.
"propal as p";
 
 3440     if (empty($user->rights->societe->client->voir) && !$user->socid) {
 
 3441       $sql .= 
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
 
 3442       $sql .= 
" WHERE sc.fk_user = ".((int) $user->id);
 
 3445     $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
 
 3446     if ($mode == 
'opened') {
 
 3447       $sql .= 
" AND p.fk_statut = ".self::STATUS_VALIDATED;
 
 3449     if ($mode == 
'signed') {
 
 3450       $sql .= 
" AND p.fk_statut = ".self::STATUS_SIGNED;
 
 3453       $sql .= 
" AND p.fk_soc = ".((int) $user->socid);
 
 3458       $langs->load(
"propal");
 
 3463       $label = $labelShort = 
'';
 
 3464       if ($mode == 
'opened') {
 
 3465         $delay_warning = $conf->propal->cloture->warning_delay;
 
 3467         $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
 
 3468         $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
 
 3470       if ($mode == 
'signed') {
 
 3471         $delay_warning = $conf->propal->facturation->warning_delay;
 
 3473         $label = $langs->trans(
"PropalsToBill"); 
 
 3474         $labelShort = $langs->trans(
"ToBill");
 
 3478       $response->warning_delay = $delay_warning / 60 / 60 / 24;
 
 3479       $response->label = $label;
 
 3480       $response->labelShort = $labelShort;
 
 3481       $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
 
 3482       $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
 
 3486       while ($obj = $this->
db->fetch_object(
$resql)) {
 
 3487         $response->nbtodo++;
 
 3488         $response->total += $obj->total_ht;
 
 3490         if ($mode == 
'opened') {
 
 3491           $datelimit = $this->
db->jdate($obj->datefin);
 
 3492           if ($datelimit < ($now - $delay_warning)) {
 
 3493             $response->nbtodolate++;
 
 3502       $this->error = $this->
db->error();
 
 3517     global $conf, $langs;
 
 3522     $sql = 
"SELECT rowid";
 
 3523     $sql .= 
" FROM ".MAIN_DB_PREFIX.
"product";
 
 3524     $sql .= 
" WHERE entity IN (".getEntity(
'product').
")";
 
 3525     $sql .= $this->
db->plimit(100);
 
 3529       $num_prods = $this->
db->num_rows(
$resql);
 
 3531       while ($i < $num_prods) {
 
 3533         $row = $this->
db->fetch_row(
$resql);
 
 3534         $prodids[$i] = $row[0];
 
 3540     $this->
ref = 
'SPECIMEN';
 
 3541     $this->ref_client = 
'NEMICEPS';
 
 3542     $this->specimen = 1;
 
 3544     $this->date = time();
 
 3545     $this->fin_validite = $this->date + 3600 * 24 * 30;
 
 3546     $this->cond_reglement_id   = 1;
 
 3547     $this->cond_reglement_code = 
'RECEP';
 
 3548     $this->mode_reglement_id   = 7;
 
 3549     $this->mode_reglement_code = 
'CHQ';
 
 3550     $this->availability_id     = 1;
 
 3551     $this->availability_code   = 
'AV_NOW';
 
 3552     $this->demand_reason_id    = 1;
 
 3553     $this->demand_reason_code  = 
'SRC_00';
 
 3554     $this->note_public = 
'This is a comment (public)';
 
 3555     $this->note_private = 
'This is a comment (private)';
 
 3557     $this->multicurrency_tx = 1;
 
 3558     $this->multicurrency_code = $conf->currency;
 
 3563     while ($xnbp < $nbp) {
 
 3565       $line->desc = $langs->trans(
"Description").
" ".$xnbp;
 
 3567       $line->subprice = 100;
 
 3570       $line->localtax1_tx = 0;
 
 3571       $line->localtax2_tx = 0;
 
 3573         $line->total_ht = 50;
 
 3574         $line->total_ttc = 60;
 
 3575         $line->total_tva = 10;
 
 3576         $line->remise_percent = 50;
 
 3578         $line->total_ht = 100;
 
 3579         $line->total_ttc = 120;
 
 3580         $line->total_tva = 20;
 
 3581         $line->remise_percent = 00;
 
 3584       if ($num_prods > 0) {
 
 3585         $prodid = mt_rand(1, $num_prods);
 
 3586         $line->fk_product = $prodids[$prodid];
 
 3587         $line->product_ref = 
'SPECIMEN';
 
 3590       $this->lines[$xnbp] = $line;
 
 3592       $this->total_ht       += $line->total_ht;
 
 3593       $this->total_tva      += $line->total_tva;
 
 3594       $this->total_ttc      += $line->total_ttc;
 
 3611     $this->nb = array();
 
 3614     $sql = 
"SELECT count(p.rowid) as nb";
 
 3615     $sql .= 
" FROM ".MAIN_DB_PREFIX.
"propal as p";
 
 3616     $sql .= 
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
 
 3617     if (empty($user->rights->societe->client->voir) && !$user->socid) {
 
 3618       $sql .= 
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
 
 3619       $sql .= 
" WHERE sc.fk_user = ".((int) $user->id);
 
 3622     $sql .= 
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
 
 3627       while ($obj = $this->
db->fetch_object(
$resql)) {
 
 3628         $this->nb[
"proposals"] = $obj->nb;
 
 3634       $this->error = $this->
db->error();
 
 3649     global $conf, $langs;
 
 3650     $langs->load(
"propal");
 
 3652     $classname = $conf->global->PROPALE_ADDON;
 
 3654     if (!empty($classname)) {
 
 3657       $file = $classname.
".php";
 
 3660       $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
 
 3661       foreach ($dirmodels as $reldir) {
 
 3665         $mybool |= @include_once $dir.$file;
 
 3673       $obj = 
new $classname();
 
 3675       $numref = $obj->getNextValue($soc, $this);
 
 3677       if ($numref != 
"") {
 
 3680         $this->error = $obj->error;
 
 3685       $langs->load(
"errors");
 
 3686       print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
 
 3702   public function getNomUrl($withpicto = 0, $option = 
'', $get_params = 
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
 
 3704     global $langs, $conf, $user, $hookmanager;
 
 3706     if (!empty($conf->dol_no_mouse_hover)) {
 
 3714     if ($user->rights->propal->lire) {
 
 3715       $label = 
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
 
 3716       if (isset($this->statut)) {
 
 3717         $label .= 
' '.$this->getLibStatut(5);
 
 3719       if (!empty($this->
ref)) {
 
 3720         $label .= 
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
 
 3722       if (!empty($this->ref_client)) {
 
 3723         $label .= 
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_client;
 
 3725       if (!empty($this->total_ht)) {
 
 3726         $label .= 
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
 
 3728       if (!empty($this->total_tva)) {
 
 3729         $label .= 
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
 
 3731       if (!empty($this->total_ttc)) {
 
 3732         $label .= 
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
 
 3734       if (!empty($this->date)) {
 
 3735         $label .= 
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date, 
'day');
 
 3737       if (!empty($this->delivery_date)) {
 
 3738           $label .= 
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date, 
'dayhour');
 
 3741       if ($option == 
'') {
 
 3742         $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
 
 3743       } elseif ($option == 
'compta') {  
 
 3744         $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
 
 3745       } elseif ($option == 
'expedition') {
 
 3746         $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
 
 3747       } elseif ($option == 
'document') {
 
 3748         $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
 
 3751       if ($option != 
'nolink') {
 
 3753         $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
 
 3754         if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
 
 3755           $add_save_lastsearch_values = 1;
 
 3757         if ($add_save_lastsearch_values) {
 
 3758           $url .= 
'&save_lastsearch_values=1';
 
 3764     if (empty($notooltip) && $user->rights->propal->lire) {
 
 3765       if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
 
 3766         $label = $langs->trans(
"Proposal");
 
 3767         $linkclose .= 
' alt="'.dol_escape_htmltag($label, 1).
'"';
 
 3769       $linkclose .= 
' title="'.dol_escape_htmltag($label, 1).
'"';
 
 3770       $linkclose .= 
' class="classfortooltip"';
 
 3773     $linkstart = 
'<a href="'.$url.
'"';
 
 3774     $linkstart .= $linkclose.
'>';
 
 3777     $result .= $linkstart;
 
 3779       $result .= 
img_object(($notooltip ? 
'' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 
'class="paddingright"' : 
'') : 
'class="'.(($withpicto != 2) ? 
'paddingright ' : 
'').
'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
 
 3781     if ($withpicto != 2) {
 
 3782       $result .= $this->ref;
 
 3784     $result .= $linkend;
 
 3786     if ($addlinktonotes >= 0) {
 
 3789       if ($addlinktonotes == 0) {
 
 3790         if (!empty($this->note_private) || !empty($this->note_public)) {
 
 3791           $txttoshow = $langs->trans(
'ViewPrivateNote');
 
 3793       } elseif ($addlinktonotes == 1) {
 
 3794         if (!empty($this->note_private)) {
 
 3797       } elseif ($addlinktonotes == 2) {
 
 3798         if (!empty($this->note_public)) {
 
 3801       } elseif ($addlinktonotes == 3) {
 
 3802         if ($user->socid > 0) {
 
 3803           if (!empty($this->note_public)) {
 
 3807           if (!empty($this->note_public)) {
 
 3810           if (!empty($this->note_private)) {
 
 3811             if (!empty($txttoshow)) {
 
 3812               $txttoshow .= 
'<br><br>';
 
 3820         $result .= 
' <span class="note inline-block">';
 
 3821         $result .= 
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
 
 3824         $result .= 
'</span>';
 
 3829     $hookmanager->initHooks(array($this->element . 
'dao'));
 
 3830     $parameters = array(
'id'=>$this->
id, 
'getnomurl' => &$result);
 
 3831     $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action); 
 
 3833       $result = $hookmanager->resPrint;
 
 3835       $result .= $hookmanager->resPrint;
 
 3862   public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = 
null)
 
 3864     global $conf, $langs;
 
 3866     $langs->load(
"propale");
 
 3867     $outputlangs->load(
"products");
 
 3872       if ($this->model_pdf) {
 
 3873         $modele = $this->model_pdf;
 
 3874       } elseif (!empty($conf->global->PROPALE_ADDON_PDF)) {
 
 3875         $modele = $conf->global->PROPALE_ADDON_PDF;
 
 3879     $modelpath = 
"core/modules/propale/doc/";
 
 3881     return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
 
 3927   public $element = 
'propaldet';
 
 3932   public $table_element = 
'propaldet';
 
 3938   public $fk_parent_line;
 
 3956   public $vat_src_code;
 
 3959   public $remise_percent;
 
 3960   public $fk_remise_except;
 
 3964   public $fk_fournprice;
 
 3969   public $special_code; 
 
 3974   public $info_bits = 0; 
 
 4003   public $product_ref;
 
 4018   public $product_label;
 
 4023   public $product_desc;
 
 4029   public $product_tobatch;
 
 4035   public $product_barcode;
 
 4037   public $localtax1_tx; 
 
 4038   public $localtax2_tx; 
 
 4039   public $localtax1_type; 
 
 4040   public $localtax2_type; 
 
 4041   public $total_localtax1; 
 
 4042   public $total_localtax2; 
 
 4047   public $skip_update_total; 
 
 4050   public $fk_multicurrency;
 
 4051   public $multicurrency_code;
 
 4052   public $multicurrency_subprice;
 
 4053   public $multicurrency_total_ht;
 
 4054   public $multicurrency_total_tva;
 
 4055   public $multicurrency_total_ttc;
 
 4076     $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,';
 
 4077     $sql .= 
' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
 
 4078     $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,';
 
 4079     $sql .= 
' pd.fk_unit,';
 
 4080     $sql .= 
' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,';
 
 4081     $sql .= 
' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,';
 
 4082     $sql .= 
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
 
 4083     $sql .= 
' pd.date_start, pd.date_end, pd.product_type';
 
 4084     $sql .= 
' FROM '.MAIN_DB_PREFIX.
'propaldet as pd';
 
 4085     $sql .= 
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON pd.fk_product = p.rowid';
 
 4086     $sql .= 
' WHERE pd.rowid = '.((int) $rowid);
 
 4088     $result = $this->
db->query($sql);
 
 4090       $objp = $this->
db->fetch_object($result);
 
 4093         $this->
id = $objp->rowid;
 
 4094         $this->
rowid      = $objp->rowid; 
 
 4095         $this->fk_propal = $objp->fk_propal;
 
 4096         $this->fk_parent_line = $objp->fk_parent_line;
 
 4097         $this->label      = $objp->custom_label;
 
 4098         $this->desc       = $objp->description;
 
 4099         $this->qty = $objp->qty;
 
 4100         $this->
price      = $objp->price; 
 
 4101         $this->subprice = $objp->subprice;
 
 4102         $this->vat_src_code = $objp->vat_src_code;
 
 4103         $this->tva_tx     = $objp->tva_tx;
 
 4104         $this->remise     = $objp->remise; 
 
 4105         $this->remise_percent = $objp->remise_percent;
 
 4106         $this->fk_remise_except = $objp->fk_remise_except;
 
 4107         $this->fk_product = $objp->fk_product;
 
 4108         $this->info_bits    = $objp->info_bits;
 
 4110         $this->total_ht     = $objp->total_ht;
 
 4111         $this->total_tva    = $objp->total_tva;
 
 4112         $this->total_ttc    = $objp->total_ttc;
 
 4114         $this->fk_fournprice = $objp->fk_fournprice;
 
 4116         $marginInfos      = 
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
 
 4117         $this->pa_ht      = $marginInfos[0];
 
 4118         $this->marge_tx     = $marginInfos[1];
 
 4119         $this->marque_tx    = $marginInfos[2];
 
 4121         $this->special_code   = $objp->special_code;
 
 4122         $this->product_type   = $objp->product_type;
 
 4123         $this->rang = $objp->rang;
 
 4125         $this->
ref = $objp->product_ref; 
 
 4126         $this->product_ref = $objp->product_ref;
 
 4127         $this->libelle = $objp->product_label; 
 
 4128         $this->product_label  = $objp->product_label;
 
 4129         $this->product_desc   = $objp->product_desc;
 
 4130         $this->fk_unit          = $objp->fk_unit;
 
 4132         $this->date_start       = $this->
db->jdate($objp->date_start);
 
 4133         $this->date_end         = $this->
db->jdate($objp->date_end);
 
 4136         $this->fk_multicurrency = $objp->fk_multicurrency;
 
 4137         $this->multicurrency_code = $objp->multicurrency_code;
 
 4138         $this->multicurrency_subprice   = $objp->multicurrency_subprice;
 
 4139         $this->multicurrency_total_ht   = $objp->multicurrency_total_ht;
 
 4140         $this->multicurrency_total_tva  = $objp->multicurrency_total_tva;
 
 4141         $this->multicurrency_total_ttc  = $objp->multicurrency_total_ttc;
 
 4145         $this->
db->free($result);
 
 4164     global $conf, $user;
 
 4168     dol_syslog(get_class($this).
"::insert rang=".$this->rang);
 
 4170     $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == 
''); 
 
 4173     if (empty($this->tva_tx)) {
 
 4176     if (empty($this->localtax1_tx)) {
 
 4177       $this->localtax1_tx = 0;
 
 4179     if (empty($this->localtax2_tx)) {
 
 4180       $this->localtax2_tx = 0;
 
 4182     if (empty($this->localtax1_type)) {
 
 4183       $this->localtax1_type = 0;
 
 4185     if (empty($this->localtax2_type)) {
 
 4186       $this->localtax2_type = 0;
 
 4188     if (empty($this->total_localtax1)) {
 
 4189       $this->total_localtax1 = 0;
 
 4191     if (empty($this->total_localtax2)) {
 
 4192       $this->total_localtax2 = 0;
 
 4194     if (empty($this->rang)) {
 
 4197     if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) {
 
 4198       $this->remise_percent = 0;
 
 4200     if (empty($this->info_bits)) {
 
 4201       $this->info_bits = 0;
 
 4203     if (empty($this->special_code)) {
 
 4204       $this->special_code = 0;
 
 4206     if (empty($this->fk_parent_line)) {
 
 4207       $this->fk_parent_line = 0;
 
 4209     if (empty($this->fk_fournprice)) {
 
 4210       $this->fk_fournprice = 0;
 
 4212     if (!is_numeric($this->qty)) {
 
 4215     if (empty($this->pa_ht)) {
 
 4218     if (empty($this->multicurrency_subprice)) {
 
 4219       $this->multicurrency_subprice = 0;
 
 4221     if (empty($this->multicurrency_total_ht)) {
 
 4222       $this->multicurrency_total_ht = 0;
 
 4224     if (empty($this->multicurrency_total_tva)) {
 
 4225       $this->multicurrency_total_tva = 0;
 
 4227     if (empty($this->multicurrency_total_ttc)) {
 
 4228       $this->multicurrency_total_ttc = 0;
 
 4232     if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
 
 4233       if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
 
 4236         $this->pa_ht = $result;
 
 4241     if ($this->product_type < 0) {
 
 4248     $sql = 
'INSERT INTO '.MAIN_DB_PREFIX.
'propaldet';
 
 4249     $sql .= 
' (fk_propal, fk_parent_line, label, description, fk_product, product_type,';
 
 4250     $sql .= 
' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
 
 4251     $sql .= 
' subprice, remise_percent, ';
 
 4252     $sql .= 
' info_bits, ';
 
 4253     $sql .= 
' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,';
 
 4254     $sql .= 
' fk_unit,';
 
 4255     $sql .= 
' date_start, date_end';
 
 4256     $sql .= 
', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)';
 
 4257     $sql .= 
" VALUES (".$this->fk_propal.
",";
 
 4258     $sql .= 
" ".($this->fk_parent_line > 0 ? 
"'".$this->db->escape($this->fk_parent_line).
"'" : 
"null").
",";
 
 4259     $sql .= 
" ".(!empty($this->label) ? 
"'".$this->db->escape($this->label).
"'" : 
"null").
",";
 
 4260     $sql .= 
" '".$this->db->escape($this->desc).
"',";
 
 4261     $sql .= 
" ".($this->fk_product ? 
"'".$this->db->escape($this->fk_product).
"'" : 
"null").
",";
 
 4262     $sql .= 
" '".$this->db->escape($this->product_type).
"',";
 
 4263     $sql .= 
" ".($this->fk_remise_except ? 
"'".$this->db->escape($this->fk_remise_except).
"'" : 
"null").
",";
 
 4264     $sql .= 
" ".price2num($this->qty, 
'MS').
",";
 
 4265     $sql .= 
" ".(empty($this->vat_src_code) ? 
"''" : 
"'".$this->db->escape($this->vat_src_code).
"'").
",";
 
 4266     $sql .= 
" ".price2num($this->tva_tx).
",";
 
 4267     $sql .= 
" ".price2num($this->localtax1_tx).
",";
 
 4268     $sql .= 
" ".price2num($this->localtax2_tx).
",";
 
 4269     $sql .= 
" '".$this->db->escape($this->localtax1_type).
"',";
 
 4270     $sql .= 
" '".$this->db->escape($this->localtax2_type).
"',";
 
 4271     $sql .= 
" ".(price2num($this->subprice) !== 
'' ? 
price2num($this->subprice, 
'MU') : 
"null").
",";
 
 4272     $sql .= 
" ".price2num($this->remise_percent, 3).
",";
 
 4273     $sql .= 
" ".(isset($this->info_bits) ? ((int) $this->info_bits) : 
"null").
",";
 
 4274     $sql .= 
" ".price2num($this->total_ht, 
'MT').
",";
 
 4275     $sql .= 
" ".price2num($this->total_tva, 
'MT').
",";
 
 4276     $sql .= 
" ".price2num($this->total_localtax1, 
'MT').
",";
 
 4277     $sql .= 
" ".price2num($this->total_localtax2, 
'MT').
",";
 
 4278     $sql .= 
" ".price2num($this->total_ttc, 
'MT').
",";
 
 4279     $sql .= 
" ".(!empty($this->fk_fournprice) ? 
"'".$this->db->escape($this->fk_fournprice).
"'" : 
"null").
",";
 
 4280     $sql .= 
" ".(isset($this->pa_ht) ? 
"'".price2num($this->pa_ht).
"'" : 
"null").
",";
 
 4281     $sql .= 
' '.((int) $this->special_code).
',';
 
 4282     $sql .= 
' '.((int) $this->rang).
',';
 
 4283     $sql .= 
' '.(empty($this->fk_unit) ? 
'NULL' : ((int) $this->fk_unit)).
',';
 
 4284     $sql .= 
" ".(!empty($this->date_start) ? 
"'".$this->db->idate($this->date_start).
"'" : 
"null").
',';
 
 4285     $sql .= 
" ".(!empty($this->date_end) ? 
"'".$this->db->idate($this->date_end).
"'" : 
"null");
 
 4286     $sql .= 
", ".($this->fk_multicurrency > 0 ? ((int) $this->fk_multicurrency) : 
'null');
 
 4287     $sql .= 
", '".$this->db->escape($this->multicurrency_code).
"'";
 
 4288     $sql .= 
", ".price2num($this->multicurrency_subprice, 
'CU');
 
 4289     $sql .= 
", ".price2num($this->multicurrency_total_ht, 
'CT');
 
 4290     $sql .= 
", ".price2num($this->multicurrency_total_tva, 
'CT');
 
 4291     $sql .= 
", ".price2num($this->multicurrency_total_ttc, 
'CT');
 
 4294     dol_syslog(get_class($this).
'::insert', LOG_DEBUG);
 
 4297       $this->
rowid = $this->
db->last_insert_id(MAIN_DB_PREFIX.
'propaldet');
 
 4300         $this->
id = $this->rowid;
 
 4307       if (!$error && !$notrigger) {
 
 4309         $result = $this->
call_trigger(
'LINEPROPAL_INSERT', $user);
 
 4311           $this->
db->rollback();
 
 4317       $this->
db->commit();
 
 4320       $this->error = $this->
db->error().
" sql=".$sql;
 
 4321       $this->
db->rollback();
 
 4333   public function delete(
User $user, $notrigger = 0)
 
 4342       $result = $this->
call_trigger(
'LINEPROPAL_DELETE', $user);
 
 4350       $sql = 
"DELETE FROM " . MAIN_DB_PREFIX . 
"propaldet WHERE rowid = " . ((int) $this->
rowid);
 
 4351       dol_syslog(
"PropaleLigne::delete", LOG_DEBUG);
 
 4352       if ($this->
db->query($sql)) {
 
 4355           $this->
id = $this->rowid;
 
 4359             dol_syslog(get_class($this) . 
"::delete error -4 " . $this->error, LOG_ERR);
 
 4363         $this->error = $this->
db->error() . 
" sql=" . $sql;
 
 4369       $this->
db->rollback();
 
 4372       $this->
db->commit();
 
 4385     global $conf, $user;
 
 4389     $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht == 
''); 
 
 4391     if (empty($this->
id) && !empty($this->
rowid)) {
 
 4392       $this->
id = $this->rowid;
 
 4396     if (empty($this->tva_tx)) {
 
 4399     if (empty($this->localtax1_tx)) {
 
 4400       $this->localtax1_tx = 0;
 
 4402     if (empty($this->localtax2_tx)) {
 
 4403       $this->localtax2_tx = 0;
 
 4405     if (empty($this->total_localtax1)) {
 
 4406       $this->total_localtax1 = 0;
 
 4408     if (empty($this->total_localtax2)) {
 
 4409       $this->total_localtax2 = 0;
 
 4411     if (empty($this->localtax1_type)) {
 
 4412       $this->localtax1_type = 0;
 
 4414     if (empty($this->localtax2_type)) {
 
 4415       $this->localtax2_type = 0;
 
 4417     if (empty($this->marque_tx)) {
 
 4418       $this->marque_tx = 0;
 
 4420     if (empty($this->marge_tx)) {
 
 4421       $this->marge_tx = 0;
 
 4423     if (empty($this->
price)) {
 
 4426     if (empty($this->remise_percent)) {
 
 4427       $this->remise_percent = 0;
 
 4429     if (empty($this->info_bits)) {
 
 4430       $this->info_bits = 0;
 
 4432     if (empty($this->special_code)) {
 
 4433       $this->special_code = 0;
 
 4435     if (empty($this->fk_parent_line)) {
 
 4436       $this->fk_parent_line = 0;
 
 4438     if (empty($this->fk_fournprice)) {
 
 4439       $this->fk_fournprice = 0;
 
 4441     if (empty($this->subprice)) {
 
 4442       $this->subprice = 0;
 
 4444     if (empty($this->pa_ht)) {
 
 4449     if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
 
 4450       if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
 
 4453         $this->pa_ht = $result;
 
 4460     $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
 
 4461     $sql .= 
" description='".$this->db->escape($this->desc).
"'";
 
 4462     $sql .= 
", label=".(!empty($this->label) ? 
"'".$this->db->escape($this->label).
"'" : 
"null");
 
 4463     $sql .= 
", product_type=".$this->product_type;
 
 4464     $sql .= 
", vat_src_code = '".(empty($this->vat_src_code) ? 
'' : $this->vat_src_code).
"'";
 
 4465     $sql .= 
", tva_tx='".price2num($this->tva_tx).
"'";
 
 4466     $sql .= 
", localtax1_tx=".price2num($this->localtax1_tx);
 
 4467     $sql .= 
", localtax2_tx=".price2num($this->localtax2_tx);
 
 4468     $sql .= 
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
 
 4469     $sql .= 
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
 
 4470     $sql .= 
", qty='".price2num($this->qty).
"'";
 
 4471     $sql .= 
", subprice=".price2num($this->subprice);
 
 4472     $sql .= 
", remise_percent=".price2num($this->remise_percent);
 
 4474     $sql .= 
", remise=".(float) 
price2num($this->remise); 
 
 4475     $sql .= 
", info_bits='".$this->db->escape($this->info_bits).
"'";
 
 4476     if (empty($this->skip_update_total)) {
 
 4477       $sql .= 
", total_ht=".price2num($this->total_ht);
 
 4478       $sql .= 
", total_tva=".price2num($this->total_tva);
 
 4479       $sql .= 
", total_ttc=".price2num($this->total_ttc);
 
 4480       $sql .= 
", total_localtax1=".price2num($this->total_localtax1);
 
 4481       $sql .= 
", total_localtax2=".price2num($this->total_localtax2);
 
 4483     $sql .= 
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ? 
"'".$this->db->escape($this->fk_fournprice).
"'" : 
"null");
 
 4484     $sql .= 
", buy_price_ht=".price2num($this->pa_ht);
 
 4485     if (strlen($this->special_code)) {
 
 4486       $sql .= 
", special_code=".$this->special_code;
 
 4488     $sql .= 
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line : 
"null");
 
 4489     if (!empty($this->rang)) {
 
 4490       $sql .= 
", rang=".((int) $this->rang);
 
 4492     $sql .= 
", date_start=".(!empty($this->date_start) ? 
"'".$this->db->idate($this->date_start).
"'" : 
"null");
 
 4493     $sql .= 
", date_end=".(!empty($this->date_end) ? 
"'".$this->db->idate($this->date_end).
"'" : 
"null");
 
 4494     $sql .= 
", fk_unit=".(!$this->fk_unit ? 
'NULL' : $this->fk_unit);
 
 4497     $sql .= 
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
 
 4498     $sql .= 
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
 
 4499     $sql .= 
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
 
 4500     $sql .= 
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
 
 4502     $sql .= 
" WHERE rowid = ".((int) $this->
id);
 
 4504     dol_syslog(get_class($this).
"::update", LOG_DEBUG);
 
 4514       if (!$error && !$notrigger) {
 
 4516         $result = $this->
call_trigger(
'LINEPROPAL_MODIFY', $user);
 
 4518           $this->
db->rollback();
 
 4524       $this->
db->commit();
 
 4527       $this->error = $this->
db->error();
 
 4528       $this->
db->rollback();
 
 4546     $sql = 
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
 
 4547     $sql .= 
" total_ht=".price2num($this->total_ht, 
'MT');
 
 4548     $sql .= 
",total_tva=".price2num($this->total_tva, 
'MT');
 
 4549     $sql .= 
",total_ttc=".price2num($this->total_ttc, 
'MT');
 
 4550     $sql .= 
" WHERE rowid = ".((int) $this->
rowid);
 
 4552     dol_syslog(
"PropaleLigne::update_total", LOG_DEBUG);
 
 4556       $this->
db->commit();
 
 4559       $this->error = $this->
db->error();
 
 4560       $this->
db->rollback();
 
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true)
Save a new position (field rang) for details lines.
deleteEcmFiles($mode=0)
Delete related files of object in database.
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
defineBuyPrice($unitPrice=0.0, $discountPercent=0.0, $fk_product=0)
Get buy price to use for margin calculation.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check an object id/ref exists If you don't need/want to instantiate object and just need to know if o...
updateRangOfLine($rowid, $rang)
Update position of line (rang)
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='', $f_user=null, $notrigger=0)
Delete all links between an object $this.
update_price($exclspec=0, $roundingadjust='none', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
deleteExtraFields()
Delete all extra fields values for the current object.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
fetchObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $clause='OR', $alsosametype=1, $orderby='sourcetype', $loadalsoobjects=1)
Fetch array of objects linked to current object (object of enabled modules only).
static commonReplaceProduct(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product id with another one.
line_max($fk_parent_line=0)
Get max value used for position of line (rang)
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage absolute discounts.
Class to manage Dolibarr database access.
static getIdFromCode($dbs, $code)
Get id of currency from code.
static getIdAndTxFromCode($dbs, $code, $date_document='')
Get id and rate of currency from code.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
File of class to manage predefined price products or services by customer.
Class to manage proposals.
const STATUS_DRAFT
Draft status.
fetch_lines($only_product=0, $loadalsotranslation=0, $filters='')
Load array lines.
set_date($user, $date, $notrigger=0)
Define proposal date.
const STATUS_SIGNED
Signed quote.
getNomUrl($withpicto=0, $option='', $get_params='', $notooltip=0, $save_lastsearch_value=-1, $addlinktonotes=-1)
Return clicable link of object (with eventually picto)
InvoiceArrayList($id)
Returns an array with id and ref of related invoices.
availability($availability_id, $notrigger=0)
Change the delivery time.
const STATUS_NOTSIGNED
Not signed quote.
setDeliveryDate($user, $delivery_date, $notrigger=0)
Set delivery date.
load_state_board()
Charge indicateurs this->nb de tableau de bord.
set_remise_percent($user, $remise, $notrigger=0)
Set an overall discount on the proposal.
classifyBilled(User $user, $notrigger=0, $note='')
Classify the proposal to status Billed.
fetch($rowid, $ref='', $ref_ext='', $forceentity=0)
Load a proposal from database.
set_availability($user, $id, $notrigger=0)
Set delivery.
update(User $user, $notrigger=0)
Update database.
demand_reason($demand_reason_id, $notrigger=0)
Change source demand.
info($id)
Object Proposal Information.
const STATUS_BILLED
Billed or processed quote.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
getLibStatut($mode=0)
Return label of status of proposal (draft, validated, ...)
getLinesArray($filters='')
Retrieve an array of proposal lines.
insert_discount($idremise)
Adding line of fixed discount in the proposal in DB.
getNextNumRef($soc)
Returns the reference to the following non used Proposal used depending on the active numbering modul...
LibStatut($status, $mode=1)
Return label of a status (draft, validated, ...)
valid($user, $notrigger=0)
Set status to validated.
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
set_ref_client($user, $ref_client, $notrigger=0)
Set customer reference number.
setDraft($user, $notrigger=0)
Set draft status.
set_echeance($user, $date_end_validity, $notrigger=0)
Define end validity date.
set_demand_reason($user, $id, $notrigger=0)
Set source of demand.
set_remise_absolue($user, $remise, $notrigger=0)
Set an absolute overall discount on the proposal.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
deleteline($lineid, $id=0)
Delete detail line.
create($user, $notrigger=0)
Create commercial proposal into database this->ref can be set or empty.
liste_array($shortlist=0, $draft=0, $notcurrentuser=0, $socid=0, $limit=0, $offset=0, $sortfield='p.datep', $sortorder='DESC')
Return list of proposal (eventually filtered on user) into an array.
add_product($idproduct, $qty, $remise_percent=0)
Add line into array ->lines $this->thirdparty should be loaded.
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, $noupdateafterinsertline=0)
Add a proposal line into database (linked to product/service or not) The parameters are already suppo...
initAsSpecimen()
Initialise an instance with random values.
closeProposal($user, $status, $note='', $notrigger=0)
Close/set the commercial proposal to status signed or refused (fill also date signature)
reopen($user, $status, $note='', $notrigger=0)
Reopen the commercial proposal.
__construct($db, $socid=0, $propalid=0)
Constructor.
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
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, $rang=0)
Update a proposal line.
createFromClone(User $user, $socid=0, $forceentity=null, $update_prices=false)
Load an object from its id and create a new one in database.
getInvoiceArrayList()
Returns an array with the numbers of related invoices.
set_date_livraison($user, $delivery_date, $notrigger=0)
Set delivery date.
const STATUS_VALIDATED
Validated status.
Class to manage commercial proposal lines.
__construct($db)
Class line Contructor.
update($notrigger=0)
Update propal line object into DB.
fetch($rowid)
Retrieve the propal line object.
insert($notrigger=0)
Insert object line propal in database.
update_total()
Update DB line fields total_xxx Used by migration.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
trait CommonIncoterm
Superclass for incoterm classes.
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_delete_preview($object)
Delete all preview files linked to object instance.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Fonction qui renvoie si tva doit etre tva percue recuperable.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller="", $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
div float
Buy price without taxes.
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array='', $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.
$conf db
API class for accounts.