44require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/comm/propal/class/propaleligne.class.php';
46require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
47require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
48require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
49require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
66 public $element =
'propal';
71 public $table_element =
'propal';
76 public $table_element_line =
'propaldet';
81 public $fk_element =
'fk_propal';
86 public $picto =
'propal';
92 public $restrictiononfksoc = 1;
123 public $ref_customer;
162 public $date_validation;
167 public $date_signature;
172 public $user_signature;
189 public $delivery_date;
195 public $fin_validite;
200 public $user_author_id;
227 public $cond_reglement_code;
232 public $cond_reglement;
237 public $cond_reglement_doc;
242 public $mode_reglement_code;
247 public $mode_reglement;
254 public $deposit_percent;
266 public $address_type;
277 public $availability_id;
284 public $fk_availability;
289 public $availability_code;
294 public $availability;
296 public $duree_validite;
301 public $demand_reason_id;
306 public $demand_reason_code;
311 public $demand_reason;
316 public $warehouse_id;
321 public $lines = array();
328 public $labelStatus = array();
329 public $labelStatusShort = array();
360 public $fields = array(
361 'rowid' => array(
'type' =>
'integer',
'label' =>
'TechnicalID',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 10),
362 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'default' =>
'1',
'enabled' => 1,
'visible' => -2,
'notnull' => 1,
'position' => 15,
'index' => 1),
363 'ref' => array(
'type' =>
'varchar(30)',
'label' =>
'Ref',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'showoncombobox' => 1,
'position' => 20),
364 'ref_client' => array(
'type' =>
'varchar(255)',
'label' =>
'RefCustomer',
'enabled' => 1,
'visible' => -1,
'position' => 22),
365 'ref_ext' => array(
'type' =>
'varchar(255)',
'label' =>
'RefExt',
'enabled' => 1,
'visible' => 0,
'position' => 40),
366 'fk_soc' => array(
'type' =>
'integer:Societe:societe/class/societe.class.php',
'label' =>
'ThirdParty',
'enabled' =>
'isModEnabled("societe")',
'visible' => -1,
'position' => 23),
367 '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),
368 'tms' => array(
'type' =>
'timestamp',
'label' =>
'DateModification',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 25),
369 'datec' => array(
'type' =>
'datetime',
'label' =>
'DateCreation',
'enabled' => 1,
'visible' => -1,
'position' => 55),
370 'datep' => array(
'type' =>
'date',
'label' =>
'Date',
'enabled' => 1,
'visible' => -1,
'position' => 60),
371 'fin_validite' => array(
'type' =>
'datetime',
'label' =>
'DateEnd',
'enabled' => 1,
'visible' => -1,
'position' => 65),
372 'date_valid' => array(
'type' =>
'datetime',
'label' =>
'DateValidation',
'enabled' => 1,
'visible' => -1,
'position' => 70),
373 'date_cloture' => array(
'type' =>
'datetime',
'label' =>
'DateClosing',
'enabled' => 1,
'visible' => -1,
'position' => 75),
374 'fk_user_author' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user author',
'enabled' => 1,
'visible' => -1,
'position' => 80),
375 'fk_user_modif' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserModif',
'enabled' => 1,
'visible' => -2,
'notnull' => -1,
'position' => 85),
376 'fk_user_valid' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserValidation',
'enabled' => 1,
'visible' => -1,
'position' => 90),
377 'fk_user_cloture' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user cloture',
'enabled' => 1,
'visible' => -1,
'position' => 95),
378 'price' => array(
'type' =>
'double',
'label' =>
'Price',
'enabled' => 1,
'visible' => -1,
'position' => 105),
379 'total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalHT',
'enabled' => 1,
'visible' => -1,
'position' => 125,
'isameasure' => 1),
380 'total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'VAT',
'enabled' => 1,
'visible' => -1,
'position' => 130,
'isameasure' => 1),
381 'localtax1' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax1',
'enabled' => 1,
'visible' => -1,
'position' => 135,
'isameasure' => 1),
382 'localtax2' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax2',
'enabled' => 1,
'visible' => -1,
'position' => 140,
'isameasure' => 1),
383 'total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalTTC',
'enabled' => 1,
'visible' => -1,
'position' => 145,
'isameasure' => 1),
384 'fk_account' => array(
'type' =>
'integer',
'label' =>
'BankAccount',
'enabled' =>
'isModEnabled("bank")',
'visible' => -1,
'position' => 150),
385 'fk_currency' => array(
'type' =>
'varchar(3)',
'label' =>
'Currency',
'enabled' => 1,
'visible' => -1,
'position' => 155),
386 'fk_cond_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentTerm',
'enabled' => 1,
'visible' => -1,
'position' => 160),
387 'deposit_percent' => array(
'type' =>
'varchar(63)',
'label' =>
'DepositPercent',
'enabled' => 1,
'visible' => -1,
'position' => 161),
388 'fk_mode_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentMode',
'enabled' => 1,
'visible' => -1,
'position' => 165),
389 'note_private' => array(
'type' =>
'html',
'label' =>
'NotePrivate',
'enabled' => 1,
'visible' => 0,
'position' => 170),
390 'note_public' => array(
'type' =>
'html',
'label' =>
'NotePublic',
'enabled' => 1,
'visible' => 0,
'position' => 175),
391 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'PDFTemplate',
'enabled' => 1,
'visible' => 0,
'position' => 180),
392 'date_livraison' => array(
'type' =>
'date',
'label' =>
'DateDeliveryPlanned',
'enabled' => 1,
'visible' => -1,
'position' => 185),
393 'fk_shipping_method' => array(
'type' =>
'integer',
'label' =>
'ShippingMethod',
'enabled' => 1,
'visible' => -1,
'position' => 190),
394 'fk_warehouse' => array(
'type' =>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label' =>
'Fk warehouse',
'enabled' =>
'isModEnabled("stock")',
'visible' => -1,
'position' => 191),
395 'fk_availability' => array(
'type' =>
'integer',
'label' =>
'Availability',
'enabled' => 1,
'visible' => -1,
'position' => 195),
396 'fk_delivery_address' => array(
'type' =>
'integer',
'label' =>
'DeliveryAddress',
'enabled' => 1,
'visible' => 0,
'position' => 200),
397 'fk_input_reason' => array(
'type' =>
'integer',
'label' =>
'InputReason',
'enabled' => 1,
'visible' => -1,
'position' => 205),
398 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => -1,
'position' => 215),
399 'fk_incoterms' => array(
'type' =>
'integer',
'label' =>
'IncotermCode',
'enabled' =>
'$conf->incoterm->enabled',
'visible' => -1,
'position' => 220),
400 'location_incoterms' => array(
'type' =>
'varchar(255)',
'label' =>
'IncotermLabel',
'enabled' =>
'$conf->incoterm->enabled',
'visible' => -1,
'position' => 225),
401 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'MulticurrencyID',
'enabled' => 1,
'visible' => -1,
'position' => 230),
402 'multicurrency_code' => array(
'type' =>
'varchar(255)',
'label' =>
'MulticurrencyCurrency',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 235),
403 'multicurrency_tx' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyRate',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 240,
'isameasure' => 1),
404 'multicurrency_total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountHT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 245,
'isameasure' => 1),
405 'multicurrency_total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountVAT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 250,
'isameasure' => 1),
406 'multicurrency_total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountTTC',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 255,
'isameasure' => 1),
407 'last_main_doc' => array(
'type' =>
'varchar(255)',
'label' =>
'LastMainDoc',
'enabled' => 1,
'visible' => -1,
'position' => 260),
408 'fk_statut' => array(
'type' =>
'smallint(6)',
'label' =>
'Status',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 500),
409 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -2,
'position' => 900),
450 $this->ismultientitymanaged = 1;
451 $this->socid = $socid;
452 $this->
id = $propalid;
454 $this->duree_validite =
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
470 public function add_product($idproduct, $qty, $remise_percent = 0)
473 global $conf, $mysoc;
479 dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
480 if ($idproduct > 0) {
481 $prod =
new Product($this->db);
482 $prod->fetch($idproduct);
484 $productdesc = $prod->description;
488 if (empty($tva_tx)) {
493 $localtax1_tx =
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
494 $localtax2_tx =
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
497 if ($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
498 $price = $prod->multiprices[$this->thirdparty->price_level];
505 $line->fk_product = $idproduct;
506 $line->desc = $productdesc;
509 $line->remise_percent = $remise_percent;
510 $line->vat_src_code = $vat_src_code;
511 $line->tva_tx = $tva_tx;
512 $line->fk_unit = $prod->fk_unit;
514 $line->info_bits = 1;
517 $this->lines[] = $line;
535 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
536 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
541 $result = $remise->fetch($idremise);
544 if ($remise->fk_facture) {
545 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
546 $this->db->rollback();
552 $line->context = $this->context;
554 $line->fk_propal = $this->id;
555 $line->fk_remise_except = $remise->id;
556 $line->desc = $remise->description;
557 $line->vat_src_code = $remise->vat_src_code;
558 $line->tva_tx = $remise->tva_tx;
559 $line->subprice = -$remise->amount_ht;
560 $line->fk_product = 0;
562 $line->remise_percent = 0;
564 $line->info_bits = 2;
567 $line->price = -$remise->amount_ht;
569 $line->total_ht = -$remise->amount_ht;
570 $line->total_tva = -$remise->amount_tva;
571 $line->total_ttc = -$remise->amount_ttc;
573 $result = $line->insert();
580 $this->db->rollback();
584 $this->error = $line->error;
585 $this->errors = $line->errors;
586 $this->db->rollback();
590 $this->db->rollback();
632 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 = array(), $fk_unit =
null, $origin =
'', $origin_id = 0, $pu_ht_devise = 0, $fk_remise_except = 0, $noupdateafterinsertline = 0)
634 global $mysoc, $conf, $langs;
636 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);
638 if ($this->statut == self::STATUS_DRAFT) {
639 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
642 if (empty($remise_percent)) {
648 if (empty($info_bits)) {
654 if (empty($fk_parent_line) || $fk_parent_line < 0) {
658 $remise_percent =
price2num($remise_percent);
661 $pu_ht_devise =
price2num($pu_ht_devise);
663 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
669 if ($price_base_type ==
'HT') {
680 if ($date_start && $date_end && $date_start > $date_end) {
681 $langs->load(
"errors");
682 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
688 $product_type = $type;
689 if (!empty($fk_product) && $fk_product > 0) {
690 $product =
new Product($this->db);
691 $result = $product->fetch($fk_product);
692 $product_type = $product->type;
694 if (
getDolGlobalString(
'STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL') && $product_type == 0 && $product->stock_reel < $qty) {
695 $langs->load(
"errors");
696 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
697 $this->db->rollback();
712 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
713 $vat_src_code = $reg[1];
714 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
717 $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);
719 $total_ht = $tabprice[0];
720 $total_tva = $tabprice[1];
721 $total_ttc = $tabprice[2];
722 $total_localtax1 = $tabprice[9];
723 $total_localtax2 = $tabprice[10];
724 $pu_ht = $tabprice[3];
725 $pu_tva = $tabprice[4];
726 $pu_ttc = $tabprice[5];
729 $multicurrency_total_ht = $tabprice[16];
730 $multicurrency_total_tva = $tabprice[17];
731 $multicurrency_total_ttc = $tabprice[18];
732 $pu_ht_devise = $tabprice[19];
736 if ($ranktouse == -1) {
737 $rangmax = $this->
line_max($fk_parent_line);
738 $ranktouse = $rangmax + 1;
745 if ((
float) $remise_percent > 0) {
746 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
747 $price = (float) $pu - $remise;
753 $this->line->context = $this->context;
755 $this->line->fk_propal = $this->id;
756 $this->line->label = $label;
757 $this->line->desc = $desc;
758 $this->line->qty = $qty;
760 $this->line->vat_src_code = $vat_src_code;
761 $this->line->tva_tx = $txtva;
762 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
763 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
764 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
765 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
766 $this->line->fk_product = $fk_product;
767 $this->line->product_type = $type;
768 $this->line->fk_remise_except = $fk_remise_except;
769 $this->line->remise_percent = $remise_percent;
770 $this->line->subprice = $pu_ht;
771 $this->line->rang = $ranktouse;
772 $this->line->info_bits = $info_bits;
773 $this->line->total_ht = $total_ht;
774 $this->line->total_tva = $total_tva;
775 $this->line->total_localtax1 = $total_localtax1;
776 $this->line->total_localtax2 = $total_localtax2;
777 $this->line->total_ttc = $total_ttc;
778 $this->line->special_code = $special_code;
779 $this->line->fk_parent_line = $fk_parent_line;
780 $this->line->fk_unit = $fk_unit;
782 $this->line->date_start = $date_start;
783 $this->line->date_end = $date_end;
785 $this->line->fk_fournprice = $fk_fournprice;
786 $this->line->pa_ht = $pa_ht;
788 $this->line->origin_id = $origin_id;
789 $this->line->origin = $origin;
792 $this->line->fk_multicurrency = $this->fk_multicurrency;
793 $this->line->multicurrency_code = $this->multicurrency_code;
794 $this->line->multicurrency_subprice = $pu_ht_devise;
795 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
796 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
797 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
800 if (empty($qty) && empty($special_code)) {
801 $this->line->special_code = 3;
805 $this->line->price =
$price;
807 if (is_array($array_options) && count($array_options) > 0) {
808 $this->line->array_options = $array_options;
811 $result = $this->line->insert();
814 if (!empty($fk_parent_line)) {
816 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
817 $linecount = count($this->lines);
818 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
824 if (empty($noupdateafterinsertline)) {
830 return $this->line->id;
832 $this->error = $this->db->error();
833 $this->db->rollback();
837 $this->error = $this->line->error;
838 $this->errors = $this->line->errors;
839 $this->db->rollback();
843 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
878 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 = array(), $fk_unit =
null, $pu_ht_devise = 0, $notrigger = 0, $rang = 0)
880 global $mysoc, $langs;
882 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
883 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");
884 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
887 $remise_percent =
price2num($remise_percent);
890 $pu_ht_devise =
price2num($pu_ht_devise);
891 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
897 if (empty($qty) && empty($special_code)) {
900 if (!empty($qty) && $special_code == 3) {
907 if ($date_start && $date_end && $date_start > $date_end) {
908 $langs->load(
"errors");
909 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
913 if ($this->
status == self::STATUS_DRAFT) {
926 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
927 $vat_src_code = $reg[1];
928 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
933 $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);
934 $total_ht = $tabprice[0];
935 $total_tva = $tabprice[1];
936 $total_ttc = $tabprice[2];
937 $total_localtax1 = $tabprice[9];
938 $total_localtax2 = $tabprice[10];
939 $pu_ht = $tabprice[3];
940 $pu_tva = $tabprice[4];
941 $pu_ttc = $tabprice[5];
944 $multicurrency_total_ht = $tabprice[16];
945 $multicurrency_total_tva = $tabprice[17];
946 $multicurrency_total_ttc = $tabprice[18];
947 $pu_ht_devise = $tabprice[19];
952 if ((
float) $remise_percent > 0) {
953 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
954 $price = (float) $pu - $remise;
959 $line->fetch($rowid);
961 $staticline = clone $line;
963 $line->oldline = $staticline;
965 $this->line->context = $this->context;
966 $this->line->rang = $rang;
969 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
970 $rangmax = $this->
line_max($fk_parent_line);
971 $this->line->rang = $rangmax + 1;
974 $this->line->id = $rowid;
975 $this->line->label = $label;
976 $this->line->desc = $desc;
977 $this->line->qty = $qty;
978 $this->line->product_type = $type;
979 $this->line->vat_src_code = $vat_src_code;
980 $this->line->tva_tx = $txtva;
981 $this->line->localtax1_tx = $txlocaltax1;
982 $this->line->localtax2_tx = $txlocaltax2;
983 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
984 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
985 $this->line->remise_percent = $remise_percent;
986 $this->line->subprice = $pu_ht;
987 $this->line->info_bits = $info_bits;
989 $this->line->total_ht = $total_ht;
990 $this->line->total_tva = $total_tva;
991 $this->line->total_localtax1 = $total_localtax1;
992 $this->line->total_localtax2 = $total_localtax2;
993 $this->line->total_ttc = $total_ttc;
994 $this->line->special_code = $special_code;
995 $this->line->fk_parent_line = $fk_parent_line;
996 $this->line->skip_update_total = $skip_update_total;
997 $this->line->fk_unit = $fk_unit;
999 $this->line->fk_fournprice = $fk_fournprice;
1000 $this->line->pa_ht = $pa_ht;
1002 $this->line->date_start = $date_start;
1003 $this->line->date_end = $date_end;
1005 if (is_array($array_options) && count($array_options) > 0) {
1007 foreach ($array_options as $key => $value) {
1008 $this->line->array_options[$key] = $array_options[$key];
1013 $this->line->multicurrency_subprice = $pu_ht_devise;
1014 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
1015 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
1016 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
1018 $result = $this->line->update($notrigger);
1021 if (!empty($fk_parent_line)) {
1031 $this->db->commit();
1034 $this->error = $this->line->error;
1035 $this->errors = $this->line->errors;
1036 $this->db->rollback();
1040 dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
1057 if ($this->
status == self::STATUS_DRAFT) {
1062 $line->context = $this->context;
1065 $line->fetch($lineid);
1067 if ($id > 0 && $line->fk_propal != $id) {
1068 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
1073 $staticline = clone $line;
1074 $line->oldline = $staticline;
1076 if ($line->delete($user) > 0) {
1079 $this->db->commit();
1082 $this->error = $line->error;
1083 $this->errors = $line->errors;
1084 $this->db->rollback();
1088 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1102 public function create($user, $notrigger = 0)
1104 global $conf, $hookmanager, $mysoc;
1110 if (empty($this->date)) {
1111 $this->date = $this->datep;
1113 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1114 if (empty($this->availability_id)) {
1115 $this->availability_id = 0;
1117 if (empty($this->demand_reason_id)) {
1118 $this->demand_reason_id = 0;
1122 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1127 if (empty($this->fk_multicurrency)) {
1128 $this->multicurrency_code = $conf->currency;
1129 $this->fk_multicurrency = 0;
1130 $this->multicurrency_tx = 1;
1134 $delivery_date = $this->delivery_date;
1141 $this->error =
"Failed to fetch company";
1142 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1147 if (!empty($this->
ref)) {
1150 $this->error =
'ErrorRefAlreadyExists';
1151 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1152 $this->db->rollback();
1157 if (empty($this->date)) {
1158 $this->error =
"Date of proposal is required";
1159 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1167 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
1170 $sql .=
", total_tva";
1171 $sql .=
", total_ttc";
1175 $sql .=
", fk_user_author";
1176 $sql .=
", note_private";
1177 $sql .=
", note_public";
1178 $sql .=
", model_pdf";
1179 $sql .=
", fin_validite";
1180 $sql .=
", fk_cond_reglement";
1181 $sql .=
", deposit_percent";
1182 $sql .=
", fk_mode_reglement";
1183 $sql .=
", fk_account";
1184 $sql .=
", ref_client";
1185 $sql .=
", ref_ext";
1186 $sql .=
", date_livraison";
1187 $sql .=
", fk_shipping_method";
1188 $sql .=
", fk_warehouse";
1189 $sql .=
", fk_availability";
1190 $sql .=
", fk_input_reason";
1191 $sql .=
", fk_projet";
1192 $sql .=
", fk_incoterms";
1193 $sql .=
", location_incoterms";
1195 $sql .=
", fk_multicurrency";
1196 $sql .=
", multicurrency_code";
1197 $sql .=
", multicurrency_tx";
1199 $sql .=
" VALUES (";
1200 $sql .= $this->socid;
1204 $sql .=
", '".$this->db->idate($this->date).
"'";
1205 $sql .=
", '".$this->db->idate($now).
"'";
1206 $sql .=
", '(PROV)'";
1207 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1208 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1209 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1210 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1211 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1212 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1213 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1214 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1215 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1216 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1217 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1218 $sql .=
", ".(!
isDolTms($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1219 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1220 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1221 $sql .=
", ".$this->availability_id;
1222 $sql .=
", ".$this->demand_reason_id;
1223 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1224 $sql .=
", ".(int) $this->fk_incoterms;
1225 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1226 $sql .=
", ".setEntity($this);
1227 $sql .=
", ".(int) $this->fk_multicurrency;
1228 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1229 $sql .=
", ".(float) $this->multicurrency_tx;
1232 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1233 $resql = $this->db->query($sql);
1235 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1238 $this->
ref =
'(PROV'.$this->id.
')';
1239 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1241 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1242 $resql = $this->db->query($sql);
1247 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1248 $this->linked_objects = $this->linkedObjectsIds;
1252 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1253 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1254 if (is_array($tmp_origin_id)) {
1255 foreach ($tmp_origin_id as $origin_id) {
1258 $this->error = $this->db->lasterror();
1263 $origin_id = $tmp_origin_id;
1266 $this->error = $this->db->lasterror();
1278 $fk_parent_line = 0;
1279 $num = count($this->lines);
1281 for ($i = 0; $i < $num; $i++) {
1282 if (!is_object($this->lines[$i])) {
1284 $line = (object) $this->lines[$i];
1286 $line = $this->lines[$i];
1289 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1290 $fk_parent_line = 0;
1293 $vatrate = $line->tva_tx;
1294 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1295 $vatrate .=
' ('.$line->vat_src_code.
')';
1299 $originid = $line->origin_id;
1300 $origintype = $line->origin;
1302 $originid = $line->id;
1303 $origintype = $this->element;
1311 $line->localtax1_tx,
1312 $line->localtax2_tx,
1314 $line->remise_percent,
1318 $line->product_type,
1320 $line->special_code,
1322 $line->fk_fournprice,
1327 $line->array_options,
1338 $this->error = $this->db->error;
1344 $line->id = $result;
1347 if ($result > 0 && $line->product_type == 9) {
1348 $fk_parent_line = $result;
1378 if (!$error && !$notrigger) {
1387 $this->error = $this->db->lasterror();
1392 $this->error = $this->db->lasterror();
1397 $this->db->commit();
1398 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1401 $this->db->rollback();
1405 $this->error = $this->db->lasterror();
1406 $this->db->rollback();
1421 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1423 global $conf, $hookmanager, $mysoc;
1432 $object =
new self($this->db);
1439 $objsoc =
new Societe($this->db);
1442 if (!empty($socid) && $socid !=
$object->socid) {
1443 if ($objsoc->fetch($socid) > 0) {
1445 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1446 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1447 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1448 $object->fk_delivery_address = 0;
1471 $objsoc->fetch(
$object->socid);
1475 if ($update_prices ===
true || $update_desc ===
true) {
1476 if ($objsoc->id > 0 && !empty(
$object->lines)) {
1479 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1482 foreach (
$object->lines as $line) {
1485 if ($line->fk_product > 0) {
1486 $prod =
new Product($this->db);
1487 $res = $prod->fetch($line->fk_product);
1489 if ($update_prices ===
true) {
1490 $pu_ht = $prod->price;
1492 $remise_percent = $objsoc->remise_percent;
1495 $pu_ht = $prod->multiprices[$objsoc->price_level];
1497 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1498 $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
1503 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1504 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1507 if (count($prodcustprice->lines) > 0) {
1508 $pu_ht =
price($prodcustprice->lines[0]->price);
1509 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1510 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1511 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1517 $line->subprice = $pu_ht;
1518 $line->tva_tx = $tva_tx;
1519 $line->remise_percent = $remise_percent;
1521 if ($update_desc ===
true) {
1522 $line->desc = $prod->description;
1532 $object->entity = (!empty($forceentity) ? $forceentity :
$object->entity);
1536 $object->user_creation_id = $user->id;
1537 $object->user_validation_id = 0;
1550 $object->context[
'createfromclone'] =
'createfromclone';
1551 $result =
$object->create($user);
1553 $this->error =
$object->error;
1554 $this->errors = array_merge($this->errors,
$object->errors);
1560 if (
$object->copy_linked_contact($this,
'internal') < 0) {
1567 if ($this->socid ==
$object->socid) {
1568 if (
$object->copy_linked_contact($this,
'external') < 0) {
1576 if (is_object($hookmanager)) {
1577 $parameters = array(
'objFrom' => $this,
'clonedObj' =>
$object);
1579 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters,
$object, $action);
1587 unset(
$object->context[
'createfromclone']);
1591 $this->db->commit();
1594 $this->db->rollback();
1608 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1610 $sql =
"SELECT p.rowid, p.ref, p.entity, p.fk_soc";
1611 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1612 $sql .=
", p.datec";
1613 $sql .=
", p.date_signature as dates";
1614 $sql .=
", p.date_valid as datev";
1615 $sql .=
", p.datep as dp";
1616 $sql .=
", p.fin_validite as dfv";
1617 $sql .=
", p.date_livraison as delivery_date";
1618 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1619 $sql .=
", p.note_private, p.note_public";
1620 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1621 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1622 $sql .=
", p.fk_delivery_address";
1623 $sql .=
", p.fk_availability";
1624 $sql .=
", p.fk_input_reason";
1625 $sql .=
", p.fk_cond_reglement";
1626 $sql .=
", p.fk_mode_reglement";
1627 $sql .=
', p.fk_account';
1628 $sql .=
", p.fk_shipping_method";
1629 $sql .=
", p.fk_warehouse";
1630 $sql .=
", p.fk_incoterms, p.location_incoterms";
1631 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1632 $sql .=
", p.tms as date_modification";
1633 $sql .=
", i.libelle as label_incoterms";
1634 $sql .=
", c.label as statut_label";
1635 $sql .=
", ca.code as availability_code, ca.label as availability";
1636 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1637 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1638 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1639 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1640 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1641 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1642 $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').
')';
1643 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1644 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1645 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1648 if (!empty($forceentity)) {
1649 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1651 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1653 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1656 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1659 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1660 $resql = $this->db->query($sql);
1662 if ($this->db->num_rows($resql)) {
1663 $obj = $this->db->fetch_object($resql);
1665 $this->
id = $obj->rowid;
1666 $this->entity = $obj->entity;
1668 $this->
ref = $obj->ref;
1669 $this->ref_client = $obj->ref_client;
1670 $this->ref_customer = $obj->ref_client;
1671 $this->ref_ext = $obj->ref_ext;
1673 $this->total = $obj->total_ttc;
1674 $this->total_ttc = $obj->total_ttc;
1675 $this->total_ht = $obj->total_ht;
1676 $this->total_tva = $obj->total_tva;
1677 $this->total_localtax1 = $obj->localtax1;
1678 $this->total_localtax2 = $obj->localtax2;
1680 $this->socid = $obj->fk_soc;
1681 $this->thirdparty =
null;
1683 $this->fk_project = $obj->fk_project;
1684 $this->project =
null;
1686 $this->model_pdf = $obj->model_pdf;
1687 $this->last_main_doc = $obj->last_main_doc;
1688 $this->note = $obj->note_private;
1689 $this->note_private = $obj->note_private;
1690 $this->note_public = $obj->note_public;
1692 $this->
status = (int) $obj->fk_statut;
1693 $this->statut = $this->status;
1695 $this->datec = $this->db->jdate($obj->datec);
1696 $this->datev = $this->db->jdate($obj->datev);
1697 $this->date_creation = $this->db->jdate($obj->datec);
1698 $this->date_validation = $this->db->jdate($obj->datev);
1699 $this->date_modification = $this->db->jdate($obj->date_modification);
1700 $this->date_signature = $this->db->jdate($obj->dates);
1701 $this->date = $this->db->jdate($obj->dp);
1702 $this->datep = $this->db->jdate($obj->dp);
1703 $this->fin_validite = $this->db->jdate($obj->dfv);
1704 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1705 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1706 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1707 $this->availability_id = $obj->fk_availability;
1708 $this->availability_code = $obj->availability_code;
1710 $this->demand_reason_id = $obj->fk_input_reason;
1711 $this->demand_reason_code = $obj->demand_reason_code;
1713 $this->fk_address = $obj->fk_delivery_address;
1715 $this->mode_reglement_id = $obj->fk_mode_reglement;
1716 $this->mode_reglement_code = $obj->mode_reglement_code;
1717 $this->mode_reglement = $obj->mode_reglement;
1718 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1719 $this->cond_reglement_id = $obj->fk_cond_reglement;
1720 $this->cond_reglement_code = $obj->cond_reglement_code;
1721 $this->cond_reglement = $obj->cond_reglement;
1722 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1723 $this->deposit_percent = $obj->deposit_percent;
1725 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1727 $this->user_author_id = $obj->fk_user_author;
1728 $this->user_validation_id = $obj->fk_user_valid;
1729 $this->user_closing_id = $obj->fk_user_cloture;
1732 $this->fk_incoterms = $obj->fk_incoterms;
1733 $this->location_incoterms = $obj->location_incoterms;
1734 $this->label_incoterms = $obj->label_incoterms;
1737 $this->fk_multicurrency = $obj->fk_multicurrency;
1738 $this->multicurrency_code = $obj->multicurrency_code;
1739 $this->multicurrency_tx = $obj->multicurrency_tx;
1740 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1741 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1742 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1748 $this->db->free($resql);
1750 $this->lines = array();
1761 $this->error =
"Record Not Found";
1764 $this->error = $this->db->lasterror();
1783 if (isset($this->
ref)) {
1784 $this->
ref = trim($this->
ref);
1786 if (isset($this->ref_client)) {
1787 $this->ref_client = trim($this->ref_client);
1789 if (isset($this->note) || isset($this->note_private)) {
1790 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1792 if (isset($this->note_public)) {
1793 $this->note_public = trim($this->note_public);
1795 if (isset($this->model_pdf)) {
1796 $this->model_pdf = trim($this->model_pdf);
1798 if (isset($this->import_key)) {
1799 $this->import_key = trim($this->import_key);
1801 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1802 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1809 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1810 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1811 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1812 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1813 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1814 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1815 if (!empty($this->fin_validite)) {
1816 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1818 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1819 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1820 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1821 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1822 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1823 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1824 $sql .=
" fk_statut=".(isset($this->
status) ? $this->
status :
"null").
",";
1825 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1826 $sql .=
" fk_user_valid=".(isset($this->user_validation_id) ? $this->user_validation_id :
"null").
",";
1827 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1828 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1829 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1830 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1831 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1832 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1833 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1834 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1835 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1836 $sql .=
" WHERE rowid=".((int) $this->
id);
1840 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1841 $resql = $this->db->query($sql);
1844 $this->errors[] =
"Error ".$this->db->lasterror();
1854 if (!$error && !$notrigger) {
1865 foreach ($this->errors as $errmsg) {
1866 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1867 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1869 $this->db->rollback();
1872 $this->db->commit();
1887 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $sqlforgedfilters =
'')
1890 $this->lines = array();
1892 $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,';
1893 $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,';
1894 $sql .=
' d.fk_unit,';
1895 $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,';
1896 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1897 $sql .=
' d.date_start, d.date_end,';
1898 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1899 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1900 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1901 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1902 if ($only_product) {
1903 $sql .=
' AND p.fk_product_type = 0';
1905 if ($sqlforgedfilters) {
1906 $sql .= $sqlforgedfilters;
1908 $sql .=
' ORDER by d.rang';
1910 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1911 $result = $this->db->query($sql);
1913 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1915 $num = $this->db->num_rows($result);
1919 $objp = $this->db->fetch_object($result);
1923 $line->rowid = $objp->rowid;
1924 $line->id = $objp->rowid;
1925 $line->fk_propal = $objp->fk_propal;
1926 $line->fk_parent_line = $objp->fk_parent_line;
1927 $line->product_type = $objp->product_type;
1928 $line->label = $objp->custom_label;
1929 $line->desc = $objp->description;
1930 $line->description = $objp->description;
1931 $line->qty = $objp->qty;
1932 $line->vat_src_code = $objp->vat_src_code;
1933 $line->tva_tx = $objp->tva_tx;
1934 $line->localtax1_tx = $objp->localtax1_tx;
1935 $line->localtax2_tx = $objp->localtax2_tx;
1936 $line->localtax1_type = $objp->localtax1_type;
1937 $line->localtax2_type = $objp->localtax2_type;
1938 $line->subprice = $objp->subprice;
1939 $line->fk_remise_except = $objp->fk_remise_except;
1940 $line->remise_percent = $objp->remise_percent;
1941 $line->price = $objp->price;
1943 $line->info_bits = $objp->info_bits;
1944 $line->total_ht = $objp->total_ht;
1945 $line->total_tva = $objp->total_tva;
1946 $line->total_localtax1 = $objp->total_localtax1;
1947 $line->total_localtax2 = $objp->total_localtax2;
1948 $line->total_ttc = $objp->total_ttc;
1949 $line->fk_fournprice = $objp->fk_fournprice;
1950 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1951 $line->pa_ht = $marginInfos[0];
1952 $line->marge_tx = $marginInfos[1];
1953 $line->marque_tx = $marginInfos[2];
1954 $line->special_code = $objp->special_code;
1955 $line->rang = $objp->rang;
1957 $line->fk_product = $objp->fk_product;
1959 $line->ref = $objp->product_ref;
1960 $line->libelle = $objp->product_label;
1962 $line->product_ref = $objp->product_ref;
1963 $line->product_label = $objp->product_label;
1964 $line->product_desc = $objp->product_desc;
1965 $line->product_tobatch = $objp->product_tobatch;
1966 $line->product_barcode = $objp->product_barcode;
1968 $line->fk_product_type = $objp->fk_product_type;
1969 $line->fk_unit = $objp->fk_unit;
1970 $line->weight = $objp->weight;
1971 $line->weight_units = $objp->weight_units;
1972 $line->volume = $objp->volume;
1973 $line->volume_units = $objp->volume_units;
1975 $line->date_start = $this->db->jdate($objp->date_start);
1976 $line->date_end = $this->db->jdate($objp->date_end);
1979 $line->fk_multicurrency = $objp->fk_multicurrency;
1980 $line->multicurrency_code = $objp->multicurrency_code;
1981 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1982 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1983 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1984 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1986 $line->fetch_optionals();
1989 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1990 $tmpproduct =
new Product($this->db);
1991 $tmpproduct->fetch($objp->fk_product);
1992 $tmpproduct->getMultiLangs();
1994 $line->multilangs = $tmpproduct->multilangs;
1997 $this->lines[$i] = $line;
2002 $this->db->free($result);
2006 $this->error = $this->db->lasterror();
2018 public function valid($user, $notrigger = 0)
2022 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2027 if ($this->
status == self::STATUS_VALIDATED) {
2028 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
2032 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'creer'))
2033 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'propal_advance',
'validate')))) {
2034 $this->error =
'ErrorPermissionDenied';
2035 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
2044 $soc =
new Societe($this->db);
2045 $soc->fetch($this->socid);
2048 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2055 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2056 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2057 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2060 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2061 $resql = $this->db->query($sql);
2068 if (!$error && !$notrigger) {
2070 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2078 $this->oldref = $this->ref;
2081 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2083 $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).
"'";
2084 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2085 $resql = $this->db->query($sql);
2088 $this->error = $this->db->lasterror();
2090 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2091 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2092 $resql = $this->db->query($sql);
2095 $this->error = $this->db->lasterror();
2101 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2102 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2103 if (!$error && file_exists($dirsource)) {
2104 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2105 if (@rename($dirsource, $dirdest)) {
2108 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2109 foreach ($listoffiles as $fileentry) {
2110 $dirsource = $fileentry[
'name'];
2111 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2112 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2113 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2114 @rename($dirsource, $dirdest);
2123 $this->user_validation_id = $user->id;
2124 $this->datev = $now;
2125 $this->date_validation = $now;
2127 $this->db->commit();
2130 $this->db->rollback();
2149 $this->error =
'ErrorBadParameter';
2150 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2154 if ($user->hasRight(
'propal',
'creer')) {
2159 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2160 $sql .=
" WHERE rowid = ".((int) $this->
id);
2163 $resql = $this->db->query($sql);
2165 $this->errors[] = $this->db->error();
2170 $this->oldcopy = clone $this;
2171 $this->date = $date;
2172 $this->datep = $date;
2175 if (!$notrigger && empty($error)) {
2185 $this->db->commit();
2188 foreach ($this->errors as $errmsg) {
2189 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2190 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2192 $this->db->rollback();
2212 if ($user->hasRight(
'propal',
'creer')) {
2217 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2218 $sql .=
" WHERE rowid = ".((int) $this->
id);
2222 $resql = $this->db->query($sql);
2224 $this->errors[] = $this->db->error();
2230 $this->oldcopy = clone $this;
2231 $this->fin_validite = $date_end_validity;
2234 if (!$notrigger && empty($error)) {
2244 $this->db->commit();
2247 foreach ($this->errors as $errmsg) {
2248 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2249 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2251 $this->db->rollback();
2285 if ($user->hasRight(
'propal',
'creer')) {
2290 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2291 $sql .=
" SET date_livraison = ".(isDolTms($delivery_date) ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2292 $sql .=
" WHERE rowid = ".((int) $this->
id);
2295 $resql = $this->db->query($sql);
2297 $this->errors[] = $this->db->error();
2302 $this->oldcopy = clone $this;
2303 $this->delivery_date = $delivery_date;
2306 if (!$notrigger && empty($error)) {
2316 $this->db->commit();
2319 foreach ($this->errors as $errmsg) {
2320 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2321 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2323 $this->db->rollback();
2343 if ($user->hasRight(
'propal',
'creer') && $this->status >= self::STATUS_DRAFT) {
2348 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2349 $sql .=
" SET fk_availability = ".((int) $id);
2350 $sql .=
" WHERE rowid = ".((int) $this->
id);
2352 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2353 $resql = $this->db->query($sql);
2355 $this->errors[] = $this->db->error();
2360 $this->oldcopy = clone $this;
2361 $this->fk_availability = $id;
2362 $this->availability_id = $id;
2365 if (!$notrigger && empty($error)) {
2375 $this->db->commit();
2378 foreach ($this->errors as $errmsg) {
2379 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2380 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2382 $this->db->rollback();
2386 $error_str =
'Propal status do not meet requirement '.$this->status;
2388 $this->error = $error_str;
2389 $this->errors[] = $this->error;
2406 if ($user->hasRight(
'propal',
'creer') && $this->status >= self::STATUS_DRAFT) {
2411 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2412 $sql .=
" SET fk_input_reason = ".((int) $id);
2413 $sql .=
" WHERE rowid = ".((int) $this->
id);
2416 $resql = $this->db->query($sql);
2418 $this->errors[] = $this->db->error();
2424 $this->oldcopy = clone $this;
2426 $this->demand_reason_id = $id;
2430 if (!$notrigger && empty($error)) {
2440 $this->db->commit();
2443 foreach ($this->errors as $errmsg) {
2444 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2445 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2447 $this->db->rollback();
2451 $error_str =
'Propal status do not meet requirement '.$this->status;
2453 $this->error = $error_str;
2454 $this->errors[] = $this->error;
2471 if ($user->hasRight(
'propal',
'creer')) {
2476 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2477 $sql .=
" WHERE rowid = ".((int) $this->
id);
2479 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2480 $resql = $this->db->query($sql);
2482 $this->errors[] = $this->db->error();
2487 $this->oldcopy = clone $this;
2488 $this->ref_client = $ref_client;
2491 if (!$notrigger && empty($error)) {
2501 $this->db->commit();
2504 foreach ($this->errors as $errmsg) {
2505 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2506 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2508 $this->db->rollback();
2526 public function reopen($user, $status, $note =
'', $notrigger = 0)
2530 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2531 $sql .=
" SET fk_statut = ".((int) $status).
",";
2532 if (!empty($note)) {
2533 $sql .=
" note_private = '".$this->db->escape($note).
"',";
2535 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2536 $sql .=
" WHERE rowid = ".((int) $this->
id);
2540 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2541 $resql = $this->db->query($sql);
2544 $this->errors[] =
"Error ".$this->db->lasterror();
2559 if (!empty($this->errors)) {
2560 foreach ($this->errors as $errmsg) {
2561 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2562 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2565 $this->db->rollback();
2568 $this->statut = $status;
2571 $this->db->commit();
2586 public function closeProposal($user, $status, $note_private =
'', $notrigger = 0, $note_public =
'')
2588 global $langs,$conf;
2595 $newprivatenote =
dol_concatdesc($this->note_private, $note_private);
2596 $newpublicnote =
dol_concatdesc($this->note_public, $note_public);
2599 $date_signature = $now;
2600 $fk_user_signature = $user->id;
2602 $this->
info($this->
id);
2603 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2604 $date_signature = $now;
2605 $fk_user_signature = $user->id;
2607 $date_signature = $this->date_signature;
2608 $fk_user_signature = $this->user_signature->id;
2612 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2613 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"', note_public = '".$this->db->escape($newpublicnote).
"'";
2614 if ($status == self::STATUS_SIGNED) {
2615 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2617 $sql .=
" WHERE rowid = ".((int) $this->
id);
2619 $resql = $this->db->query($sql);
2623 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2625 if ($status == self::STATUS_SIGNED) {
2626 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2627 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_TOBILL') ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2630 $soc =
new Societe($this->db);
2631 $soc->id = $this->socid;
2632 $result = $soc->setAsCustomer();
2635 $this->error = $this->db->lasterror();
2636 $this->db->rollback();
2643 $outputlangs = $langs;
2645 $outputlangs =
new Translate(
"", $conf);
2646 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2647 $outputlangs->setDefaultLang($newlang);
2656 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2660 $this->oldcopy = clone $this;
2661 $this->statut = $status;
2663 $this->date_signature = $date_signature;
2664 $this->note_private = $newprivatenote;
2667 if (!$notrigger && empty($error)) {
2677 $this->db->commit();
2680 $this->statut = $this->oldcopy->status;
2681 $this->
status = $this->oldcopy->status;
2682 $this->date_signature = $this->oldcopy->date_signature;
2683 $this->note_private = $this->oldcopy->note_private;
2685 $this->db->rollback();
2689 $this->error = $this->db->lasterror();
2690 $this->db->rollback();
2705 global $conf, $langs;
2712 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2718 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2719 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2720 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2723 $resql = $this->db->query($sql);
2725 $this->errors[] = $this->db->error();
2728 $num = $this->db->affected_rows($resql);
2736 $outputlangs = $langs;
2738 $outputlangs =
new Translate(
"", $conf);
2739 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2740 $outputlangs->setDefaultLang($newlang);
2749 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2752 $this->oldcopy = clone $this;
2755 $this->date_cloture = $now;
2756 $this->note_private = $newprivatenote;
2759 if (!$notrigger && empty($error)) {
2769 $this->db->commit();
2772 foreach ($this->errors as $errmsg) {
2773 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2774 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2776 $this->db->rollback();
2793 $sql =
"UPDATE ". MAIN_DB_PREFIX .
"propal";
2794 $sql .=
" SET fk_statut = " . self::STATUS_CANCELED .
",";
2795 $sql .=
" fk_user_modif = " . ((int) $user->id);
2796 $sql .=
" WHERE rowid = " . ((int) $this->
id);
2798 dol_syslog(get_class($this).
"::cancel", LOG_DEBUG);
2799 if ($this->db->query($sql)) {
2812 $this->db->commit();
2815 foreach ($this->errors as $errmsg) {
2816 dol_syslog(get_class($this).
"::cancel ".$errmsg, LOG_ERR);
2817 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2819 $this->db->rollback();
2823 $this->error = $this->db->error();
2824 $this->db->rollback();
2843 if ($this->
status <= self::STATUS_DRAFT) {
2847 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2851 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2852 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2853 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2854 $sql .=
" WHERE rowid = ".((int) $this->
id);
2856 $resql = $this->db->query($sql);
2858 $this->errors[] = $this->db->error();
2863 $this->oldcopy = clone $this;
2866 if (!$notrigger && empty($error)) {
2879 $this->db->commit();
2882 foreach ($this->errors as $errmsg) {
2883 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2884 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2886 $this->db->rollback();
2906 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2913 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2914 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2915 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2916 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2917 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2918 $sql .=
" AND p.fk_soc = s.rowid";
2919 $sql .=
" AND p.fk_statut = c.id";
2923 if (!$user->hasRight(
'societe',
'client',
'voir')) {
2924 $search_sale = $user->id;
2927 if ($search_sale && $search_sale !=
'-1') {
2928 if ($search_sale == -2) {
2929 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
2930 } elseif ($search_sale > 0) {
2931 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc AND sc.fk_user = ".((int) $search_sale).
")";
2936 $sql .=
" AND p.fk_soc = ".((int) $socid);
2939 $sql .=
" AND p.fk_statut = ".((int) self::STATUS_DRAFT);
2941 if ($notcurrentuser > 0) {
2942 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2944 $sql .= $this->db->order($sortfield, $sortorder);
2945 $sql .= $this->db->plimit($limit, $offset);
2947 $result = $this->db->query($sql);
2949 $num = $this->db->num_rows($result);
2953 $obj = $this->db->fetch_object($result);
2955 if ($shortlist == 1) {
2956 $ga[$obj->propalid] = $obj->ref;
2957 } elseif ($shortlist == 2) {
2958 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2960 $ga[$i][
'id'] = $obj->propalid;
2961 $ga[$i][
'ref'] = $obj->ref;
2962 $ga[$i][
'name'] = $obj->name;
2996 $linkedInvoices = array();
2999 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
3002 foreach ($objectid as $key =>
$object) {
3004 if ($objecttype ==
'facture') {
3009 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
3010 foreach ($subobjectid as $subkey => $subobject) {
3011 if ($subobjecttype ==
'facture') {
3012 $linkedInvoices[] = $subobject;
3020 if (count($linkedInvoices) > 0) {
3021 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
3022 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
3023 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
3025 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
3026 $resql = $this->db->query($sql);
3029 $tab_sqlobj = array();
3030 $nump = $this->db->num_rows($resql);
3031 for ($i = 0; $i < $nump; $i++) {
3032 $sqlobj = $this->db->fetch_object($resql);
3033 $tab_sqlobj[] = $sqlobj;
3035 $this->db->free($resql);
3037 $nump = count($tab_sqlobj);
3041 while ($i < $nump) {
3042 $obj = array_shift($tab_sqlobj);
3065 public function delete($user, $notrigger = 0)
3068 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3084 if (!$error && !empty($this->table_element_line)) {
3085 $tabletodelete = $this->table_element_line;
3086 $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).
")";
3087 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3088 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3090 $this->error = $this->db->lasterror();
3091 $this->errors[] = $this->error;
3092 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3117 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3123 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3124 $res = $this->db->query($sql);
3127 $this->error = $this->db->lasterror();
3128 $this->errors[] = $this->error;
3129 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3145 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3146 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3147 $file = $dir.
"/".$ref.
".pdf";
3148 if (file_exists($file)) {
3152 $this->error =
'ErrorFailToDeleteFile';
3153 $this->errors[] = $this->error;
3154 $this->db->rollback();
3158 if (file_exists($dir)) {
3161 $this->error =
'ErrorFailToDeleteDir';
3162 $this->errors[] = $this->error;
3163 $this->db->rollback();
3171 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3172 $this->db->commit();
3175 $this->db->rollback();
3192 if ($this->
status >= self::STATUS_DRAFT) {
3197 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3198 $sql .=
' SET fk_availability = '.((int) $availability_id);
3199 $sql .=
' WHERE rowid='.((int) $this->
id);
3201 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3202 $resql = $this->db->query($sql);
3204 $this->errors[] = $this->db->error();
3209 $this->oldcopy = clone $this;
3210 $this->availability_id = $availability_id;
3213 if (!$notrigger && empty($error)) {
3223 $this->db->commit();
3226 foreach ($this->errors as $errmsg) {
3227 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3228 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3230 $this->db->rollback();
3234 $error_str =
'Propal status do not meet requirement '.$this->status;
3236 $this->error = $error_str;
3237 $this->errors[] = $this->error;
3256 if ($this->
status >= self::STATUS_DRAFT) {
3261 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3262 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3263 $sql .=
' WHERE rowid='.((int) $this->
id);
3265 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3266 $resql = $this->db->query($sql);
3268 $this->errors[] = $this->db->error();
3273 $this->oldcopy = clone $this;
3274 $this->demand_reason_id = $demand_reason_id;
3277 if (!$notrigger && empty($error)) {
3287 $this->db->commit();
3290 foreach ($this->errors as $errmsg) {
3291 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3292 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3294 $this->db->rollback();
3298 $error_str =
'Propal status do not meet requirement '.$this->status;
3300 $this->error = $error_str;
3301 $this->errors[] = $this->error;
3315 $sql =
"SELECT c.rowid, ";
3316 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3317 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3318 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3319 $sql .=
" WHERE c.rowid = ".((int) $id);
3321 $result = $this->db->query($sql);
3324 if ($this->db->num_rows($result)) {
3325 $obj = $this->db->fetch_object($result);
3327 $this->
id = $obj->rowid;
3329 $this->date_creation = $this->db->jdate($obj->datec);
3330 $this->date_validation = $this->db->jdate($obj->datev);
3331 $this->date_signature = $this->db->jdate($obj->date_signature);
3332 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3334 $this->user_creation_id = $obj->fk_user_author;
3335 $this->user_validation_id = $obj->fk_user_valid;
3337 if ($obj->fk_user_signature) {
3338 $user_signature =
new User($this->db);
3339 $user_signature->fetch($obj->fk_user_signature);
3340 $this->user_signature = $user_signature;
3343 $this->user_closing_id = $obj->fk_user_cloture;
3345 $this->db->free($result);
3374 global $hookmanager;
3377 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3379 $langs->load(
"propal");
3380 $this->labelStatus[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceled");
3381 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3382 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3383 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3384 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3385 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3386 $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceledShort");
3387 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3388 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3389 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3390 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3391 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3395 if ($status == self::STATUS_CANCELED) {
3396 $statusType =
'status9';
3397 } elseif ($status == self::STATUS_DRAFT) {
3398 $statusType =
'status0';
3399 } elseif ($status == self::STATUS_VALIDATED) {
3400 $statusType =
'status1';
3401 } elseif ($status == self::STATUS_SIGNED) {
3402 $statusType =
'status4';
3403 } elseif ($status == self::STATUS_NOTSIGNED) {
3404 $statusType =
'status9';
3405 } elseif ($status == self::STATUS_BILLED) {
3406 $statusType =
'status6';
3409 $parameters = array(
'status' => $status,
'mode' => $mode);
3410 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3413 return $hookmanager->resPrint;
3416 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3431 global $conf, $langs;
3435 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3436 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3437 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3438 if ($mode ==
'opened') {
3439 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3441 if ($mode ==
'signed') {
3442 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3446 if (!$user->hasRight(
'societe',
'client',
'voir')) {
3447 $search_sale = $user->id;
3450 if ($search_sale && $search_sale !=
'-1') {
3451 if ($search_sale == -2) {
3452 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3453 } elseif ($search_sale > 0) {
3454 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc AND sc.fk_user = ".((int) $search_sale).
")";
3458 $resql = $this->db->query($sql);
3460 $langs->load(
"propal");
3465 $label = $labelShort =
'';
3466 if ($mode ==
'opened') {
3467 $delay_warning = $conf->propal->cloture->warning_delay;
3469 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3470 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3472 if ($mode ==
'signed') {
3473 $delay_warning = $conf->propal->facturation->warning_delay;
3475 $label = $langs->trans(
"PropalsToBill");
3476 $labelShort = $langs->trans(
"ToBill");
3480 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3481 $response->label = $label;
3482 $response->labelShort = $labelShort;
3483 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3484 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3488 while ($obj = $this->db->fetch_object($resql)) {
3489 $response->nbtodo++;
3490 $response->total += $obj->total_ht;
3492 if ($mode ==
'opened') {
3493 $datelimit = $this->db->jdate($obj->datefin);
3494 if ($datelimit < ($now - $delay_warning)) {
3495 $response->nbtodolate++;
3504 $this->error = $this->db->error();
3519 global $conf, $langs;
3524 $sql =
"SELECT rowid";
3525 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3526 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3527 $sql .= $this->db->plimit(100);
3529 $resql = $this->db->query($sql);
3531 $num_prods = $this->db->num_rows($resql);
3533 while ($i < $num_prods) {
3535 $row = $this->db->fetch_row($resql);
3536 $prodids[$i] = $row[0];
3542 $this->
ref =
'SPECIMEN';
3543 $this->ref_client =
'NEMICEPS';
3544 $this->specimen = 1;
3546 $this->date = time();
3547 $this->fin_validite = $this->date + 3600 * 24 * 30;
3548 $this->cond_reglement_id = 1;
3549 $this->cond_reglement_code =
'RECEP';
3550 $this->mode_reglement_id = 7;
3551 $this->mode_reglement_code =
'CHQ';
3552 $this->availability_id = 1;
3553 $this->availability_code =
'AV_NOW';
3554 $this->demand_reason_id = 1;
3555 $this->demand_reason_code =
'SRC_00';
3556 $this->note_public =
'This is a comment (public)';
3557 $this->note_private =
'This is a comment (private)';
3559 $this->multicurrency_tx = 1;
3560 $this->multicurrency_code = $conf->currency;
3565 while ($xnbp < $nbp) {
3567 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3569 $line->subprice = 100;
3572 $line->localtax1_tx = 0;
3573 $line->localtax2_tx = 0;
3575 $line->total_ht = 50;
3576 $line->total_ttc = 60;
3577 $line->total_tva = 10;
3578 $line->remise_percent = 50;
3580 $line->total_ht = 100;
3581 $line->total_ttc = 120;
3582 $line->total_tva = 20;
3583 $line->remise_percent = 00;
3586 if ($num_prods > 0) {
3587 $prodid = mt_rand(1, $num_prods);
3588 $line->fk_product = $prodids[$prodid];
3589 $line->product_ref =
'SPECIMEN';
3592 $this->lines[$xnbp] = $line;
3594 $this->total_ht += $line->total_ht;
3595 $this->total_tva += $line->total_tva;
3596 $this->total_ttc += $line->total_ttc;
3613 $this->nb = array();
3616 $sql =
"SELECT count(p.rowid) as nb";
3617 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3618 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3619 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3623 if (!$user->hasRight(
'societe',
'client',
'voir')) {
3624 $search_sale = $user->id;
3627 if ($search_sale && $search_sale !=
'-1') {
3628 if ($search_sale == -2) {
3629 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3630 } elseif ($search_sale > 0) {
3631 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc AND sc.fk_user = ".((int) $search_sale).
")";
3635 $resql = $this->db->query($sql);
3638 while ($obj = $this->db->fetch_object($resql)) {
3639 $this->nb[
"proposals"] = $obj->nb;
3641 $this->db->free($resql);
3645 $this->error = $this->db->error();
3660 global $conf, $langs;
3661 $langs->load(
"propal");
3665 if (!empty($classname)) {
3668 $file = $classname.
".php";
3671 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3672 foreach ($dirmodels as $reldir) {
3676 $mybool = ((bool) @include_once $dir.$file) || $mybool;
3684 $obj =
new $classname();
3685 '@phan-var-force ModeleNumRefPropales $obj';
3687 $numref = $obj->getNextValue($soc, $this);
3689 if ($numref !=
"") {
3692 $this->error = $obj->error;
3697 $langs->load(
"errors");
3698 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3711 global $conf, $langs, $user;
3713 $langs->load(
'propal');
3715 $nofetch = !empty($params[
'nofetch']);
3718 return [
'optimize' => $langs->trans(
"Proposal")];
3720 if ($user->hasRight(
'propal',
'lire')) {
3721 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3722 if (isset($this->
status)) {
3723 $datas[
'status'] =
' '.$this->getLibStatut(5);
3725 if (!empty($this->
ref)) {
3726 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3729 $langs->load(
'companies');
3730 if (empty($this->thirdparty)) {
3733 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3735 if (!empty($this->ref_customer)) {
3736 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
3739 $langs->load(
'project');
3740 if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) {
3742 if ($res > 0 && $this->project instanceof
Project) {
3743 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3747 if (!empty($this->total_ht)) {
3748 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3750 if (!empty($this->total_tva)) {
3751 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3753 if (!empty($this->total_ttc)) {
3754 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3756 if (!empty($this->date)) {
3757 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3759 if (!empty($this->delivery_date)) {
3760 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3778 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3780 global $langs, $conf, $user, $hookmanager;
3782 if (!empty($conf->dol_no_mouse_hover)) {
3789 'objecttype' => $this->element,
3790 'option' => $option,
3793 $classfortooltip =
'classfortooltip';
3796 $classfortooltip =
'classforajaxtooltip';
3797 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3804 if ($user->hasRight(
'propal',
'lire')) {
3805 if ($option ==
'') {
3806 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3807 } elseif ($option ==
'compta') {
3808 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3809 } elseif ($option ==
'expedition') {
3810 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3811 } elseif ($option ==
'document') {
3812 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3815 if ($option !=
'nolink') {
3817 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3818 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3819 $add_save_lastsearch_values = 1;
3821 if ($add_save_lastsearch_values) {
3822 $url .=
'&save_lastsearch_values=1';
3828 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3830 $label = $langs->trans(
"Proposal");
3831 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3833 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3834 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3837 $linkstart =
'<a href="'.$url.
'"';
3838 $linkstart .= $linkclose.
'>';
3841 $result .= $linkstart;
3843 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3845 if ($withpicto != 2) {
3846 $result .= $this->ref;
3848 $result .= $linkend;
3850 if ($addlinktonotes >= 0) {
3853 if ($addlinktonotes == 0) {
3854 if (!empty($this->note_private) || !empty($this->note_public)) {
3855 $txttoshow = $langs->trans(
'ViewPrivateNote');
3857 } elseif ($addlinktonotes == 1) {
3858 if (!empty($this->note_private)) {
3861 } elseif ($addlinktonotes == 2) {
3862 if (!empty($this->note_public)) {
3865 } elseif ($addlinktonotes == 3) {
3866 if ($user->socid > 0) {
3867 if (!empty($this->note_public)) {
3871 if (!empty($this->note_public)) {
3874 if (!empty($this->note_private)) {
3875 if (!empty($txttoshow)) {
3876 $txttoshow .=
'<br><br>';
3884 $result .=
' <span class="note inline-block">';
3885 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3888 $result .=
'</span>';
3893 $hookmanager->initHooks(array($this->element .
'dao'));
3894 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
3895 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3897 $result = $hookmanager->resPrint;
3899 $result .= $hookmanager->resPrint;
3912 return $this->
fetch_lines(0, 0, $sqlforgedfilters);
3926 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3928 global $conf, $langs;
3930 $langs->load(
"propale");
3931 $outputlangs->load(
"products");
3936 if ($this->model_pdf) {
3937 $modele = $this->model_pdf;
3943 $modelpath =
"core/modules/propale/doc/";
3945 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3993 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
3995 $return =
'<div class="box-flex-item box-flex-grow-zero">';
3996 $return .=
'<div class="info-box info-box-sm">';
3997 $return .=
'<div class="info-box-icon bg-infobox-action">';
3999 $return .=
'</div>';
4000 $return .=
'<div class="info-box-content">';
4001 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
4002 if ($selected >= 0) {
4003 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
4005 if (!empty($arraydata[
'projectlink'])) {
4006 $return .=
'<span class="info-box-ref"> | '.$arraydata[
'projectlink'].
'</span>';
4009 if (property_exists($this,
'thirdparty') && is_object($this->thirdparty)) {
4010 $return .=
'<div class="info-box-ref tdoverflowmax150">'.$this->thirdparty->getNomUrl(1).
'</div>';
4012 if (property_exists($this,
'total_ht')) {
4013 $return .=
'<span class="info-box-label amount" title="'.$langs->trans(
"AmountHT").
'">'.
price($this->total_ht).
'</span>';
4015 if (!empty($arraydata[
'authorlink'])) {
4016 $return .=
' <span class="info-box-label">'.$arraydata[
'authorlink'].
'</span>';
4018 if (method_exists($this,
'getLibStatut')) {
4019 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
4021 $return .=
'</div>';
4022 $return .=
'</div>';
4023 $return .=
'</div>';
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
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.
update_price($exclspec=0, $roundingadjust='auto', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
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.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check if an object id or ref exists If you don't need or want to instantiate the object and just need...
updateRangOfLine($rowid, $rang)
Update position of line (rang)
fetch_project()
Load the project with id $this->fk_project into this->project.
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.
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.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
Class to manage projects.
Class to manage proposals.
getTooltipContentArray($params)
getTooltipContentArray
const STATUS_DRAFT
Draft status.
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 clickable link of object (with eventually picto)
getKanbanView($option='', $arraydata=null)
Return clickable 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.
classifyBilled(User $user, $notrigger=0, $note='')
Classify the proposal to status Billed.
getLinesArray($sqlforgedfilters='')
Retrieve an array of proposal lines.
fetch($rowid, $ref='', $ref_ext='', $forceentity=0)
Load a proposal from database.
set_availability($user, $id, $notrigger=0)
Set delivery.
fetch_lines($only_product=0, $loadalsotranslation=0, $sqlforgedfilters='')
Load array lines.
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=array(), $fk_unit=null, $pu_ht_devise=0, $notrigger=0, $rang=0)
Update a proposal line.
update(User $user, $notrigger=0)
Update database.
closeProposal($user, $status, $note_private='', $notrigger=0, $note_public='')
Close/set the commercial proposal to status signed or refused (fill also date signature)
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, ...)
const STATUS_CANCELED
Canceled status.
insert_discount($idremise)
Add a discount line into an proposal (as a proposal line) using an existing absolute discount (Consum...
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.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
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.
initAsSpecimen()
Initialise an instance with random values.
reopen($user, $status, $note='', $notrigger=0)
Reopen the commercial proposal.
deleteLine($lineid, $id=0)
Delete detail line.
__construct($db, $socid=0, $propalid=0)
Constructor.
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
setCancel(User $user)
Cancel the proposal.
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=array(), $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...
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.
loadStateBoard()
Load the indicators this->nb for the state board.
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.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
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($utf8_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.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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 '.
isDolTms($timestamp)
isDolTms check if a timestamp is valid.
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_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
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.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a 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...
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
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...
getMarginInfos($pv_ht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $pa_ht)
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.