41require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
42require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobjectline.class.php";
43require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
44require_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
46require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
47require_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;
146 public $date_creation;
157 public $date_validation;
162 public $date_signature;
167 public $user_signature;
184 public $date_livraison;
189 public $delivery_date;
192 public $fin_validite;
194 public $user_author_id;
195 public $user_close_id;
213 public $cond_reglement_code;
214 public $cond_reglement_doc;
215 public $mode_reglement_code;
217 public $deposit_percent;
239 public $address_type;
242 public $availability_id;
243 public $availability_code;
245 public $duree_validite;
247 public $demand_reason_id;
248 public $demand_reason_code;
250 public $warehouse_id;
252 public $extraparams = array();
257 public $lines = array();
260 public $labelStatus = array();
261 public $labelStatusShort = array();
267 public $fk_multicurrency;
269 public $multicurrency_code;
270 public $multicurrency_tx;
271 public $multicurrency_total_ht;
272 public $multicurrency_total_tva;
273 public $multicurrency_total_ttc;
274 public $multicurrency_total_localtax1;
275 public $multicurrency_total_localtax2;
306 public $fields = array(
307 'rowid' =>array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
308 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>15,
'index'=>1),
309 'ref' =>array(
'type'=>
'varchar(30)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>20),
310 'ref_client' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefCustomer',
'enabled'=>1,
'visible'=>-1,
'position'=>22),
311 'ref_ext' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefExt',
'enabled'=>1,
'visible'=>0,
'position'=>40),
312 'fk_soc' =>array(
'type'=>
'integer:Societe:societe/class/societe.class.php',
'label'=>
'ThirdParty',
'enabled'=>
'isModEnabled("societe")',
'visible'=>-1,
'position'=>23),
313 '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),
314 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>25),
315 'datec' =>array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
316 'datep' =>array(
'type'=>
'date',
'label'=>
'Date',
'enabled'=>1,
'visible'=>-1,
'position'=>60),
317 'fin_validite' =>array(
'type'=>
'datetime',
'label'=>
'DateEnd',
'enabled'=>1,
'visible'=>-1,
'position'=>65),
318 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'DateValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>70),
319 'date_cloture' =>array(
'type'=>
'datetime',
'label'=>
'DateClosing',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
320 'fk_user_author' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
321 'fk_user_modif' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'position'=>85),
322 'fk_user_valid' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
323 'fk_user_cloture' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Fk user cloture',
'enabled'=>1,
'visible'=>-1,
'position'=>95),
324 'price' =>array(
'type'=>
'double',
'label'=>
'Price',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
328 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalHT',
'enabled'=>1,
'visible'=>-1,
'position'=>125,
'isameasure'=>1),
329 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'VAT',
'enabled'=>1,
'visible'=>-1,
'position'=>130,
'isameasure'=>1),
330 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'LocalTax1',
'enabled'=>1,
'visible'=>-1,
'position'=>135,
'isameasure'=>1),
331 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'LocalTax2',
'enabled'=>1,
'visible'=>-1,
'position'=>140,
'isameasure'=>1),
332 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalTTC',
'enabled'=>1,
'visible'=>-1,
'position'=>145,
'isameasure'=>1),
333 'fk_account' =>array(
'type'=>
'integer',
'label'=>
'BankAccount',
'enabled'=>
'isModEnabled("banque")',
'visible'=>-1,
'position'=>150),
334 'fk_currency' =>array(
'type'=>
'varchar(3)',
'label'=>
'Currency',
'enabled'=>1,
'visible'=>-1,
'position'=>155),
335 'fk_cond_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentTerm',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
336 'deposit_percent' =>array(
'type'=>
'varchar(63)',
'label'=>
'DepositPercent',
'enabled'=>1,
'visible'=>-1,
'position'=>161),
337 'fk_mode_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentMode',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
338 'note_private' =>array(
'type'=>
'html',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>170),
339 'note_public' =>array(
'type'=>
'html',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>175),
340 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'PDFTemplate',
'enabled'=>1,
'visible'=>0,
'position'=>180),
341 'date_livraison' =>array(
'type'=>
'date',
'label'=>
'DateDeliveryPlanned',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
342 'fk_shipping_method' =>array(
'type'=>
'integer',
'label'=>
'ShippingMethod',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
343 'fk_warehouse' =>array(
'type'=>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label'=>
'Fk warehouse',
'enabled'=>
'isModEnabled("stock")',
'visible'=>-1,
'position'=>191),
344 'fk_availability' =>array(
'type'=>
'integer',
'label'=>
'Availability',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
345 'fk_delivery_address' =>array(
'type'=>
'integer',
'label'=>
'DeliveryAddress',
'enabled'=>1,
'visible'=>0,
'position'=>200),
346 'fk_input_reason' =>array(
'type'=>
'integer',
'label'=>
'InputReason',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
347 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>215),
348 'fk_incoterms' =>array(
'type'=>
'integer',
'label'=>
'IncotermCode',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>220),
349 'location_incoterms' =>array(
'type'=>
'varchar(255)',
'label'=>
'IncotermLabel',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>225),
350 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'MulticurrencyID',
'enabled'=>1,
'visible'=>-1,
'position'=>230),
351 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'MulticurrencyCurrency',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>235),
352 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyRate',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>240,
'isameasure'=>1),
353 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountHT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>245,
'isameasure'=>1),
354 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountVAT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>250,
'isameasure'=>1),
355 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountTTC',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>255,
'isameasure'=>1),
356 'last_main_doc' =>array(
'type'=>
'varchar(255)',
'label'=>
'LastMainDoc',
'enabled'=>1,
'visible'=>-1,
'position'=>260),
357 'fk_statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Status',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
358 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>900),
393 global $conf, $langs;
397 $this->socid = $socid;
398 $this->
id = $propalid;
400 $this->duree_validite =
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
419 global $conf, $mysoc;
425 dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
426 if ($idproduct > 0) {
427 $prod =
new Product($this->db);
428 $prod->fetch($idproduct);
430 $productdesc = $prod->description;
434 if (empty($tva_tx)) {
439 $localtax1_tx =
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
440 $localtax2_tx =
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
443 if ($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
444 $price = $prod->multiprices[$this->thirdparty->price_level];
451 $line->fk_product = $idproduct;
452 $line->desc = $productdesc;
456 $line->vat_src_code = $vat_src_code;
457 $line->tva_tx = $tva_tx;
458 $line->fk_unit = $prod->fk_unit;
460 $line->info_bits = 1;
463 $this->lines[] = $line;
481 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
482 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
487 $result =
$remise->fetch($idremise);
491 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
492 $this->db->rollback();
498 $this->line->context = $this->context;
500 $line->fk_propal = $this->id;
501 $line->fk_remise_except =
$remise->id;
502 $line->desc =
$remise->description;
503 $line->vat_src_code =
$remise->vat_src_code;
504 $line->tva_tx =
$remise->tva_tx;
505 $line->subprice = -
$remise->amount_ht;
506 $line->fk_product = 0;
508 $line->remise_percent = 0;
510 $line->info_bits = 2;
513 $line->price = -
$remise->amount_ht;
515 $line->total_ht = -
$remise->amount_ht;
516 $line->total_tva = -
$remise->amount_tva;
517 $line->total_ttc = -
$remise->amount_ttc;
519 $result = $line->insert();
526 $this->db->rollback();
530 $this->error = $line->error;
531 $this->errors = $line->errors;
532 $this->db->rollback();
536 $this->db->rollback();
578 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)
580 global $mysoc, $conf, $langs;
582 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);
584 if ($this->
statut == self::STATUS_DRAFT) {
585 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
594 if (empty($info_bits)) {
600 if (empty($fk_parent_line) || $fk_parent_line < 0) {
607 $pu_ht_devise =
price2num($pu_ht_devise);
609 if (!preg_match(
'/\((.*)\)/', $txtva)) {
615 if ($price_base_type ==
'HT') {
626 if ($date_start && $date_end && $date_start > $date_end) {
627 $langs->load(
"errors");
628 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
634 $product_type = $type;
635 if (!empty($fk_product) && $fk_product > 0) {
636 $product =
new Product($this->db);
637 $result = $product->fetch($fk_product);
638 $product_type = $product->type;
640 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL) && $product_type == 0 && $product->stock_reel < $qty) {
641 $langs->load(
"errors");
642 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
643 $this->db->rollback();
659 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
660 $vat_src_code = $reg[1];
661 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
664 $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);
666 $total_ht = $tabprice[0];
667 $total_tva = $tabprice[1];
668 $total_ttc = $tabprice[2];
669 $total_localtax1 = $tabprice[9];
670 $total_localtax2 = $tabprice[10];
671 $pu_ht = $tabprice[3];
672 $pu_tva = $tabprice[4];
673 $pu_ttc = $tabprice[5];
676 $multicurrency_total_ht = $tabprice[16];
677 $multicurrency_total_tva = $tabprice[17];
678 $multicurrency_total_ttc = $tabprice[18];
679 $pu_ht_devise = $tabprice[19];
683 if ($ranktouse == -1) {
684 $rangmax = $this->
line_max($fk_parent_line);
685 $ranktouse = $rangmax + 1;
700 $this->line->context = $this->context;
702 $this->line->fk_propal = $this->id;
703 $this->line->label = $label;
704 $this->line->desc = $desc;
705 $this->line->qty = $qty;
707 $this->line->vat_src_code = $vat_src_code;
708 $this->line->tva_tx = $txtva;
709 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
710 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
711 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
712 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
713 $this->line->fk_product = $fk_product;
714 $this->line->product_type = $type;
715 $this->line->fk_remise_except = $fk_remise_except;
717 $this->line->subprice = $pu_ht;
718 $this->line->rang = $ranktouse;
719 $this->line->info_bits = $info_bits;
720 $this->line->total_ht = $total_ht;
721 $this->line->total_tva = $total_tva;
722 $this->line->total_localtax1 = $total_localtax1;
723 $this->line->total_localtax2 = $total_localtax2;
724 $this->line->total_ttc = $total_ttc;
725 $this->line->special_code = $special_code;
726 $this->line->fk_parent_line = $fk_parent_line;
727 $this->line->fk_unit = $fk_unit;
729 $this->line->date_start = $date_start;
730 $this->line->date_end = $date_end;
732 $this->line->fk_fournprice = $fk_fournprice;
733 $this->line->pa_ht = $pa_ht;
735 $this->line->origin_id = $origin_id;
736 $this->line->origin = $origin;
739 $this->line->fk_multicurrency = $this->fk_multicurrency;
740 $this->line->multicurrency_code = $this->multicurrency_code;
741 $this->line->multicurrency_subprice = $pu_ht_devise;
742 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
743 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
744 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
747 if (empty($qty) && empty($special_code)) {
748 $this->line->special_code = 3;
752 $this->line->price =
$price;
754 if (is_array($array_options) && count($array_options) > 0) {
755 $this->line->array_options = $array_options;
758 $result = $this->line->insert();
761 if (!empty($fk_parent_line)) {
763 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
764 $linecount = count($this->lines);
765 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
771 if (empty($noupdateafterinsertline)) {
777 return $this->line->id;
779 $this->error = $this->db->error();
780 $this->db->rollback();
784 $this->error = $this->line->error;
785 $this->errors = $this->line->errors;
786 $this->db->rollback();
790 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
825 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)
827 global $mysoc, $langs;
829 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
830 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");
831 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
837 $pu_ht_devise =
price2num($pu_ht_devise);
838 if (!preg_match(
'/\((.*)\)/', $txtva)) {
844 if (empty($qty) && empty($special_code)) {
847 if (!empty($qty) && $special_code == 3) {
854 if ($date_start && $date_end && $date_start > $date_end) {
855 $langs->load(
"errors");
856 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
860 if ($this->
statut == self::STATUS_DRAFT) {
873 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
874 $vat_src_code = $reg[1];
875 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
880 $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);
881 $total_ht = $tabprice[0];
882 $total_tva = $tabprice[1];
883 $total_ttc = $tabprice[2];
884 $total_localtax1 = $tabprice[9];
885 $total_localtax2 = $tabprice[10];
886 $pu_ht = $tabprice[3];
887 $pu_tva = $tabprice[4];
888 $pu_ttc = $tabprice[5];
891 $multicurrency_total_ht = $tabprice[16];
892 $multicurrency_total_tva = $tabprice[17];
893 $multicurrency_total_ttc = $tabprice[18];
894 $pu_ht_devise = $tabprice[19];
906 $line->fetch($rowid);
908 $staticline = clone $line;
910 $line->oldline = $staticline;
912 $this->line->context = $this->context;
913 $this->line->rang = $rang;
916 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
917 $rangmax = $this->
line_max($fk_parent_line);
918 $this->line->rang = $rangmax + 1;
921 $this->line->id = $rowid;
922 $this->line->label = $label;
923 $this->line->desc = $desc;
924 $this->line->qty = $qty;
925 $this->line->product_type = $type;
926 $this->line->vat_src_code = $vat_src_code;
927 $this->line->tva_tx = $txtva;
928 $this->line->localtax1_tx = $txlocaltax1;
929 $this->line->localtax2_tx = $txlocaltax2;
930 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
931 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
933 $this->line->subprice = $pu_ht;
934 $this->line->info_bits = $info_bits;
936 $this->line->total_ht = $total_ht;
937 $this->line->total_tva = $total_tva;
938 $this->line->total_localtax1 = $total_localtax1;
939 $this->line->total_localtax2 = $total_localtax2;
940 $this->line->total_ttc = $total_ttc;
941 $this->line->special_code = $special_code;
942 $this->line->fk_parent_line = $fk_parent_line;
943 $this->line->skip_update_total = $skip_update_total;
944 $this->line->fk_unit = $fk_unit;
946 $this->line->fk_fournprice = $fk_fournprice;
947 $this->line->pa_ht = $pa_ht;
949 $this->line->date_start = $date_start;
950 $this->line->date_end = $date_end;
952 if (is_array($array_options) && count($array_options) > 0) {
954 foreach ($array_options as $key => $value) {
955 $this->line->array_options[$key] = $array_options[$key];
960 $this->line->multicurrency_subprice = $pu_ht_devise;
961 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
962 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
963 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
965 $result = $this->line->update($notrigger);
968 if (!empty($fk_parent_line)) {
974 $this->fk_propal = $this->id;
975 $this->
rowid = $rowid;
980 $this->error = $this->line->error;
981 $this->errors = $this->line->errors;
982 $this->db->rollback();
986 dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
1003 if ($this->
statut == self::STATUS_DRAFT) {
1008 $line->context = $this->context;
1011 $line->fetch($lineid);
1013 if ($id > 0 && $line->fk_propal != $id) {
1014 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
1019 $staticline = clone $line;
1020 $line->oldline = $staticline;
1022 if ($line->delete($user) > 0) {
1025 $this->db->commit();
1028 $this->error = $line->error;
1029 $this->errors = $line->errors;
1030 $this->db->rollback();
1034 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1048 public function create($user, $notrigger = 0)
1050 global $conf, $hookmanager, $mysoc;
1056 if (empty($this->date)) {
1059 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1060 if (empty($this->availability_id)) {
1061 $this->availability_id = 0;
1063 if (empty($this->demand_reason_id)) {
1064 $this->demand_reason_id = 0;
1068 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1073 if (empty($this->fk_multicurrency)) {
1074 $this->multicurrency_code = $conf->currency;
1075 $this->fk_multicurrency = 0;
1076 $this->multicurrency_tx = 1;
1080 $delivery_date = empty($this->delivery_date) ? $this->date_livraison : $this->delivery_date;
1087 $this->error =
"Failed to fetch company";
1088 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1093 if (!empty($this->
ref)) {
1096 $this->error =
'ErrorRefAlreadyExists';
1097 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1098 $this->db->rollback();
1103 if (empty($this->date)) {
1104 $this->error =
"Date of proposal is required";
1105 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1113 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
1117 $sql .=
", remise_percent";
1118 $sql .=
", remise_absolue";
1119 $sql .=
", total_tva";
1120 $sql .=
", total_ttc";
1124 $sql .=
", fk_user_author";
1125 $sql .=
", note_private";
1126 $sql .=
", note_public";
1127 $sql .=
", model_pdf";
1128 $sql .=
", fin_validite";
1129 $sql .=
", fk_cond_reglement";
1130 $sql .=
", deposit_percent";
1131 $sql .=
", fk_mode_reglement";
1132 $sql .=
", fk_account";
1133 $sql .=
", ref_client";
1134 $sql .=
", ref_ext";
1135 $sql .=
", date_livraison";
1136 $sql .=
", fk_shipping_method";
1137 $sql .=
", fk_warehouse";
1138 $sql .=
", fk_availability";
1139 $sql .=
", fk_input_reason";
1140 $sql .=
", fk_projet";
1141 $sql .=
", fk_incoterms";
1142 $sql .=
", location_incoterms";
1144 $sql .=
", fk_multicurrency";
1145 $sql .=
", multicurrency_code";
1146 $sql .=
", multicurrency_tx";
1148 $sql .=
" VALUES (";
1149 $sql .= $this->socid;
1151 $sql .=
", ".((float) $this->remise);
1152 $sql .=
", ".($this->remise_percent ? ((float) $this->remise_percent) :
'NULL');
1153 $sql .=
", ".($this->remise_absolue ? ((float) $this->remise_absolue) :
'NULL');
1156 $sql .=
", '".$this->db->idate($this->date).
"'";
1157 $sql .=
", '".$this->db->idate($now).
"'";
1158 $sql .=
", '(PROV)'";
1159 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1160 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1161 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1162 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1163 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1164 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1165 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1166 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1167 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1168 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1169 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1170 $sql .=
", ".(empty($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1171 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1172 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1173 $sql .=
", ".$this->availability_id;
1174 $sql .=
", ".$this->demand_reason_id;
1175 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1176 $sql .=
", ".(int) $this->fk_incoterms;
1177 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1178 $sql .=
", ".setEntity($this);
1179 $sql .=
", ".(int) $this->fk_multicurrency;
1180 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1181 $sql .=
", ".(double) $this->multicurrency_tx;
1184 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1185 $resql = $this->db->query($sql);
1187 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1190 $this->
ref =
'(PROV'.$this->id.
')';
1191 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1193 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1194 $resql = $this->db->query($sql);
1199 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1200 $this->linked_objects = $this->linkedObjectsIds;
1204 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1205 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1206 if (is_array($tmp_origin_id)) {
1207 foreach ($tmp_origin_id as $origin_id) {
1210 $this->error = $this->db->lasterror();
1216 $origin_id = $tmp_origin_id;
1219 $this->error = $this->db->lasterror();
1231 $fk_parent_line = 0;
1232 $num = count($this->lines);
1234 for ($i = 0; $i < $num; $i++) {
1235 if (!is_object($this->lines[$i])) {
1237 $line = (object) $this->lines[$i];
1239 $line = $this->lines[$i];
1242 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1243 $fk_parent_line = 0;
1246 $vatrate = $line->tva_tx;
1247 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1248 $vatrate .=
' ('.$line->vat_src_code.
')';
1251 if (!empty($conf->global->MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION)) {
1252 $originid = $line->origin_id;
1253 $origintype = $line->origin;
1255 $originid = $line->id;
1256 $origintype = $this->element;
1264 $line->localtax1_tx,
1265 $line->localtax2_tx,
1267 $line->remise_percent,
1271 $line->product_type,
1273 $line->special_code,
1275 $line->fk_fournprice,
1280 $line->array_options,
1291 $this->error = $this->db->error;
1297 $line->id = $result;
1300 if ($result > 0 && $line->product_type == 9) {
1301 $fk_parent_line = $result;
1331 if (!$error && !$notrigger) {
1340 $this->error = $this->db->lasterror();
1345 $this->error = $this->db->lasterror();
1350 $this->db->commit();
1351 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1354 $this->db->rollback();
1358 $this->error = $this->db->lasterror();
1359 $this->db->rollback();
1374 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1376 global $conf, $hookmanager, $mysoc;
1385 $object =
new self($this->db);
1390 $object->fetch($this->
id);
1392 $objsoc =
new Societe($this->db);
1395 if (!empty($socid) && $socid != $object->socid) {
1396 if ($objsoc->fetch($socid) > 0) {
1397 $object->socid = $objsoc->id;
1398 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1399 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1400 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1401 $object->fk_delivery_address =
'';
1413 $object->fk_project =
'';
1418 $object->ref_client =
'';
1423 $objsoc->fetch($object->socid);
1427 if ($update_prices ===
true || $update_desc ===
true) {
1428 if ($objsoc->id > 0 && !empty($object->lines)) {
1429 if ($update_prices ===
true && !empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1431 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1434 foreach ($object->lines as $line) {
1437 if ($line->fk_product > 0) {
1438 $prod =
new Product($this->db);
1439 $res = $prod->fetch($line->fk_product);
1441 if ($update_prices ===
true) {
1442 $pu_ht = $prod->price;
1446 if (!empty($conf->global->PRODUIT_MULTIPRICES) && $objsoc->price_level > 0) {
1447 $pu_ht = $prod->multiprices[$objsoc->price_level];
1448 if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) {
1449 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1450 $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
1453 } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1455 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1456 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1459 if (count($prodcustprice->lines) > 0) {
1460 $pu_ht =
price($prodcustprice->lines[0]->price);
1461 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1462 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1463 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1469 $line->subprice = $pu_ht;
1470 $line->tva_tx = $tva_tx;
1473 if ($update_desc ===
true) {
1474 $line->desc = $prod->description;
1484 $object->entity = (!empty($forceentity) ? $forceentity : $object->entity);
1488 $object->user_author = $user->id;
1490 $object->user_validation_id = 0;
1492 $object->date = $now;
1493 $object->datep = $now;
1494 $object->fin_validite = $object->date + ($object->duree_validite * 24 * 3600);
1495 if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) {
1496 $object->ref_client =
'';
1499 $object->note_private =
'';
1500 $object->note_public =
'';
1503 $object->context[
'createfromclone'] =
'createfromclone';
1504 $result = $object->create($user);
1506 $this->error = $object->error;
1507 $this->errors = array_merge($this->errors, $object->errors);
1513 if ($object->copy_linked_contact($this,
'internal') < 0) {
1520 if ($this->socid == $object->socid) {
1521 if ($object->copy_linked_contact($this,
'external') < 0) {
1529 if (is_object($hookmanager)) {
1530 $parameters = array(
'objFrom'=>$this,
'clonedObj'=>$object);
1532 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1540 unset($object->context[
'createfromclone']);
1544 $this->db->commit();
1547 $this->db->rollback();
1561 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1563 $sql =
"SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc";
1564 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1565 $sql .=
", p.datec";
1566 $sql .=
", p.date_signature as dates";
1567 $sql .=
", p.date_valid as datev";
1568 $sql .=
", p.datep as dp";
1569 $sql .=
", p.fin_validite as dfv";
1570 $sql .=
", p.date_livraison as delivery_date";
1571 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1572 $sql .=
", p.note_private, p.note_public";
1573 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1574 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1575 $sql .=
", p.fk_delivery_address";
1576 $sql .=
", p.fk_availability";
1577 $sql .=
", p.fk_input_reason";
1578 $sql .=
", p.fk_cond_reglement";
1579 $sql .=
", p.fk_mode_reglement";
1580 $sql .=
', p.fk_account';
1581 $sql .=
", p.fk_shipping_method";
1582 $sql .=
", p.fk_warehouse";
1583 $sql .=
", p.fk_incoterms, p.location_incoterms";
1584 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1585 $sql .=
", p.tms as date_modification";
1586 $sql .=
", i.libelle as label_incoterms";
1587 $sql .=
", c.label as statut_label";
1588 $sql .=
", ca.code as availability_code, ca.label as availability";
1589 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1590 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1591 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1592 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1593 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1594 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1595 $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').
')';
1596 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1597 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1598 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1601 if (!empty($forceentity)) {
1602 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1604 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1606 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1609 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1612 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1613 $resql = $this->db->query($sql);
1615 if ($this->db->num_rows($resql)) {
1616 $obj = $this->db->fetch_object($resql);
1618 $this->
id = $obj->rowid;
1619 $this->entity = $obj->entity;
1621 $this->
ref = $obj->ref;
1622 $this->ref_client = $obj->ref_client;
1623 $this->ref_customer = $obj->ref_client;
1624 $this->ref_ext = $obj->ref_ext;
1626 $this->remise = $obj->remise;
1627 $this->remise_percent = $obj->remise_percent;
1628 $this->remise_absolue = $obj->remise_absolue;
1629 $this->total = $obj->total_ttc;
1630 $this->total_ttc = $obj->total_ttc;
1631 $this->total_ht = $obj->total_ht;
1632 $this->total_tva = $obj->total_tva;
1633 $this->total_localtax1 = $obj->localtax1;
1634 $this->total_localtax2 = $obj->localtax2;
1636 $this->socid = $obj->fk_soc;
1637 $this->thirdparty =
null;
1639 $this->fk_project = $obj->fk_project;
1640 $this->project =
null;
1642 $this->model_pdf = $obj->model_pdf;
1643 $this->modelpdf = $obj->model_pdf;
1644 $this->last_main_doc = $obj->last_main_doc;
1645 $this->note = $obj->note_private;
1646 $this->note_private = $obj->note_private;
1647 $this->note_public = $obj->note_public;
1649 $this->status = (int) $obj->fk_statut;
1650 $this->
statut = $this->status;
1652 $this->datec = $this->db->jdate($obj->datec);
1653 $this->datev = $this->db->jdate($obj->datev);
1654 $this->date_creation = $this->db->jdate($obj->datec);
1655 $this->date_validation = $this->db->jdate($obj->datev);
1656 $this->date_modification = $this->db->jdate($obj->date_modification);
1657 $this->date_signature = $this->db->jdate($obj->dates);
1658 $this->date = $this->db->jdate($obj->dp);
1659 $this->datep = $this->db->jdate($obj->dp);
1660 $this->fin_validite = $this->db->jdate($obj->dfv);
1661 $this->date_livraison = $this->db->jdate($obj->delivery_date);
1662 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1663 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1664 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1665 $this->availability_id = $obj->fk_availability;
1666 $this->availability_code = $obj->availability_code;
1668 $this->demand_reason_id = $obj->fk_input_reason;
1669 $this->demand_reason_code = $obj->demand_reason_code;
1671 $this->fk_address = $obj->fk_delivery_address;
1673 $this->mode_reglement_id = $obj->fk_mode_reglement;
1674 $this->mode_reglement_code = $obj->mode_reglement_code;
1675 $this->mode_reglement = $obj->mode_reglement;
1676 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1677 $this->cond_reglement_id = $obj->fk_cond_reglement;
1678 $this->cond_reglement_code = $obj->cond_reglement_code;
1679 $this->cond_reglement = $obj->cond_reglement;
1680 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1681 $this->deposit_percent = $obj->deposit_percent;
1683 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1685 $this->user_author_id = $obj->fk_user_author;
1686 $this->user_validation_id = $obj->fk_user_valid;
1687 $this->user_close_id = $obj->fk_user_cloture;
1690 $this->fk_incoterms = $obj->fk_incoterms;
1691 $this->location_incoterms = $obj->location_incoterms;
1692 $this->label_incoterms = $obj->label_incoterms;
1695 $this->fk_multicurrency = $obj->fk_multicurrency;
1696 $this->multicurrency_code = $obj->multicurrency_code;
1697 $this->multicurrency_tx = $obj->multicurrency_tx;
1698 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1699 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1700 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1702 if ($obj->fk_statut == self::STATUS_DRAFT) {
1703 $this->brouillon = 1;
1710 $this->db->free($resql);
1712 $this->lines = array();
1723 $this->error =
"Record Not Found";
1726 $this->error = $this->db->lasterror();
1745 if (isset($this->
ref)) {
1746 $this->
ref = trim($this->
ref);
1748 if (isset($this->ref_client)) {
1749 $this->ref_client = trim($this->ref_client);
1751 if (isset($this->note) || isset($this->note_private)) {
1752 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1754 if (isset($this->note_public)) {
1755 $this->note_public = trim($this->note_public);
1757 if (isset($this->model_pdf)) {
1758 $this->model_pdf = trim($this->model_pdf);
1760 if (isset($this->import_key)) {
1761 $this->import_key = trim($this->import_key);
1763 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1764 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1771 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1772 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1773 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1774 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1775 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1776 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1777 if (!empty($this->fin_validite)) {
1778 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1780 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1781 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1782 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1783 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1784 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1785 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1786 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->
statut :
"null").
",";
1787 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1788 $sql .=
" fk_user_valid = ".(!empty($this->user_validation_id) ? (int) $this->user_validation_id :
"null").
",";
1789 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1790 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1791 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1792 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1793 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1794 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1795 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1796 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1797 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1798 $sql .=
" WHERE rowid=".((int) $this->
id);
1802 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1803 $resql = $this->db->query($sql);
1806 $this->errors[] =
"Error ".$this->db->lasterror();
1816 if (!$error && !$notrigger) {
1827 foreach ($this->errors as $errmsg) {
1828 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1829 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1831 $this->db->rollback();
1834 $this->db->commit();
1850 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $filters =
'')
1853 global $langs, $conf;
1855 $this->lines = array();
1857 $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,';
1858 $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,';
1859 $sql .=
' d.fk_unit,';
1860 $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,';
1861 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1862 $sql .=
' d.date_start, d.date_end,';
1863 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1864 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1865 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1866 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1867 if ($only_product) {
1868 $sql .=
' AND p.fk_product_type = 0';
1873 $sql .=
' ORDER by d.rang';
1875 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1876 $result = $this->db->query($sql);
1878 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1880 $num = $this->db->num_rows($result);
1884 $objp = $this->db->fetch_object($result);
1888 $line->rowid = $objp->rowid;
1889 $line->id = $objp->rowid;
1890 $line->fk_propal = $objp->fk_propal;
1891 $line->fk_parent_line = $objp->fk_parent_line;
1892 $line->product_type = $objp->product_type;
1893 $line->label = $objp->custom_label;
1894 $line->desc = $objp->description;
1895 $line->description = $objp->description;
1896 $line->qty = $objp->qty;
1897 $line->vat_src_code = $objp->vat_src_code;
1898 $line->tva_tx = $objp->tva_tx;
1899 $line->localtax1_tx = $objp->localtax1_tx;
1900 $line->localtax2_tx = $objp->localtax2_tx;
1901 $line->localtax1_type = $objp->localtax1_type;
1902 $line->localtax2_type = $objp->localtax2_type;
1903 $line->subprice = $objp->subprice;
1904 $line->fk_remise_except = $objp->fk_remise_except;
1905 $line->remise_percent = $objp->remise_percent;
1906 $line->price = $objp->price;
1908 $line->info_bits = $objp->info_bits;
1909 $line->total_ht = $objp->total_ht;
1910 $line->total_tva = $objp->total_tva;
1911 $line->total_localtax1 = $objp->total_localtax1;
1912 $line->total_localtax2 = $objp->total_localtax2;
1913 $line->total_ttc = $objp->total_ttc;
1914 $line->fk_fournprice = $objp->fk_fournprice;
1915 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1916 $line->pa_ht = $marginInfos[0];
1917 $line->marge_tx = $marginInfos[1];
1918 $line->marque_tx = $marginInfos[2];
1919 $line->special_code = $objp->special_code;
1920 $line->rang = $objp->rang;
1922 $line->fk_product = $objp->fk_product;
1924 $line->ref = $objp->product_ref;
1925 $line->libelle = $objp->product_label;
1927 $line->product_ref = $objp->product_ref;
1928 $line->product_label = $objp->product_label;
1929 $line->product_desc = $objp->product_desc;
1930 $line->product_tobatch = $objp->product_tobatch;
1931 $line->product_barcode = $objp->product_barcode;
1933 $line->fk_product_type = $objp->fk_product_type;
1934 $line->fk_unit = $objp->fk_unit;
1935 $line->weight = $objp->weight;
1936 $line->weight_units = $objp->weight_units;
1937 $line->volume = $objp->volume;
1938 $line->volume_units = $objp->volume_units;
1940 $line->date_start = $this->db->jdate($objp->date_start);
1941 $line->date_end = $this->db->jdate($objp->date_end);
1944 $line->fk_multicurrency = $objp->fk_multicurrency;
1945 $line->multicurrency_code = $objp->multicurrency_code;
1946 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1947 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1948 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1949 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1951 $line->fetch_optionals();
1954 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1955 $tmpproduct =
new Product($this->db);
1956 $tmpproduct->fetch($objp->fk_product);
1957 $tmpproduct->getMultiLangs();
1959 $line->multilangs = $tmpproduct->multilangs;
1962 $this->lines[$i] = $line;
1967 $this->db->free($result);
1971 $this->error = $this->db->lasterror();
1983 public function valid($user, $notrigger = 0)
1987 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1992 if ($this->
statut == self::STATUS_VALIDATED) {
1993 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1997 if (!((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->creer))
1998 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->validate)))) {
1999 $this->error =
'ErrorPermissionDenied';
2000 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
2009 $soc =
new Societe($this->db);
2010 $soc->fetch($this->socid);
2013 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2020 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2021 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2022 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2025 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2026 $resql = $this->db->query($sql);
2033 if (!$error && !$notrigger) {
2035 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2043 $this->oldref = $this->ref;
2046 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2048 $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).
"'";
2049 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2050 $resql = $this->db->query($sql);
2053 $this->error = $this->db->lasterror();
2055 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2056 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2057 $resql = $this->db->query($sql);
2059 $error++; $this->error = $this->db->lasterror();
2065 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2066 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2067 if (!$error && file_exists($dirsource)) {
2068 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2069 if (@rename($dirsource, $dirdest)) {
2072 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2073 foreach ($listoffiles as $fileentry) {
2074 $dirsource = $fileentry[
'name'];
2075 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2076 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2077 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2078 @rename($dirsource, $dirdest);
2085 $this->brouillon = 0;
2087 $this->user_validation_id = $user->id;
2088 $this->datev = $now;
2090 $this->db->commit();
2093 $this->db->rollback();
2112 $this->error =
'ErrorBadParameter';
2113 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2117 if (!empty($user->rights->propal->creer)) {
2122 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2123 $sql .=
" WHERE rowid = ".((int) $this->
id);
2126 $resql = $this->db->query($sql);
2128 $this->errors[] = $this->db->error();
2133 $this->oldcopy = clone $this;
2134 $this->date = $date;
2135 $this->datep = $date;
2138 if (!$notrigger && empty($error)) {
2148 $this->db->commit();
2151 foreach ($this->errors as $errmsg) {
2152 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2153 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2155 $this->db->rollback();
2175 if (!empty($user->rights->propal->creer)) {
2180 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2181 $sql .=
" WHERE rowid = ".((int) $this->
id);
2185 $resql = $this->db->query($sql);
2187 $this->errors[] = $this->db->error();
2193 $this->oldcopy = clone $this;
2194 $this->fin_validite = $date_end_validity;
2197 if (!$notrigger && empty($error)) {
2207 $this->db->commit();
2210 foreach ($this->errors as $errmsg) {
2211 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2212 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2214 $this->db->rollback();
2248 if (!empty($user->rights->propal->creer)) {
2253 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2254 $sql .=
" SET date_livraison = ".($delivery_date !=
'' ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2255 $sql .=
" WHERE rowid = ".((int) $this->
id);
2258 $resql = $this->db->query($sql);
2260 $this->errors[] = $this->db->error();
2265 $this->oldcopy = clone $this;
2266 $this->date_livraison = $delivery_date;
2267 $this->delivery_date = $delivery_date;
2270 if (!$notrigger && empty($error)) {
2280 $this->db->commit();
2283 foreach ($this->errors as $errmsg) {
2284 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2285 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2287 $this->db->rollback();
2307 if (!empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) {
2312 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2313 $sql .=
" SET fk_availability = ".((int) $id);
2314 $sql .=
" WHERE rowid = ".((int) $this->
id);
2316 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2317 $resql = $this->db->query($sql);
2319 $this->errors[] = $this->db->error();
2324 $this->oldcopy = clone $this;
2325 $this->fk_availability = $id;
2326 $this->availability_id = $id;
2329 if (!$notrigger && empty($error)) {
2339 $this->db->commit();
2342 foreach ($this->errors as $errmsg) {
2343 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2344 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2346 $this->db->rollback();
2350 $error_str =
'Propal status do not meet requirement '.$this->statut;
2352 $this->error = $error_str;
2353 $this->errors[] = $this->error;
2370 if (!empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) {
2375 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2376 $sql .=
" SET fk_input_reason = ".((int) $id);
2377 $sql .=
" WHERE rowid = ".((int) $this->
id);
2380 $resql = $this->db->query($sql);
2382 $this->errors[] = $this->db->error();
2388 $this->oldcopy = clone $this;
2389 $this->fk_input_reason = $id;
2390 $this->demand_reason_id = $id;
2394 if (!$notrigger && empty($error)) {
2404 $this->db->commit();
2407 foreach ($this->errors as $errmsg) {
2408 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2409 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2411 $this->db->rollback();
2415 $error_str =
'Propal status do not meet requirement '.$this->statut;
2417 $this->error = $error_str;
2418 $this->errors[] = $this->error;
2435 if (!empty($user->rights->propal->creer)) {
2440 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2441 $sql .=
" WHERE rowid = ".((int) $this->
id);
2443 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2444 $resql = $this->db->query($sql);
2446 $this->errors[] = $this->db->error();
2451 $this->oldcopy = clone $this;
2452 $this->ref_client = $ref_client;
2455 if (!$notrigger && empty($error)) {
2465 $this->db->commit();
2468 foreach ($this->errors as $errmsg) {
2469 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2470 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2472 $this->db->rollback();
2495 if (!empty($user->rights->propal->creer)) {
2502 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET remise_percent = ".((float)
$remise);
2506 $resql = $this->db->query($sql);
2508 $this->errors[] = $this->db->error();
2513 $this->oldcopy = clone $this;
2514 $this->remise_percent =
$remise;
2518 if (!$notrigger && empty($error)) {
2528 $this->db->commit();
2531 foreach ($this->errors as $errmsg) {
2532 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2533 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2535 $this->db->rollback();
2561 if (!empty($user->rights->propal->creer)) {
2566 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2567 $sql .=
" SET remise_absolue = ".((float)
$remise);
2571 $resql = $this->db->query($sql);
2573 $this->errors[] = $this->db->error();
2578 $this->oldcopy = clone $this;
2582 if (!$notrigger && empty($error)) {
2592 $this->db->commit();
2595 foreach ($this->errors as $errmsg) {
2596 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2597 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2599 $this->db->rollback();
2622 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2623 $sql .=
" SET fk_statut = ".((int) $status).
",";
2624 if (!empty(
$note)) {
2625 $sql .=
" note_private = '".$this->db->escape(
$note).
"',";
2627 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2628 $sql .=
" WHERE rowid = ".((int) $this->
id);
2632 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2633 $resql = $this->db->query($sql);
2636 $this->errors[] =
"Error ".$this->db->lasterror();
2651 if (!empty($this->errors)) {
2652 foreach ($this->errors as $errmsg) {
2653 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2654 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2657 $this->db->rollback();
2661 $this->status = $status;
2663 $this->db->commit();
2679 global $langs,$conf;
2688 if (empty($conf->global->PROPALE_KEEP_OLD_SIGNATURE_INFO)) {
2689 $date_signature = $now;
2690 $fk_user_signature = $user->id;
2692 $this->
info($this->
id);
2693 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2694 $date_signature = $now;
2695 $fk_user_signature = $user->id;
2697 $date_signature = $this->date_signature;
2698 $fk_user_signature = $this->user_signature->id;
2702 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2703 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"'";
2704 if ($status == self::STATUS_SIGNED) {
2705 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2707 $sql .=
" WHERE rowid = ".((int) $this->
id);
2709 $resql = $this->db->query($sql);
2712 $modelpdf = !empty($conf->global->PROPALE_ADDON_PDF_ODT_CLOSED) ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2713 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2715 if ($status == self::STATUS_SIGNED) {
2716 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2717 $modelpdf = !empty($conf->global->PROPALE_ADDON_PDF_ODT_TOBILL) ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2721 $soc->id = $this->socid;
2722 $result = $soc->set_as_client();
2725 $this->error=$this->db->lasterror();
2726 $this->db->rollback();
2731 if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
2733 $outputlangs = $langs;
2735 $outputlangs =
new Translate(
"", $conf);
2736 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2737 $outputlangs->setDefaultLang($newlang);
2741 $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0);
2742 $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0);
2743 $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0);
2746 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2750 $this->oldcopy= clone $this;
2752 $this->status = $status;
2753 $this->date_signature = $date_signature;
2754 $this->note_private = $newprivatenote;
2757 if (!$notrigger && empty($error)) {
2767 $this->db->commit();
2770 $this->
statut = $this->oldcopy->statut;
2771 $this->status = $this->oldcopy->statut;
2772 $this->date_signature = $this->oldcopy->date_signature;
2773 $this->note_private = $this->oldcopy->note_private;
2775 $this->db->rollback();
2779 $this->error = $this->db->lasterror();
2780 $this->db->rollback();
2795 global $conf, $langs;
2802 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2808 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2809 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2810 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2813 $resql = $this->db->query($sql);
2815 $this->errors[] = $this->db->error();
2818 $num = $this->db->affected_rows($resql);
2822 $modelpdf = $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2824 if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
2826 $outputlangs = $langs;
2828 $outputlangs =
new Translate(
"", $conf);
2829 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2830 $outputlangs->setDefaultLang($newlang);
2834 $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0);
2835 $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0);
2836 $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0);
2839 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2842 $this->oldcopy = clone $this;
2844 $this->date_cloture = $now;
2845 $this->note_private = $newprivatenote;
2848 if (!$notrigger && empty($error)) {
2858 $this->db->commit();
2861 foreach ($this->errors as $errmsg) {
2862 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2863 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2865 $this->db->rollback();
2884 if ($this->
statut <= self::STATUS_DRAFT) {
2888 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2892 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2893 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2894 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2895 $sql .=
" WHERE rowid = ".((int) $this->
id);
2897 $resql = $this->db->query($sql);
2899 $this->errors[] = $this->db->error();
2904 $this->oldcopy = clone $this;
2907 if (!$notrigger && empty($error)) {
2918 $this->brouillon = 1;
2920 $this->db->commit();
2923 foreach ($this->errors as $errmsg) {
2924 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2925 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2927 $this->db->rollback();
2947 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2954 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2955 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2956 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2957 if (empty($user->rights->societe->client->voir) && !$socid) {
2958 $sql .=
", sc.fk_soc, sc.fk_user";
2960 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2961 if (empty($user->rights->societe->client->voir) && !$socid) {
2962 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
2964 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2965 $sql .=
" AND p.fk_soc = s.rowid";
2966 $sql .=
" AND p.fk_statut = c.id";
2967 if (empty($user->rights->societe->client->voir) && !$socid) {
2968 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
2971 $sql .=
" AND s.rowid = ".((int) $socid);
2974 $sql .=
" AND p.fk_statut = ".self::STATUS_DRAFT;
2976 if ($notcurrentuser > 0) {
2977 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2979 $sql .= $this->db->order($sortfield, $sortorder);
2980 $sql .= $this->db->plimit($limit, $offset);
2982 $result = $this->db->query($sql);
2984 $num = $this->db->num_rows($result);
2988 $obj = $this->db->fetch_object($result);
2990 if ($shortlist == 1) {
2991 $ga[$obj->propalid] = $obj->ref;
2992 } elseif ($shortlist == 2) {
2993 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2995 $ga[$i][
'id'] = $obj->propalid;
2996 $ga[$i][
'ref'] = $obj->ref;
2997 $ga[$i][
'name'] = $obj->name;
3031 $linkedInvoices = array();
3034 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
3037 foreach ($objectid as $key => $object) {
3039 if ($objecttype ==
'facture') {
3040 $linkedInvoices[] = $object;
3044 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
3045 foreach ($subobjectid as $subkey => $subobject) {
3046 if ($subobjecttype ==
'facture') {
3047 $linkedInvoices[] = $subobject;
3055 if (count($linkedInvoices) > 0) {
3056 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
3057 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
3058 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
3060 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
3061 $resql = $this->db->query($sql);
3064 $tab_sqlobj = array();
3065 $nump = $this->db->num_rows($resql);
3066 for ($i = 0; $i < $nump; $i++) {
3067 $sqlobj = $this->db->fetch_object($resql);
3068 $tab_sqlobj[] = $sqlobj;
3070 $this->db->free($resql);
3072 $nump = count($tab_sqlobj);
3076 while ($i < $nump) {
3077 $obj = array_shift($tab_sqlobj);
3100 public function delete($user, $notrigger = 0)
3103 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3119 if (!$error && !empty($this->table_element_line)) {
3120 $tabletodelete = $this->table_element_line;
3121 $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).
")";
3122 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3123 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3125 $this->error = $this->db->lasterror();
3126 $this->errors[] = $this->error;
3127 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3152 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3158 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3159 $res = $this->db->query($sql);
3162 $this->error = $this->db->lasterror();
3163 $this->errors[] = $this->error;
3164 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3179 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3180 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3181 $file = $dir.
"/".$ref.
".pdf";
3182 if (file_exists($file)) {
3186 $this->error =
'ErrorFailToDeleteFile';
3187 $this->errors[] = $this->error;
3188 $this->db->rollback();
3192 if (file_exists($dir)) {
3195 $this->error =
'ErrorFailToDeleteDir';
3196 $this->errors[] = $this->error;
3197 $this->db->rollback();
3205 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3206 $this->db->commit();
3209 $this->db->rollback();
3226 if ($this->
statut >= self::STATUS_DRAFT) {
3231 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3232 $sql .=
' SET fk_availability = '.((int) $availability_id);
3233 $sql .=
' WHERE rowid='.((int) $this->
id);
3235 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3236 $resql = $this->db->query($sql);
3238 $this->errors[] = $this->db->error();
3243 $this->oldcopy = clone $this;
3244 $this->availability_id = $availability_id;
3247 if (!$notrigger && empty($error)) {
3257 $this->db->commit();
3260 foreach ($this->errors as $errmsg) {
3261 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3262 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3264 $this->db->rollback();
3268 $error_str =
'Propal status do not meet requirement '.$this->statut;
3270 $this->error = $error_str;
3271 $this->errors[] = $this->error;
3290 if ($this->
statut >= self::STATUS_DRAFT) {
3295 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3296 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3297 $sql .=
' WHERE rowid='.((int) $this->
id);
3299 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3300 $resql = $this->db->query($sql);
3302 $this->errors[] = $this->db->error();
3307 $this->oldcopy = clone $this;
3308 $this->demand_reason_id = $demand_reason_id;
3311 if (!$notrigger && empty($error)) {
3321 $this->db->commit();
3324 foreach ($this->errors as $errmsg) {
3325 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3326 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3328 $this->db->rollback();
3332 $error_str =
'Propal status do not meet requirement '.$this->statut;
3334 $this->error = $error_str;
3335 $this->errors[] = $this->error;
3349 $sql =
"SELECT c.rowid, ";
3350 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3351 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3352 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3353 $sql .=
" WHERE c.rowid = ".((int) $id);
3355 $result = $this->db->query($sql);
3358 if ($this->db->num_rows($result)) {
3359 $obj = $this->db->fetch_object($result);
3361 $this->
id = $obj->rowid;
3363 $this->date_creation = $this->db->jdate($obj->datec);
3364 $this->date_validation = $this->db->jdate($obj->datev);
3365 $this->date_signature = $this->db->jdate($obj->date_signature);
3366 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3368 $cuser =
new User($this->db);
3369 $cuser->fetch($obj->fk_user_author);
3370 $this->user_creation = $cuser;
3372 if ($obj->fk_user_valid) {
3373 $this->user_validation_id = $obj->fk_user_valid;
3376 if ($obj->fk_user_signature) {
3377 $user_signature =
new User($this->db);
3378 $user_signature->fetch($obj->fk_user_signature);
3379 $this->user_signature = $user_signature;
3382 if ($obj->fk_user_cloture) {
3383 $cluser =
new User($this->db);
3384 $cluser->fetch($obj->fk_user_cloture);
3385 $this->user_cloture = $cluser;
3388 $this->db->free($result);
3417 global $conf, $hookmanager;
3420 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3422 $langs->load(
"propal");
3423 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3424 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3425 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3426 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3427 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3428 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3429 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3430 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3431 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3432 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3436 if ($status == self::STATUS_DRAFT) {
3437 $statusType =
'status0';
3438 } elseif ($status == self::STATUS_VALIDATED) {
3439 $statusType =
'status1';
3440 } elseif ($status == self::STATUS_SIGNED) {
3441 $statusType =
'status4';
3442 } elseif ($status == self::STATUS_NOTSIGNED) {
3443 $statusType =
'status9';
3444 } elseif ($status == self::STATUS_BILLED) {
3445 $statusType =
'status6';
3449 $parameters = array(
'status' => $status,
'mode' => $mode);
3450 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3453 return $hookmanager->resPrint;
3456 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3471 global $conf, $langs;
3475 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3476 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3477 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3478 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
3479 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3482 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3483 if ($mode ==
'opened') {
3484 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3486 if ($mode ==
'signed') {
3487 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3490 $sql .=
" AND p.fk_soc = ".((int) $user->socid);
3493 $resql = $this->db->query($sql);
3495 $langs->load(
"propal");
3500 $label = $labelShort =
'';
3501 if ($mode ==
'opened') {
3502 $delay_warning = $conf->propal->cloture->warning_delay;
3504 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3505 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3507 if ($mode ==
'signed') {
3508 $delay_warning = $conf->propal->facturation->warning_delay;
3510 $label = $langs->trans(
"PropalsToBill");
3511 $labelShort = $langs->trans(
"ToBill");
3515 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3516 $response->label = $label;
3517 $response->labelShort = $labelShort;
3518 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3519 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3523 while ($obj = $this->db->fetch_object($resql)) {
3524 $response->nbtodo++;
3525 $response->total += $obj->total_ht;
3527 if ($mode ==
'opened') {
3528 $datelimit = $this->db->jdate($obj->datefin);
3529 if ($datelimit < ($now - $delay_warning)) {
3530 $response->nbtodolate++;
3539 $this->error = $this->db->error();
3554 global $conf, $langs;
3559 $sql =
"SELECT rowid";
3560 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3561 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3562 $sql .= $this->db->plimit(100);
3564 $resql = $this->db->query($sql);
3566 $num_prods = $this->db->num_rows($resql);
3568 while ($i < $num_prods) {
3570 $row = $this->db->fetch_row($resql);
3571 $prodids[$i] = $row[0];
3577 $this->
ref =
'SPECIMEN';
3578 $this->ref_client =
'NEMICEPS';
3579 $this->specimen = 1;
3581 $this->date = time();
3582 $this->fin_validite = $this->date + 3600 * 24 * 30;
3583 $this->cond_reglement_id = 1;
3584 $this->cond_reglement_code =
'RECEP';
3585 $this->mode_reglement_id = 7;
3586 $this->mode_reglement_code =
'CHQ';
3587 $this->availability_id = 1;
3588 $this->availability_code =
'AV_NOW';
3589 $this->demand_reason_id = 1;
3590 $this->demand_reason_code =
'SRC_00';
3591 $this->note_public =
'This is a comment (public)';
3592 $this->note_private =
'This is a comment (private)';
3594 $this->multicurrency_tx = 1;
3595 $this->multicurrency_code = $conf->currency;
3600 while ($xnbp < $nbp) {
3602 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3604 $line->subprice = 100;
3607 $line->localtax1_tx = 0;
3608 $line->localtax2_tx = 0;
3610 $line->total_ht = 50;
3611 $line->total_ttc = 60;
3612 $line->total_tva = 10;
3613 $line->remise_percent = 50;
3615 $line->total_ht = 100;
3616 $line->total_ttc = 120;
3617 $line->total_tva = 20;
3618 $line->remise_percent = 00;
3621 if ($num_prods > 0) {
3622 $prodid = mt_rand(1, $num_prods);
3623 $line->fk_product = $prodids[$prodid];
3624 $line->product_ref =
'SPECIMEN';
3627 $this->lines[$xnbp] = $line;
3629 $this->total_ht += $line->total_ht;
3630 $this->total_tva += $line->total_tva;
3631 $this->total_ttc += $line->total_ttc;
3648 $this->nb = array();
3651 $sql =
"SELECT count(p.rowid) as nb";
3652 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3653 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3654 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3655 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3656 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3659 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3661 $resql = $this->db->query($sql);
3664 while ($obj = $this->db->fetch_object($resql)) {
3665 $this->nb[
"proposals"] = $obj->nb;
3667 $this->db->free($resql);
3671 $this->error = $this->db->error();
3686 global $conf, $langs;
3687 $langs->load(
"propal");
3689 $classname = $conf->global->PROPALE_ADDON;
3691 if (!empty($classname)) {
3694 $file = $classname.
".php";
3697 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3698 foreach ($dirmodels as $reldir) {
3702 $mybool |= @include_once $dir.$file;
3710 $obj =
new $classname();
3712 $numref = $obj->getNextValue($soc, $this);
3714 if ($numref !=
"") {
3717 $this->error = $obj->error;
3722 $langs->load(
"errors");
3723 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3736 global $conf, $langs, $user;
3738 $langs->load(
'propal');
3740 $nofetch = !empty($params[
'nofetch']);
3742 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
3743 return [
'optimize' => $langs->trans(
"Proposal")];
3745 if ($user->hasRight(
'propal',
'lire')) {
3746 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3747 if (isset($this->
statut)) {
3748 $datas[
'status'] =
' '.$this->getLibStatut(5);
3750 if (!empty($this->
ref)) {
3751 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3754 $langs->load(
'companies');
3755 if (empty($this->thirdparty)) {
3758 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3760 if (!empty($this->ref_client)) {
3761 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_client;
3764 $langs->load(
'project');
3765 if (empty($this->project)) {
3768 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3772 if (!empty($this->total_ht)) {
3773 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3775 if (!empty($this->total_tva)) {
3776 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3778 if (!empty($this->total_ttc)) {
3779 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3781 if (!empty($this->date)) {
3782 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3784 if (!empty($this->delivery_date)) {
3785 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3803 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3805 global $langs, $conf, $user, $hookmanager;
3807 if (!empty($conf->dol_no_mouse_hover)) {
3814 'objecttype' => $this->element,
3815 'option' => $option,
3818 $classfortooltip =
'classfortooltip';
3821 $classfortooltip =
'classforajaxtooltip';
3822 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3829 if ($user->hasRight(
'propal',
'lire')) {
3830 if ($option ==
'') {
3831 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3832 } elseif ($option ==
'compta') {
3833 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3834 } elseif ($option ==
'expedition') {
3835 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3836 } elseif ($option ==
'document') {
3837 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3840 if ($option !=
'nolink') {
3842 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3843 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3844 $add_save_lastsearch_values = 1;
3846 if ($add_save_lastsearch_values) {
3847 $url .=
'&save_lastsearch_values=1';
3853 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3854 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
3855 $label = $langs->trans(
"Proposal");
3856 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3858 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3859 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3862 $linkstart =
'<a href="'.$url.
'"';
3863 $linkstart .= $linkclose.
'>';
3866 $result .= $linkstart;
3868 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3870 if ($withpicto != 2) {
3871 $result .= $this->ref;
3873 $result .= $linkend;
3875 if ($addlinktonotes >= 0) {
3878 if ($addlinktonotes == 0) {
3879 if (!empty($this->note_private) || !empty($this->note_public)) {
3880 $txttoshow = $langs->trans(
'ViewPrivateNote');
3882 } elseif ($addlinktonotes == 1) {
3883 if (!empty($this->note_private)) {
3886 } elseif ($addlinktonotes == 2) {
3887 if (!empty($this->note_public)) {
3890 } elseif ($addlinktonotes == 3) {
3891 if ($user->socid > 0) {
3892 if (!empty($this->note_public)) {
3896 if (!empty($this->note_public)) {
3899 if (!empty($this->note_private)) {
3900 if (!empty($txttoshow)) {
3901 $txttoshow .=
'<br><br>';
3909 $result .=
' <span class="note inline-block">';
3910 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3913 $result .=
'</span>';
3918 $hookmanager->initHooks(array($this->element .
'dao'));
3919 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
3920 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3922 $result = $hookmanager->resPrint;
3924 $result .= $hookmanager->resPrint;
3951 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3953 global $conf, $langs;
3955 $langs->load(
"propale");
3956 $outputlangs->load(
"products");
3961 if ($this->model_pdf) {
3962 $modele = $this->model_pdf;
3963 } elseif (!empty($conf->global->PROPALE_ADDON_PDF)) {
3964 $modele = $conf->global->PROPALE_ADDON_PDF;
3968 $modelpath =
"core/modules/propale/doc/";
3970 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4018 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
4020 $return =
'<div class="box-flex-item box-flex-grow-zero">';
4021 $return .=
'<div class="info-box info-box-sm">';
4022 $return .=
'<span class="info-box-icon bg-infobox-action">';
4024 $return .=
'</span>';
4025 $return .=
'<div class="info-box-content">';
4026 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
4027 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
4028 if (property_exists($this,
'fk_project')) {
4029 $return .=
'<span class="info-box-ref"> | '.$this->fk_project.
'</span>';
4031 if (property_exists($this,
'author')) {
4032 $return .=
'<br><span class="info-box-label">'.$this->author.
'</span>';
4034 if (property_exists($this,
'total_ht')) {
4035 $return .=
'<br><span class="" >'.$langs->trans(
"AmountHT").
' : </span><span class="info-box-label amount">'.
price($this->total_ht).
'</span>';
4037 if (method_exists($this,
'getLibStatut')) {
4038 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
4040 $return .=
'</div>';
4041 $return .=
'</div>';
4042 $return .=
'</div>';
4055 public $element =
'propaldet';
4060 public $table_element =
'propaldet';
4066 public $fk_parent_line;
4084 public $vat_src_code;
4087 public $remise_percent;
4088 public $fk_remise_except;
4092 public $fk_fournprice;
4097 public $special_code;
4102 public $info_bits = 0;
4131 public $product_ref;
4146 public $product_label;
4151 public $product_desc;
4157 public $product_tobatch;
4163 public $product_barcode;
4165 public $localtax1_tx;
4166 public $localtax2_tx;
4167 public $localtax1_type;
4168 public $localtax2_type;
4169 public $total_localtax1;
4170 public $total_localtax2;
4175 public $skip_update_total;
4178 public $fk_multicurrency;
4179 public $multicurrency_code;
4180 public $multicurrency_subprice;
4181 public $multicurrency_total_ht;
4182 public $multicurrency_total_tva;
4183 public $multicurrency_total_ttc;
4204 $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,';
4205 $sql .=
' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
4206 $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,';
4207 $sql .=
' pd.fk_unit,';
4208 $sql .=
' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,';
4209 $sql .=
' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,';
4210 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
4211 $sql .=
' pd.date_start, pd.date_end, pd.product_type';
4212 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as pd';
4213 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON pd.fk_product = p.rowid';
4214 $sql .=
' WHERE pd.rowid = '.((int) $rowid);
4216 $result = $this->db->query($sql);
4218 $objp = $this->db->fetch_object($result);
4221 $this->
id = $objp->rowid;
4222 $this->
rowid = $objp->rowid;
4223 $this->fk_propal = $objp->fk_propal;
4224 $this->fk_parent_line = $objp->fk_parent_line;
4225 $this->label = $objp->custom_label;
4226 $this->desc = $objp->description;
4227 $this->qty = $objp->qty;
4228 $this->
price = $objp->price;
4229 $this->subprice = $objp->subprice;
4230 $this->vat_src_code = $objp->vat_src_code;
4231 $this->tva_tx = $objp->tva_tx;
4232 $this->remise = $objp->remise;
4233 $this->remise_percent = $objp->remise_percent;
4234 $this->fk_remise_except = $objp->fk_remise_except;
4235 $this->fk_product = $objp->fk_product;
4236 $this->info_bits = $objp->info_bits;
4238 $this->total_ht = $objp->total_ht;
4239 $this->total_tva = $objp->total_tva;
4240 $this->total_ttc = $objp->total_ttc;
4242 $this->fk_fournprice = $objp->fk_fournprice;
4244 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
4245 $this->pa_ht = $marginInfos[0];
4246 $this->marge_tx = $marginInfos[1];
4247 $this->marque_tx = $marginInfos[2];
4249 $this->special_code = $objp->special_code;
4250 $this->product_type = $objp->product_type;
4251 $this->rang = $objp->rang;
4253 $this->
ref = $objp->product_ref;
4254 $this->product_ref = $objp->product_ref;
4255 $this->libelle = $objp->product_label;
4256 $this->product_label = $objp->product_label;
4257 $this->product_desc = $objp->product_desc;
4258 $this->fk_unit = $objp->fk_unit;
4260 $this->date_start = $this->db->jdate($objp->date_start);
4261 $this->date_end = $this->db->jdate($objp->date_end);
4264 $this->fk_multicurrency = $objp->fk_multicurrency;
4265 $this->multicurrency_code = $objp->multicurrency_code;
4266 $this->multicurrency_subprice = $objp->multicurrency_subprice;
4267 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
4268 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
4269 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
4273 $this->db->free($result);
4292 global $conf, $user;
4296 dol_syslog(get_class($this).
"::insert rang=".$this->rang);
4298 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4301 if (empty($this->tva_tx)) {
4304 if (empty($this->localtax1_tx)) {
4305 $this->localtax1_tx = 0;
4307 if (empty($this->localtax2_tx)) {
4308 $this->localtax2_tx = 0;
4310 if (empty($this->localtax1_type)) {
4311 $this->localtax1_type = 0;
4313 if (empty($this->localtax2_type)) {
4314 $this->localtax2_type = 0;
4316 if (empty($this->total_localtax1)) {
4317 $this->total_localtax1 = 0;
4319 if (empty($this->total_localtax2)) {
4320 $this->total_localtax2 = 0;
4322 if (empty($this->rang)) {
4325 if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) {
4326 $this->remise_percent = 0;
4328 if (empty($this->info_bits)) {
4329 $this->info_bits = 0;
4331 if (empty($this->special_code)) {
4332 $this->special_code = 0;
4334 if (empty($this->fk_parent_line)) {
4335 $this->fk_parent_line = 0;
4337 if (empty($this->fk_fournprice)) {
4338 $this->fk_fournprice = 0;
4340 if (!is_numeric($this->qty)) {
4343 if (empty($this->pa_ht)) {
4346 if (empty($this->multicurrency_subprice)) {
4347 $this->multicurrency_subprice = 0;
4349 if (empty($this->multicurrency_total_ht)) {
4350 $this->multicurrency_total_ht = 0;
4352 if (empty($this->multicurrency_total_tva)) {
4353 $this->multicurrency_total_tva = 0;
4355 if (empty($this->multicurrency_total_ttc)) {
4356 $this->multicurrency_total_ttc = 0;
4360 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4361 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4364 $this->pa_ht = $result;
4369 if ($this->product_type < 0) {
4376 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'propaldet';
4377 $sql .=
' (fk_propal, fk_parent_line, label, description, fk_product, product_type,';
4378 $sql .=
' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
4379 $sql .=
' subprice, remise_percent, ';
4380 $sql .=
' info_bits, ';
4381 $sql .=
' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,';
4382 $sql .=
' fk_unit,';
4383 $sql .=
' date_start, date_end';
4384 $sql .=
', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)';
4385 $sql .=
" VALUES (".$this->fk_propal.
",";
4386 $sql .=
" ".($this->fk_parent_line > 0 ?
"'".$this->db->escape($this->fk_parent_line).
"'" :
"null").
",";
4387 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
4388 $sql .=
" '".$this->db->escape($this->desc).
"',";
4389 $sql .=
" ".($this->fk_product ?
"'".$this->db->escape($this->fk_product).
"'" :
"null").
",";
4390 $sql .=
" '".$this->db->escape($this->product_type).
"',";
4391 $sql .=
" ".($this->fk_remise_except ?
"'".$this->db->escape($this->fk_remise_except).
"'" :
"null").
",";
4392 $sql .=
" ".price2num($this->qty,
'MS').
",";
4393 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
4394 $sql .=
" ".price2num($this->tva_tx).
",";
4395 $sql .=
" ".price2num($this->localtax1_tx).
",";
4396 $sql .=
" ".price2num($this->localtax2_tx).
",";
4397 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
4398 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
4399 $sql .=
" ".(price2num($this->subprice) !==
'' ?
price2num($this->subprice,
'MU') :
"null").
",";
4400 $sql .=
" ".price2num($this->remise_percent, 3).
",";
4401 $sql .=
" ".(isset($this->info_bits) ? ((int) $this->info_bits) :
"null").
",";
4402 $sql .=
" ".price2num($this->total_ht,
'MT').
",";
4403 $sql .=
" ".price2num($this->total_tva,
'MT').
",";
4404 $sql .=
" ".price2num($this->total_localtax1,
'MT').
",";
4405 $sql .=
" ".price2num($this->total_localtax2,
'MT').
",";
4406 $sql .=
" ".price2num($this->total_ttc,
'MT').
",";
4407 $sql .=
" ".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null").
",";
4408 $sql .=
" ".(isset($this->pa_ht) ?
"'".price2num($this->pa_ht).
"'" :
"null").
",";
4409 $sql .=
' '.((int) $this->special_code).
',';
4410 $sql .=
' '.((int) $this->rang).
',';
4411 $sql .=
' '.(empty($this->fk_unit) ?
'NULL' : ((int) $this->fk_unit)).
',';
4412 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
',';
4413 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4414 $sql .=
", ".($this->fk_multicurrency > 0 ? ((int) $this->fk_multicurrency) :
'null');
4415 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
4416 $sql .=
", ".price2num($this->multicurrency_subprice,
'CU');
4417 $sql .=
", ".price2num($this->multicurrency_total_ht,
'CT');
4418 $sql .=
", ".price2num($this->multicurrency_total_tva,
'CT');
4419 $sql .=
", ".price2num($this->multicurrency_total_ttc,
'CT');
4422 dol_syslog(get_class($this).
'::insert', LOG_DEBUG);
4423 $resql = $this->db->query($sql);
4425 $this->
rowid = $this->db->last_insert_id(MAIN_DB_PREFIX.
'propaldet');
4428 $this->
id = $this->rowid;
4435 if (!$error && !$notrigger) {
4437 $result = $this->
call_trigger(
'LINEPROPAL_INSERT', $user);
4439 $this->db->rollback();
4446 $this->db->commit();
4450 foreach ($this->errors as $errmsg) {
4451 dol_syslog(get_class($this).
"::insert ".$errmsg, LOG_ERR);
4452 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4454 $this->db->rollback();
4457 $this->error = $this->db->error().
" sql=".$sql;
4458 $this->db->rollback();
4470 public function delete(
User $user, $notrigger = 0)
4479 $result = $this->
call_trigger(
'LINEPROPAL_DELETE', $user);
4487 $sql =
"DELETE FROM " . MAIN_DB_PREFIX .
"propaldet WHERE rowid = " . ((int) $this->
rowid);
4488 dol_syslog(
"PropaleLigne::delete", LOG_DEBUG);
4489 if ($this->db->query($sql)) {
4492 $this->
id = $this->rowid;
4496 dol_syslog(get_class($this) .
"::delete error -4 " . $this->error, LOG_ERR);
4500 $this->error = $this->db->error() .
" sql=" . $sql;
4506 $this->db->rollback();
4509 $this->db->commit();
4522 global $conf, $user;
4526 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4528 if (empty($this->
id) && !empty($this->
rowid)) {
4529 $this->
id = $this->rowid;
4533 if (empty($this->tva_tx)) {
4536 if (empty($this->localtax1_tx)) {
4537 $this->localtax1_tx = 0;
4539 if (empty($this->localtax2_tx)) {
4540 $this->localtax2_tx = 0;
4542 if (empty($this->total_localtax1)) {
4543 $this->total_localtax1 = 0;
4545 if (empty($this->total_localtax2)) {
4546 $this->total_localtax2 = 0;
4548 if (empty($this->localtax1_type)) {
4549 $this->localtax1_type = 0;
4551 if (empty($this->localtax2_type)) {
4552 $this->localtax2_type = 0;
4554 if (empty($this->marque_tx)) {
4555 $this->marque_tx = 0;
4557 if (empty($this->marge_tx)) {
4558 $this->marge_tx = 0;
4560 if (empty($this->
price)) {
4563 if (empty($this->remise_percent)) {
4564 $this->remise_percent = 0;
4566 if (empty($this->info_bits)) {
4567 $this->info_bits = 0;
4569 if (empty($this->special_code)) {
4570 $this->special_code = 0;
4572 if (empty($this->fk_parent_line)) {
4573 $this->fk_parent_line = 0;
4575 if (empty($this->fk_fournprice)) {
4576 $this->fk_fournprice = 0;
4578 if (empty($this->subprice)) {
4579 $this->subprice = 0;
4581 if (empty($this->pa_ht)) {
4586 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4587 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4590 $this->pa_ht = $result;
4597 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4598 $sql .=
" description='".$this->db->escape($this->desc).
"'";
4599 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
4600 $sql .=
", product_type=".$this->product_type;
4601 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"'";
4602 $sql .=
", tva_tx='".price2num($this->tva_tx).
"'";
4603 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
4604 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
4605 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
4606 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
4607 $sql .=
", qty='".price2num($this->qty).
"'";
4608 $sql .=
", subprice=".price2num($this->subprice);
4609 $sql .=
", remise_percent=".price2num($this->remise_percent);
4611 $sql .=
", remise=".(float)
price2num($this->remise);
4612 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
4613 if (empty($this->skip_update_total)) {
4614 $sql .=
", total_ht=".price2num($this->total_ht);
4615 $sql .=
", total_tva=".price2num($this->total_tva);
4616 $sql .=
", total_ttc=".price2num($this->total_ttc);
4617 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
4618 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
4620 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
4621 $sql .=
", buy_price_ht=".price2num($this->pa_ht);
4622 if (strlen($this->special_code)) {
4623 $sql .=
", special_code=".$this->special_code;
4625 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
4626 if (!empty($this->rang)) {
4627 $sql .=
", rang=".((int) $this->rang);
4629 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
4630 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4631 $sql .=
", fk_unit=".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
4634 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
4635 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
4636 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
4637 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
4639 $sql .=
" WHERE rowid = ".((int) $this->
id);
4641 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
4642 $resql = $this->db->query($sql);
4651 if (!$error && !$notrigger) {
4653 $result = $this->
call_trigger(
'LINEPROPAL_MODIFY', $user);
4655 $this->db->rollback();
4662 $this->db->commit();
4666 foreach ($this->errors as $errmsg) {
4667 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
4668 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4670 $this->db->rollback();
4673 $this->error = $this->db->error();
4674 $this->db->rollback();
4692 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4693 $sql .=
" total_ht=".price2num($this->total_ht,
'MT');
4694 $sql .=
",total_tva=".price2num($this->total_tva,
'MT');
4695 $sql .=
",total_ttc=".price2num($this->total_ttc,
'MT');
4696 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
4698 dol_syslog(
"PropaleLigne::update_total", LOG_DEBUG);
4700 $resql = $this->db->query($sql);
4702 $this->db->commit();
4705 $this->error = $this->db->error();
4706 $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.
setErrorsFromObject($object)
setErrorsFromObject
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.
fetch_project()
Load the project with id $this->fk_project into this->project.
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.
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 commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
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 in llx_element_contact.
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.
getTooltipContentArray($params)
getTooltipContentArray
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)
getKanbanView($option='', $arraydata=null)
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.
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.
createFromClone(User $user, $socid=0, $forceentity=null, $update_prices=false, $update_desc=false)
Load an object from its id and create a new one in database.
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.
print $langs trans("Ref").' m m m statut
trait CommonIncoterm
Superclass for incoterm classes.
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_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).
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.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
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...
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.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
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.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
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.