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;
230 public $cond_reglement_code;
235 public $cond_reglement;
240 public $cond_reglement_doc;
245 public $mode_reglement_code;
250 public $mode_reglement;
257 public $deposit_percent;
269 public $address_type;
280 public $availability_id;
287 public $fk_availability;
292 public $availability_code;
297 public $availability;
302 public $duree_validite;
307 public $demand_reason_id;
312 public $demand_reason_code;
317 public $demand_reason;
322 public $warehouse_id;
327 public $lines = array();
334 public $labelStatus = array();
335 public $labelStatusShort = array();
366 public $fields = array(
367 'rowid' => array(
'type' =>
'integer',
'label' =>
'TechnicalID',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 10),
368 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'default' =>
'1',
'enabled' => 1,
'visible' => -2,
'notnull' => 1,
'position' => 15,
'index' => 1),
369 'ref' => array(
'type' =>
'varchar(30)',
'label' =>
'Ref',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'showoncombobox' => 1,
'position' => 20),
370 'ref_client' => array(
'type' =>
'varchar(255)',
'label' =>
'RefCustomer',
'enabled' => 1,
'visible' => -1,
'position' => 22),
371 'ref_ext' => array(
'type' =>
'varchar(255)',
'label' =>
'RefExt',
'enabled' => 1,
'visible' => 0,
'position' => 40),
372 'fk_soc' => array(
'type' =>
'integer:Societe:societe/class/societe.class.php',
'label' =>
'ThirdParty',
'enabled' =>
'isModEnabled("societe")',
'visible' => -1,
'position' => 23),
373 '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),
374 'tms' => array(
'type' =>
'timestamp',
'label' =>
'DateModification',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 25),
375 'datec' => array(
'type' =>
'datetime',
'label' =>
'DateCreation',
'enabled' => 1,
'visible' => -1,
'position' => 55),
376 'datep' => array(
'type' =>
'date',
'label' =>
'Date',
'enabled' => 1,
'visible' => -1,
'position' => 60),
377 'fin_validite' => array(
'type' =>
'datetime',
'label' =>
'DateEnd',
'enabled' => 1,
'visible' => -1,
'position' => 65),
378 'date_valid' => array(
'type' =>
'datetime',
'label' =>
'DateValidation',
'enabled' => 1,
'visible' => -1,
'position' => 70),
379 'date_cloture' => array(
'type' =>
'datetime',
'label' =>
'DateClosing',
'enabled' => 1,
'visible' => -1,
'position' => 75),
380 'fk_user_author' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user author',
'enabled' => 1,
'visible' => -1,
'position' => 80),
381 'fk_user_modif' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserModif',
'enabled' => 1,
'visible' => -2,
'notnull' => -1,
'position' => 85),
382 'fk_user_valid' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserValidation',
'enabled' => 1,
'visible' => -1,
'position' => 90),
383 'fk_user_cloture' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user cloture',
'enabled' => 1,
'visible' => -1,
'position' => 95),
384 'price' => array(
'type' =>
'double',
'label' =>
'Price',
'enabled' => 1,
'visible' => -1,
'position' => 105),
385 'total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalHT',
'enabled' => 1,
'visible' => -1,
'position' => 125,
'isameasure' => 1),
386 'total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'VAT',
'enabled' => 1,
'visible' => -1,
'position' => 130,
'isameasure' => 1),
387 'localtax1' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax1',
'enabled' => 1,
'visible' => -1,
'position' => 135,
'isameasure' => 1),
388 'localtax2' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax2',
'enabled' => 1,
'visible' => -1,
'position' => 140,
'isameasure' => 1),
389 'total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalTTC',
'enabled' => 1,
'visible' => -1,
'position' => 145,
'isameasure' => 1),
390 'fk_account' => array(
'type' =>
'integer',
'label' =>
'BankAccount',
'enabled' =>
'isModEnabled("bank")',
'visible' => -1,
'position' => 150),
391 'fk_currency' => array(
'type' =>
'varchar(3)',
'label' =>
'Currency',
'enabled' => 1,
'visible' => -1,
'position' => 155),
392 'fk_cond_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentTerm',
'enabled' => 1,
'visible' => -1,
'position' => 160),
393 'deposit_percent' => array(
'type' =>
'varchar(63)',
'label' =>
'DepositPercent',
'enabled' => 1,
'visible' => -1,
'position' => 161),
394 'fk_mode_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentMode',
'enabled' => 1,
'visible' => -1,
'position' => 165),
395 'note_private' => array(
'type' =>
'html',
'label' =>
'NotePrivate',
'enabled' => 1,
'visible' => 0,
'position' => 170),
396 'note_public' => array(
'type' =>
'html',
'label' =>
'NotePublic',
'enabled' => 1,
'visible' => 0,
'position' => 175),
397 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'PDFTemplate',
'enabled' => 1,
'visible' => 0,
'position' => 180),
398 'date_livraison' => array(
'type' =>
'date',
'label' =>
'DateDeliveryPlanned',
'enabled' => 1,
'visible' => -1,
'position' => 185),
399 'fk_shipping_method' => array(
'type' =>
'integer',
'label' =>
'ShippingMethod',
'enabled' => 1,
'visible' => -1,
'position' => 190),
400 'fk_warehouse' => array(
'type' =>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label' =>
'Fk warehouse',
'enabled' =>
'isModEnabled("stock")',
'visible' => -1,
'position' => 191),
401 'fk_availability' => array(
'type' =>
'integer',
'label' =>
'Availability',
'enabled' => 1,
'visible' => -1,
'position' => 195),
402 'fk_delivery_address' => array(
'type' =>
'integer',
'label' =>
'DeliveryAddress',
'enabled' => 1,
'visible' => 0,
'position' => 200),
403 'fk_input_reason' => array(
'type' =>
'integer',
'label' =>
'InputReason',
'enabled' => 1,
'visible' => -1,
'position' => 205),
404 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => -1,
'position' => 215),
405 'fk_incoterms' => array(
'type' =>
'integer',
'label' =>
'IncotermCode',
'enabled' =>
'$conf->incoterm->enabled',
'visible' => -1,
'position' => 220),
406 'location_incoterms' => array(
'type' =>
'varchar(255)',
'label' =>
'IncotermLabel',
'enabled' =>
'$conf->incoterm->enabled',
'visible' => -1,
'position' => 225),
407 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'MulticurrencyID',
'enabled' => 1,
'visible' => -1,
'position' => 230),
408 'multicurrency_code' => array(
'type' =>
'varchar(255)',
'label' =>
'MulticurrencyCurrency',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 235),
409 'multicurrency_tx' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyRate',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 240,
'isameasure' => 1),
410 'multicurrency_total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountHT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 245,
'isameasure' => 1),
411 'multicurrency_total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountVAT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 250,
'isameasure' => 1),
412 'multicurrency_total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountTTC',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 255,
'isameasure' => 1),
413 'last_main_doc' => array(
'type' =>
'varchar(255)',
'label' =>
'LastMainDoc',
'enabled' => 1,
'visible' => -1,
'position' => 260),
414 'fk_statut' => array(
'type' =>
'smallint(6)',
'label' =>
'Status',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 500),
415 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -2,
'position' => 900),
456 $this->ismultientitymanaged = 1;
457 $this->socid = $socid;
458 $this->
id = $propalid;
460 $this->duree_validite =
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
476 public function add_product($idproduct, $qty, $remise_percent = 0)
479 global $conf, $mysoc;
485 dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
486 if ($idproduct > 0) {
487 $prod =
new Product($this->db);
488 $prod->fetch($idproduct);
490 $productdesc = $prod->description;
492 $tva_tx = (string)
get_default_tva($mysoc, $this->thirdparty, $prod->id);
494 if (empty($tva_tx)) {
499 $localtax1_tx =
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
500 $localtax2_tx =
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
503 if ($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
504 $price = $prod->multiprices[$this->thirdparty->price_level];
506 $price = $prod->price;
511 $line->fk_product = $idproduct;
512 $line->desc = $productdesc;
514 $line->subprice = $price;
515 $line->remise_percent = $remise_percent;
516 $line->vat_src_code = $vat_src_code;
517 $line->tva_tx = $tva_tx;
518 $line->fk_unit = $prod->fk_unit;
520 $line->info_bits = 1;
523 $this->lines[] = $line;
541 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
542 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
547 $result = $remise->fetch($idremise);
550 if ($remise->fk_facture) {
551 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
552 $this->db->rollback();
558 $line->context = $this->context;
560 $line->fk_propal = $this->id;
561 $line->fk_remise_except = $remise->id;
562 $line->desc = $remise->description;
563 $line->vat_src_code = $remise->vat_src_code;
564 $line->tva_tx = $remise->tva_tx;
565 $line->subprice = -(float) $remise->amount_ht;
566 $line->fk_product = 0;
568 $line->remise_percent = 0;
570 $line->info_bits = 2;
573 $line->price = -(float) $remise->amount_ht;
575 $line->total_ht = -(float) $remise->amount_ht;
576 $line->total_tva = -(float) $remise->amount_tva;
577 $line->total_ttc = -(float) $remise->amount_ttc;
579 $result = $line->insert();
586 $this->db->rollback();
590 $this->error = $line->error;
591 $this->errors = $line->errors;
592 $this->db->rollback();
596 $this->db->rollback();
638 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)
640 global $mysoc, $conf, $langs;
642 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);
644 if ($this->statut == self::STATUS_DRAFT) {
645 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
648 if (empty($remise_percent)) {
654 if (empty($info_bits)) {
660 if (empty($fk_parent_line) || $fk_parent_line < 0) {
664 $remise_percent =
price2num($remise_percent);
667 $pu_ht_devise =
price2num($pu_ht_devise);
669 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
675 if ($price_base_type ==
'HT') {
686 if ($date_start && $date_end && $date_start > $date_end) {
687 $langs->load(
"errors");
688 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
694 $product_type = $type;
695 if (!empty($fk_product) && $fk_product > 0) {
696 $product =
new Product($this->db);
697 $result = $product->fetch($fk_product);
698 $product_type = $product->type;
700 if (
getDolGlobalString(
'STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL') && $product_type == 0 && $product->stock_reel < $qty) {
701 $langs->load(
"errors");
702 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
703 $this->db->rollback();
718 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
719 $vat_src_code = $reg[1];
720 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
723 $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);
725 $total_ht = $tabprice[0];
726 $total_tva = $tabprice[1];
727 $total_ttc = $tabprice[2];
728 $total_localtax1 = $tabprice[9];
729 $total_localtax2 = $tabprice[10];
730 $pu_ht = $tabprice[3];
731 $pu_tva = $tabprice[4];
732 $pu_ttc = $tabprice[5];
735 $multicurrency_total_ht = $tabprice[16];
736 $multicurrency_total_tva = $tabprice[17];
737 $multicurrency_total_ttc = $tabprice[18];
738 $pu_ht_devise = $tabprice[19];
742 if ($ranktouse == -1) {
743 $rangmax = $this->
line_max($fk_parent_line);
744 $ranktouse = $rangmax + 1;
751 if ((
float) $remise_percent > 0) {
752 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
753 $price = (float) $pu - $remise;
759 $this->line->context = $this->context;
761 $this->line->fk_propal = $this->id;
762 $this->line->label = $label;
763 $this->line->desc = $desc;
764 $this->line->qty = $qty;
766 $this->line->vat_src_code = $vat_src_code;
767 $this->line->tva_tx = $txtva;
768 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
769 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
770 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
771 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
772 $this->line->fk_product = $fk_product;
773 $this->line->product_type = $type;
774 $this->line->fk_remise_except = $fk_remise_except;
775 $this->line->remise_percent = $remise_percent;
776 $this->line->subprice = $pu_ht;
777 $this->line->rang = $ranktouse;
778 $this->line->info_bits = $info_bits;
779 $this->line->total_ht = $total_ht;
780 $this->line->total_tva = $total_tva;
781 $this->line->total_localtax1 = $total_localtax1;
782 $this->line->total_localtax2 = $total_localtax2;
783 $this->line->total_ttc = $total_ttc;
784 $this->line->special_code = $special_code;
785 $this->line->fk_parent_line = $fk_parent_line;
786 $this->line->fk_unit = $fk_unit;
788 $this->line->date_start = $date_start;
789 $this->line->date_end = $date_end;
791 $this->line->fk_fournprice = $fk_fournprice;
792 $this->line->pa_ht = $pa_ht;
794 $this->line->origin_id = $origin_id;
795 $this->line->origin = $origin;
798 $this->line->fk_multicurrency = $this->fk_multicurrency;
799 $this->line->multicurrency_code = $this->multicurrency_code;
800 $this->line->multicurrency_subprice = $pu_ht_devise;
801 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
802 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
803 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
806 if (empty($qty) && empty($special_code)) {
807 $this->line->special_code = 3;
811 $this->line->price = $price;
813 if (is_array($array_options) && count($array_options) > 0) {
814 $this->line->array_options = $array_options;
817 $result = $this->line->insert();
820 if (!empty($fk_parent_line)) {
822 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
823 $linecount = count($this->lines);
824 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
830 if (empty($noupdateafterinsertline)) {
836 return $this->line->id;
838 $this->error = $this->db->error();
839 $this->db->rollback();
843 $this->error = $this->line->error;
844 $this->errors = $this->line->errors;
845 $this->db->rollback();
849 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
884 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)
886 global $mysoc, $langs;
888 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
889 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");
890 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
893 $remise_percent =
price2num($remise_percent);
896 $pu_ht_devise =
price2num($pu_ht_devise);
897 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
903 if (empty($qty) && empty($special_code)) {
906 if (!empty($qty) && $special_code == 3) {
913 if ($date_start && $date_end && $date_start > $date_end) {
914 $langs->load(
"errors");
915 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
919 if ($this->
status == self::STATUS_DRAFT) {
932 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
933 $vat_src_code = $reg[1];
934 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
939 $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);
940 $total_ht = $tabprice[0];
941 $total_tva = $tabprice[1];
942 $total_ttc = $tabprice[2];
943 $total_localtax1 = $tabprice[9];
944 $total_localtax2 = $tabprice[10];
945 $pu_ht = $tabprice[3];
946 $pu_tva = $tabprice[4];
947 $pu_ttc = $tabprice[5];
950 $multicurrency_total_ht = $tabprice[16];
951 $multicurrency_total_tva = $tabprice[17];
952 $multicurrency_total_ttc = $tabprice[18];
953 $pu_ht_devise = $tabprice[19];
958 if ((
float) $remise_percent > 0) {
959 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
960 $price = (float) $pu - $remise;
965 $line->fetch($rowid);
967 $staticline = clone $line;
969 $line->oldline = $staticline;
971 $this->line->context = $this->context;
972 $this->line->rang = $rang;
975 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
976 $rangmax = $this->
line_max($fk_parent_line);
977 $this->line->rang = $rangmax + 1;
980 $this->line->id = $rowid;
981 $this->line->label = $label;
982 $this->line->desc = $desc;
983 $this->line->qty = $qty;
984 $this->line->product_type = $type;
985 $this->line->vat_src_code = $vat_src_code;
986 $this->line->tva_tx = $txtva;
987 $this->line->localtax1_tx = $txlocaltax1;
988 $this->line->localtax2_tx = $txlocaltax2;
989 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
990 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
991 $this->line->remise_percent = $remise_percent;
992 $this->line->subprice = $pu_ht;
993 $this->line->info_bits = $info_bits;
995 $this->line->total_ht = $total_ht;
996 $this->line->total_tva = $total_tva;
997 $this->line->total_localtax1 = $total_localtax1;
998 $this->line->total_localtax2 = $total_localtax2;
999 $this->line->total_ttc = $total_ttc;
1000 $this->line->special_code = $special_code;
1001 $this->line->fk_parent_line = $fk_parent_line;
1002 $this->line->skip_update_total = $skip_update_total;
1003 $this->line->fk_unit = $fk_unit;
1005 $this->line->fk_fournprice = $fk_fournprice;
1006 $this->line->pa_ht = $pa_ht;
1008 $this->line->date_start = $date_start;
1009 $this->line->date_end = $date_end;
1011 if (is_array($array_options) && count($array_options) > 0) {
1013 foreach ($array_options as $key => $value) {
1014 $this->line->array_options[$key] = $array_options[$key];
1019 $this->line->multicurrency_subprice = $pu_ht_devise;
1020 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
1021 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
1022 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
1024 $result = $this->line->update($notrigger);
1027 if (!empty($fk_parent_line)) {
1037 $this->db->commit();
1040 $this->error = $this->line->error;
1041 $this->errors = $this->line->errors;
1042 $this->db->rollback();
1046 dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
1063 if ($this->
status == self::STATUS_DRAFT) {
1068 $line->context = $this->context;
1071 $line->fetch($lineid);
1073 if ($id > 0 && $line->fk_propal != $id) {
1074 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
1079 $staticline = clone $line;
1080 $line->oldline = $staticline;
1082 if ($line->delete($user) > 0) {
1085 $this->db->commit();
1088 $this->error = $line->error;
1089 $this->errors = $line->errors;
1090 $this->db->rollback();
1094 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1108 public function create($user, $notrigger = 0)
1110 global $conf, $hookmanager, $mysoc;
1116 if (empty($this->date)) {
1117 $this->date = $this->datep;
1119 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1120 if (empty($this->availability_id)) {
1121 $this->availability_id = 0;
1123 if (empty($this->demand_reason_id)) {
1124 $this->demand_reason_id = 0;
1128 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1133 if (empty($this->fk_multicurrency)) {
1134 $this->multicurrency_code = $conf->currency;
1135 $this->fk_multicurrency = 0;
1136 $this->multicurrency_tx = 1;
1140 $delivery_date = $this->delivery_date;
1147 $this->error =
"Failed to fetch company";
1148 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1153 if (!empty($this->
ref)) {
1156 $this->error =
'ErrorRefAlreadyExists';
1157 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1158 $this->db->rollback();
1163 if (empty($this->date)) {
1164 $this->error =
"Date of proposal is required";
1165 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1173 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
1176 $sql .=
", total_tva";
1177 $sql .=
", total_ttc";
1181 $sql .=
", fk_user_author";
1182 $sql .=
", note_private";
1183 $sql .=
", note_public";
1184 $sql .=
", model_pdf";
1185 $sql .=
", fin_validite";
1186 $sql .=
", fk_cond_reglement";
1187 $sql .=
", deposit_percent";
1188 $sql .=
", fk_mode_reglement";
1189 $sql .=
", fk_account";
1190 $sql .=
", ref_client";
1191 $sql .=
", ref_ext";
1192 $sql .=
", date_livraison";
1193 $sql .=
", fk_shipping_method";
1194 $sql .=
", fk_warehouse";
1195 $sql .=
", fk_availability";
1196 $sql .=
", fk_input_reason";
1197 $sql .=
", fk_projet";
1198 $sql .=
", fk_incoterms";
1199 $sql .=
", location_incoterms";
1201 $sql .=
", fk_multicurrency";
1202 $sql .=
", multicurrency_code";
1203 $sql .=
", multicurrency_tx";
1205 $sql .=
" VALUES (";
1206 $sql .= $this->socid;
1210 $sql .=
", '".$this->db->idate($this->date).
"'";
1211 $sql .=
", '".$this->db->idate($now).
"'";
1212 $sql .=
", '(PROV)'";
1213 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1214 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1215 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1216 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1217 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1218 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1219 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1220 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1221 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1222 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1223 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1224 $sql .=
", ".(!
isDolTms($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1225 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1226 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1227 $sql .=
", ".$this->availability_id;
1228 $sql .=
", ".$this->demand_reason_id;
1229 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1230 $sql .=
", ".(int) $this->fk_incoterms;
1231 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1232 $sql .=
", ".setEntity($this);
1233 $sql .=
", ".(int) $this->fk_multicurrency;
1234 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1235 $sql .=
", ".(float) $this->multicurrency_tx;
1238 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1239 $resql = $this->db->query($sql);
1241 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1244 $this->
ref =
'(PROV'.$this->id.
')';
1245 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1247 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1248 $resql = $this->db->query($sql);
1253 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1254 $this->linked_objects = $this->linkedObjectsIds;
1258 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1259 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1260 if (is_array($tmp_origin_id)) {
1261 foreach ($tmp_origin_id as $origin_id) {
1264 $this->error = $this->db->lasterror();
1269 $origin_id = $tmp_origin_id;
1272 $this->error = $this->db->lasterror();
1284 $fk_parent_line = 0;
1285 $num = count($this->lines);
1287 for ($i = 0; $i < $num; $i++) {
1288 if (!is_object($this->lines[$i])) {
1290 $line = (object) $this->lines[$i];
1292 $line = $this->lines[$i];
1295 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1296 $fk_parent_line = 0;
1299 $vatrate = $line->tva_tx;
1300 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1301 $vatrate .=
' ('.$line->vat_src_code.
')';
1305 $originid = $line->origin_id;
1306 $origintype = $line->origin;
1308 $originid = $line->id;
1309 $origintype = $this->element;
1317 $line->localtax1_tx,
1318 $line->localtax2_tx,
1320 $line->remise_percent,
1324 $line->product_type,
1326 $line->special_code,
1328 $line->fk_fournprice,
1333 $line->array_options,
1344 $this->error = $this->db->error;
1350 $line->id = $result;
1353 if ($result > 0 && $line->product_type == 9) {
1354 $fk_parent_line = $result;
1384 if (!$error && !$notrigger) {
1393 $this->error = $this->db->lasterror();
1398 $this->error = $this->db->lasterror();
1403 $this->db->commit();
1404 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1407 $this->db->rollback();
1411 $this->error = $this->db->lasterror();
1412 $this->db->rollback();
1427 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1429 global $conf, $hookmanager, $mysoc;
1438 $object =
new self($this->db);
1445 $objsoc =
new Societe($this->db);
1448 if (!empty($socid) && $socid !=
$object->socid) {
1449 if ($objsoc->fetch($socid) > 0) {
1451 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1452 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1453 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1454 $object->fk_delivery_address = 0;
1477 $objsoc->fetch(
$object->socid);
1481 if ($update_prices ===
true || $update_desc ===
true) {
1482 if ($objsoc->id > 0 && !empty(
$object->lines)) {
1485 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1488 foreach (
$object->lines as $line) {
1491 if ($line->fk_product > 0) {
1492 $prod =
new Product($this->db);
1493 $res = $prod->fetch($line->fk_product);
1495 if ($update_prices ===
true) {
1496 $pu_ht = $prod->price;
1498 $remise_percent = $objsoc->remise_percent;
1501 $pu_ht = $prod->multiprices[$objsoc->price_level];
1503 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1504 $tva_tx = (string) $prod->multiprices_tva_tx[$objsoc->price_level];
1509 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1510 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1513 if (count($prodcustprice->lines) > 0) {
1514 $pu_ht =
price($prodcustprice->lines[0]->price);
1515 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1516 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1517 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1523 $line->subprice = $pu_ht;
1524 $line->tva_tx = $tva_tx;
1525 $line->remise_percent = $remise_percent;
1527 if ($update_desc ===
true) {
1528 $line->desc = $prod->description;
1538 $object->entity = (!empty($forceentity) ? $forceentity :
$object->entity);
1542 $object->user_creation_id = $user->id;
1543 $object->user_validation_id = 0;
1556 $object->context[
'createfromclone'] =
'createfromclone';
1557 $result =
$object->create($user);
1559 $this->error =
$object->error;
1560 $this->errors = array_merge($this->errors,
$object->errors);
1566 if (
$object->copy_linked_contact($this,
'internal') < 0) {
1573 if ($this->socid ==
$object->socid) {
1574 if (
$object->copy_linked_contact($this,
'external') < 0) {
1582 if (is_object($hookmanager)) {
1583 $parameters = array(
'objFrom' => $this,
'clonedObj' =>
$object);
1585 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters,
$object, $action);
1593 unset(
$object->context[
'createfromclone']);
1597 $this->db->commit();
1600 $this->db->rollback();
1614 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1616 $sql =
"SELECT p.rowid, p.ref, p.entity, p.fk_soc";
1617 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1618 $sql .=
", p.datec";
1619 $sql .=
", p.date_signature as dates";
1620 $sql .=
", p.date_valid as datev";
1621 $sql .=
", p.datep as dp";
1622 $sql .=
", p.fin_validite as dfv";
1623 $sql .=
", p.date_livraison as delivery_date";
1624 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1625 $sql .=
", p.note_private, p.note_public";
1626 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1627 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1628 $sql .=
", p.fk_delivery_address";
1629 $sql .=
", p.fk_availability";
1630 $sql .=
", p.fk_input_reason";
1631 $sql .=
", p.fk_cond_reglement";
1632 $sql .=
", p.fk_mode_reglement";
1633 $sql .=
', p.fk_account';
1634 $sql .=
", p.fk_shipping_method";
1635 $sql .=
", p.fk_warehouse";
1636 $sql .=
", p.fk_incoterms, p.location_incoterms";
1637 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1638 $sql .=
", p.tms as date_modification";
1639 $sql .=
", i.libelle as label_incoterms";
1640 $sql .=
", c.label as statut_label";
1641 $sql .=
", ca.code as availability_code, ca.label as availability";
1642 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1643 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1644 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1645 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1646 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1647 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1648 $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').
')';
1649 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1650 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1651 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1654 if (!empty($forceentity)) {
1655 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1657 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1659 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1662 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1665 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1666 $resql = $this->db->query($sql);
1668 if ($this->db->num_rows($resql)) {
1669 $obj = $this->db->fetch_object($resql);
1671 $this->
id = $obj->rowid;
1672 $this->entity = $obj->entity;
1674 $this->
ref = $obj->ref;
1675 $this->ref_client = $obj->ref_client;
1676 $this->ref_customer = $obj->ref_client;
1677 $this->ref_ext = $obj->ref_ext;
1679 $this->total = $obj->total_ttc;
1680 $this->total_ttc = $obj->total_ttc;
1681 $this->total_ht = $obj->total_ht;
1682 $this->total_tva = $obj->total_tva;
1683 $this->total_localtax1 = $obj->localtax1;
1684 $this->total_localtax2 = $obj->localtax2;
1686 $this->socid = $obj->fk_soc;
1687 $this->thirdparty =
null;
1689 $this->fk_project = $obj->fk_project;
1690 $this->project =
null;
1692 $this->model_pdf = $obj->model_pdf;
1693 $this->last_main_doc = $obj->last_main_doc;
1694 $this->note = $obj->note_private;
1695 $this->note_private = $obj->note_private;
1696 $this->note_public = $obj->note_public;
1698 $this->
status = (int) $obj->fk_statut;
1699 $this->statut = $this->status;
1701 $this->datec = $this->db->jdate($obj->datec);
1702 $this->datev = $this->db->jdate($obj->datev);
1703 $this->date_creation = $this->db->jdate($obj->datec);
1704 $this->date_validation = $this->db->jdate($obj->datev);
1705 $this->date_modification = $this->db->jdate($obj->date_modification);
1706 $this->date_signature = $this->db->jdate($obj->dates);
1707 $this->date = $this->db->jdate($obj->dp);
1708 $this->datep = $this->db->jdate($obj->dp);
1709 $this->fin_validite = $this->db->jdate($obj->dfv);
1710 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1711 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1712 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1713 $this->availability_id = $obj->fk_availability;
1714 $this->availability_code = $obj->availability_code;
1716 $this->demand_reason_id = $obj->fk_input_reason;
1717 $this->demand_reason_code = $obj->demand_reason_code;
1719 $this->fk_address = $obj->fk_delivery_address;
1721 $this->mode_reglement_id = $obj->fk_mode_reglement;
1722 $this->mode_reglement_code = $obj->mode_reglement_code;
1723 $this->mode_reglement = $obj->mode_reglement;
1724 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1725 $this->cond_reglement_id = $obj->fk_cond_reglement;
1726 $this->cond_reglement_code = $obj->cond_reglement_code;
1727 $this->cond_reglement = $obj->cond_reglement;
1728 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1729 $this->deposit_percent = $obj->deposit_percent;
1731 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1733 $this->user_author_id = $obj->fk_user_author;
1734 $this->user_validation_id = $obj->fk_user_valid;
1735 $this->user_closing_id = $obj->fk_user_cloture;
1738 $this->fk_incoterms = $obj->fk_incoterms;
1739 $this->location_incoterms = $obj->location_incoterms;
1740 $this->label_incoterms = $obj->label_incoterms;
1743 $this->fk_multicurrency = $obj->fk_multicurrency;
1744 $this->multicurrency_code = $obj->multicurrency_code;
1745 $this->multicurrency_tx = $obj->multicurrency_tx;
1746 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1747 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1748 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1754 $this->db->free($resql);
1756 $this->lines = array();
1767 $this->error =
"Record Not Found";
1770 $this->error = $this->db->lasterror();
1789 if (isset($this->
ref)) {
1790 $this->
ref = trim($this->
ref);
1792 if (isset($this->ref_client)) {
1793 $this->ref_client = trim($this->ref_client);
1795 if (isset($this->note) || isset($this->note_private)) {
1796 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1798 if (isset($this->note_public)) {
1799 $this->note_public = trim($this->note_public);
1801 if (isset($this->model_pdf)) {
1802 $this->model_pdf = trim($this->model_pdf);
1804 if (isset($this->import_key)) {
1805 $this->import_key = trim($this->import_key);
1807 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1808 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1815 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1816 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1817 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1818 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1819 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1820 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1821 if (!empty($this->fin_validite)) {
1822 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1824 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1825 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1826 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1827 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1828 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1829 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1830 $sql .=
" fk_statut=".(isset($this->
status) ? $this->
status :
"null").
",";
1831 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1832 $sql .=
" fk_user_valid=".(isset($this->user_validation_id) ? $this->user_validation_id :
"null").
",";
1833 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1834 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1835 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1836 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1837 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1838 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1839 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1840 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1841 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1842 $sql .=
" WHERE rowid=".((int) $this->
id);
1846 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1847 $resql = $this->db->query($sql);
1850 $this->errors[] =
"Error ".$this->db->lasterror();
1860 if (!$error && !$notrigger) {
1871 foreach ($this->errors as $errmsg) {
1872 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1873 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1875 $this->db->rollback();
1878 $this->db->commit();
1893 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $sqlforgedfilters =
'')
1896 $this->lines = array();
1898 $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,';
1899 $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,';
1900 $sql .=
' d.fk_unit,';
1901 $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,';
1902 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1903 $sql .=
' d.date_start, d.date_end,';
1904 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1905 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1906 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1907 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1908 if ($only_product) {
1909 $sql .=
' AND p.fk_product_type = 0';
1911 if ($sqlforgedfilters) {
1912 $sql .= $sqlforgedfilters;
1914 $sql .=
' ORDER by d.rang';
1916 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1917 $result = $this->db->query($sql);
1919 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1921 $num = $this->db->num_rows($result);
1925 $objp = $this->db->fetch_object($result);
1929 $line->rowid = $objp->rowid;
1930 $line->id = $objp->rowid;
1931 $line->fk_propal = $objp->fk_propal;
1932 $line->fk_parent_line = $objp->fk_parent_line;
1933 $line->product_type = $objp->product_type;
1934 $line->label = $objp->custom_label;
1935 $line->desc = $objp->description;
1936 $line->description = $objp->description;
1937 $line->qty = $objp->qty;
1938 $line->vat_src_code = $objp->vat_src_code;
1939 $line->tva_tx = $objp->tva_tx;
1940 $line->localtax1_tx = $objp->localtax1_tx;
1941 $line->localtax2_tx = $objp->localtax2_tx;
1942 $line->localtax1_type = $objp->localtax1_type;
1943 $line->localtax2_type = $objp->localtax2_type;
1944 $line->subprice = $objp->subprice;
1945 $line->fk_remise_except = $objp->fk_remise_except;
1946 $line->remise_percent = $objp->remise_percent;
1947 $line->price = $objp->price;
1949 $line->info_bits = $objp->info_bits;
1950 $line->total_ht = $objp->total_ht;
1951 $line->total_tva = $objp->total_tva;
1952 $line->total_localtax1 = $objp->total_localtax1;
1953 $line->total_localtax2 = $objp->total_localtax2;
1954 $line->total_ttc = $objp->total_ttc;
1955 $line->fk_fournprice = $objp->fk_fournprice;
1956 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1957 $line->pa_ht = $marginInfos[0];
1958 $line->marge_tx = $marginInfos[1];
1959 $line->marque_tx = $marginInfos[2];
1960 $line->special_code = $objp->special_code;
1961 $line->rang = $objp->rang;
1963 $line->fk_product = $objp->fk_product;
1965 $line->ref = $objp->product_ref;
1966 $line->libelle = $objp->product_label;
1968 $line->product_ref = $objp->product_ref;
1969 $line->product_label = $objp->product_label;
1970 $line->product_desc = $objp->product_desc;
1971 $line->product_tobatch = $objp->product_tobatch;
1972 $line->product_barcode = $objp->product_barcode;
1974 $line->fk_product_type = $objp->fk_product_type;
1975 $line->fk_unit = $objp->fk_unit;
1976 $line->weight = $objp->weight;
1977 $line->weight_units = $objp->weight_units;
1978 $line->volume = $objp->volume;
1979 $line->volume_units = $objp->volume_units;
1981 $line->date_start = $this->db->jdate($objp->date_start);
1982 $line->date_end = $this->db->jdate($objp->date_end);
1985 $line->fk_multicurrency = $objp->fk_multicurrency;
1986 $line->multicurrency_code = $objp->multicurrency_code;
1987 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1988 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1989 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1990 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1992 $line->fetch_optionals();
1995 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1996 $tmpproduct =
new Product($this->db);
1997 $tmpproduct->fetch($objp->fk_product);
1998 $tmpproduct->getMultiLangs();
2000 $line->multilangs = $tmpproduct->multilangs;
2003 $this->lines[$i] = $line;
2008 $this->db->free($result);
2012 $this->error = $this->db->lasterror();
2024 public function valid($user, $notrigger = 0)
2028 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2033 if ($this->
status == self::STATUS_VALIDATED) {
2034 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
2038 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'creer'))
2039 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'propal_advance',
'validate')))) {
2040 $this->error =
'ErrorPermissionDenied';
2041 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
2050 $soc =
new Societe($this->db);
2051 $soc->fetch($this->socid);
2054 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2061 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2062 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2063 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2066 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2067 $resql = $this->db->query($sql);
2074 if (!$error && !$notrigger) {
2076 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2084 $this->oldref = $this->ref;
2087 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2089 $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).
"'";
2090 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2091 $resql = $this->db->query($sql);
2094 $this->error = $this->db->lasterror();
2096 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2097 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2098 $resql = $this->db->query($sql);
2101 $this->error = $this->db->lasterror();
2107 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2108 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2109 if (!$error && file_exists($dirsource)) {
2110 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2111 if (@rename($dirsource, $dirdest)) {
2114 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2115 foreach ($listoffiles as $fileentry) {
2116 $dirsource = $fileentry[
'name'];
2117 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2118 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2119 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2120 @rename($dirsource, $dirdest);
2129 $this->user_validation_id = $user->id;
2130 $this->datev = $now;
2131 $this->date_validation = $now;
2133 $this->db->commit();
2136 $this->db->rollback();
2155 $this->error =
'ErrorBadParameter';
2156 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2160 if ($user->hasRight(
'propal',
'creer')) {
2165 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2166 $sql .=
" WHERE rowid = ".((int) $this->
id);
2169 $resql = $this->db->query($sql);
2171 $this->errors[] = $this->db->error();
2176 $this->oldcopy = clone $this;
2177 $this->date = $date;
2178 $this->datep = $date;
2181 if (!$notrigger && empty($error)) {
2191 $this->db->commit();
2194 foreach ($this->errors as $errmsg) {
2195 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2196 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2198 $this->db->rollback();
2218 if ($user->hasRight(
'propal',
'creer')) {
2223 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2224 $sql .=
" WHERE rowid = ".((int) $this->
id);
2228 $resql = $this->db->query($sql);
2230 $this->errors[] = $this->db->error();
2236 $this->oldcopy = clone $this;
2237 $this->fin_validite = $date_end_validity;
2240 if (!$notrigger && empty($error)) {
2250 $this->db->commit();
2253 foreach ($this->errors as $errmsg) {
2254 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2255 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2257 $this->db->rollback();
2291 if ($user->hasRight(
'propal',
'creer')) {
2296 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2297 $sql .=
" SET date_livraison = ".(isDolTms($delivery_date) ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2298 $sql .=
" WHERE rowid = ".((int) $this->
id);
2301 $resql = $this->db->query($sql);
2303 $this->errors[] = $this->db->error();
2308 $this->oldcopy = clone $this;
2309 $this->delivery_date = $delivery_date;
2312 if (!$notrigger && empty($error)) {
2322 $this->db->commit();
2325 foreach ($this->errors as $errmsg) {
2326 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2327 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2329 $this->db->rollback();
2349 if ($user->hasRight(
'propal',
'creer') && $this->status >= self::STATUS_DRAFT) {
2354 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2355 $sql .=
" SET fk_availability = ".((int) $id);
2356 $sql .=
" WHERE rowid = ".((int) $this->
id);
2358 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2359 $resql = $this->db->query($sql);
2361 $this->errors[] = $this->db->error();
2366 $this->oldcopy = clone $this;
2367 $this->fk_availability = $id;
2368 $this->availability_id = $id;
2371 if (!$notrigger && empty($error)) {
2381 $this->db->commit();
2384 foreach ($this->errors as $errmsg) {
2385 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2386 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2388 $this->db->rollback();
2392 $error_str =
'Propal status do not meet requirement '.$this->status;
2394 $this->error = $error_str;
2395 $this->errors[] = $this->error;
2412 if ($user->hasRight(
'propal',
'creer') && $this->status >= self::STATUS_DRAFT) {
2417 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2418 $sql .=
" SET fk_input_reason = ".((int) $id);
2419 $sql .=
" WHERE rowid = ".((int) $this->
id);
2422 $resql = $this->db->query($sql);
2424 $this->errors[] = $this->db->error();
2430 $this->oldcopy = clone $this;
2432 $this->demand_reason_id = $id;
2436 if (!$notrigger && empty($error)) {
2446 $this->db->commit();
2449 foreach ($this->errors as $errmsg) {
2450 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2451 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2453 $this->db->rollback();
2457 $error_str =
'Propal status do not meet requirement '.$this->status;
2459 $this->error = $error_str;
2460 $this->errors[] = $this->error;
2477 if ($user->hasRight(
'propal',
'creer')) {
2482 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2483 $sql .=
" WHERE rowid = ".((int) $this->
id);
2485 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2486 $resql = $this->db->query($sql);
2488 $this->errors[] = $this->db->error();
2493 $this->oldcopy = clone $this;
2494 $this->ref_client = $ref_client;
2497 if (!$notrigger && empty($error)) {
2507 $this->db->commit();
2510 foreach ($this->errors as $errmsg) {
2511 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2512 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2514 $this->db->rollback();
2532 public function reopen($user, $status, $note =
'', $notrigger = 0)
2536 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2537 $sql .=
" SET fk_statut = ".((int) $status).
",";
2538 if (!empty($note)) {
2539 $sql .=
" note_private = '".$this->db->escape($note).
"',";
2541 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2542 $sql .=
" WHERE rowid = ".((int) $this->
id);
2546 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2547 $resql = $this->db->query($sql);
2550 $this->errors[] =
"Error ".$this->db->lasterror();
2565 if (!empty($this->errors)) {
2566 foreach ($this->errors as $errmsg) {
2567 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2568 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2571 $this->db->rollback();
2574 $this->statut = $status;
2577 $this->db->commit();
2592 public function closeProposal($user, $status, $note_private =
'', $notrigger = 0, $note_public =
'')
2594 global $langs,$conf;
2601 $newprivatenote =
dol_concatdesc($this->note_private, $note_private);
2602 $newpublicnote =
dol_concatdesc($this->note_public, $note_public);
2605 $date_signature = $now;
2606 $fk_user_signature = $user->id;
2608 $this->
info($this->
id);
2609 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2610 $date_signature = $now;
2611 $fk_user_signature = $user->id;
2613 $date_signature = $this->date_signature;
2614 $fk_user_signature = $this->user_signature->id;
2618 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2619 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"', note_public = '".$this->db->escape($newpublicnote).
"'";
2620 if ($status == self::STATUS_SIGNED) {
2621 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2623 $sql .=
" WHERE rowid = ".((int) $this->
id);
2625 $resql = $this->db->query($sql);
2629 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2631 if ($status == self::STATUS_SIGNED) {
2632 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2633 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_TOBILL') ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2636 $soc =
new Societe($this->db);
2637 $soc->id = $this->socid;
2638 $result = $soc->setAsCustomer();
2641 $this->error = $this->db->lasterror();
2642 $this->db->rollback();
2649 $outputlangs = $langs;
2651 $outputlangs =
new Translate(
"", $conf);
2652 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2653 $outputlangs->setDefaultLang($newlang);
2662 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2666 $this->oldcopy = clone $this;
2667 $this->statut = $status;
2669 $this->date_signature = $date_signature;
2670 $this->note_private = $newprivatenote;
2673 if (!$notrigger && empty($error)) {
2683 $this->db->commit();
2686 $this->statut = $this->oldcopy->status;
2687 $this->
status = $this->oldcopy->status;
2688 $this->date_signature = $this->oldcopy->date_signature;
2689 $this->note_private = $this->oldcopy->note_private;
2691 $this->db->rollback();
2695 $this->error = $this->db->lasterror();
2696 $this->db->rollback();
2711 global $conf, $langs;
2718 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2724 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2725 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2726 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2729 $resql = $this->db->query($sql);
2731 $this->errors[] = $this->db->error();
2734 $num = $this->db->affected_rows($resql);
2742 $outputlangs = $langs;
2744 $outputlangs =
new Translate(
"", $conf);
2745 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2746 $outputlangs->setDefaultLang($newlang);
2755 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2758 $this->oldcopy = clone $this;
2761 $this->date_cloture = $now;
2762 $this->note_private = $newprivatenote;
2765 if (!$notrigger && empty($error)) {
2775 $this->db->commit();
2778 foreach ($this->errors as $errmsg) {
2779 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2780 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2782 $this->db->rollback();
2799 $sql =
"UPDATE ". MAIN_DB_PREFIX .
"propal";
2800 $sql .=
" SET fk_statut = " . self::STATUS_CANCELED .
",";
2801 $sql .=
" fk_user_modif = " . ((int) $user->id);
2802 $sql .=
" WHERE rowid = " . ((int) $this->
id);
2804 dol_syslog(get_class($this).
"::cancel", LOG_DEBUG);
2805 if ($this->db->query($sql)) {
2818 $this->db->commit();
2821 foreach ($this->errors as $errmsg) {
2822 dol_syslog(get_class($this).
"::cancel ".$errmsg, LOG_ERR);
2823 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2825 $this->db->rollback();
2829 $this->error = $this->db->error();
2830 $this->db->rollback();
2849 if ($this->
status <= self::STATUS_DRAFT) {
2853 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2857 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2858 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2859 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2860 $sql .=
" WHERE rowid = ".((int) $this->
id);
2862 $resql = $this->db->query($sql);
2864 $this->errors[] = $this->db->error();
2869 $this->oldcopy = clone $this;
2872 if (!$notrigger && empty($error)) {
2885 $this->db->commit();
2888 foreach ($this->errors as $errmsg) {
2889 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2890 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2892 $this->db->rollback();
2912 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2919 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2920 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2921 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2922 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2923 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2924 $sql .=
" AND p.fk_soc = s.rowid";
2925 $sql .=
" AND p.fk_statut = c.id";
2929 if (!$user->hasRight(
'societe',
'client',
'voir')) {
2930 $search_sale = $user->id;
2933 if ($search_sale && $search_sale !=
'-1') {
2934 if ($search_sale == -2) {
2935 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
2936 } elseif ($search_sale > 0) {
2937 $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).
")";
2942 $sql .=
" AND p.fk_soc = ".((int) $socid);
2945 $sql .=
" AND p.fk_statut = ".((int) self::STATUS_DRAFT);
2947 if ($notcurrentuser > 0) {
2948 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2950 $sql .= $this->db->order($sortfield, $sortorder);
2951 $sql .= $this->db->plimit($limit, $offset);
2953 $result = $this->db->query($sql);
2955 $num = $this->db->num_rows($result);
2959 $obj = $this->db->fetch_object($result);
2961 if ($shortlist == 1) {
2962 $ga[$obj->propalid] = $obj->ref;
2963 } elseif ($shortlist == 2) {
2964 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2966 $ga[$i][
'id'] = $obj->propalid;
2967 $ga[$i][
'ref'] = $obj->ref;
2968 $ga[$i][
'name'] = $obj->name;
3002 $linkedInvoices = array();
3005 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
3008 foreach ($objectid as $key =>
$object) {
3010 if ($objecttype ==
'facture') {
3015 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
3016 foreach ($subobjectid as $subkey => $subobject) {
3017 if ($subobjecttype ==
'facture') {
3018 $linkedInvoices[] = $subobject;
3026 if (count($linkedInvoices) > 0) {
3027 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
3028 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
3029 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
3031 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
3032 $resql = $this->db->query($sql);
3035 $tab_sqlobj = array();
3036 $nump = $this->db->num_rows($resql);
3037 for ($i = 0; $i < $nump; $i++) {
3038 $sqlobj = $this->db->fetch_object($resql);
3039 $tab_sqlobj[] = $sqlobj;
3041 $this->db->free($resql);
3043 $nump = count($tab_sqlobj);
3047 while ($i < $nump) {
3048 $obj = array_shift($tab_sqlobj);
3071 public function delete($user, $notrigger = 0)
3074 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3090 if (!$error && !empty($this->table_element_line)) {
3091 $tabletodelete = $this->table_element_line;
3092 $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).
")";
3093 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3094 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3096 $this->error = $this->db->lasterror();
3097 $this->errors[] = $this->error;
3098 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3123 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3129 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3130 $res = $this->db->query($sql);
3133 $this->error = $this->db->lasterror();
3134 $this->errors[] = $this->error;
3135 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3151 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3152 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3153 $file = $dir.
"/".$ref.
".pdf";
3154 if (file_exists($file)) {
3158 $this->error =
'ErrorFailToDeleteFile';
3159 $this->errors[] = $this->error;
3160 $this->db->rollback();
3164 if (file_exists($dir)) {
3167 $this->error =
'ErrorFailToDeleteDir';
3168 $this->errors[] = $this->error;
3169 $this->db->rollback();
3177 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3178 $this->db->commit();
3181 $this->db->rollback();
3198 if ($this->
status >= self::STATUS_DRAFT) {
3203 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3204 $sql .=
' SET fk_availability = '.((int) $availability_id);
3205 $sql .=
' WHERE rowid='.((int) $this->
id);
3207 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3208 $resql = $this->db->query($sql);
3210 $this->errors[] = $this->db->error();
3215 $this->oldcopy = clone $this;
3216 $this->availability_id = $availability_id;
3219 if (!$notrigger && empty($error)) {
3229 $this->db->commit();
3232 foreach ($this->errors as $errmsg) {
3233 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3234 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3236 $this->db->rollback();
3240 $error_str =
'Propal status do not meet requirement '.$this->status;
3242 $this->error = $error_str;
3243 $this->errors[] = $this->error;
3262 if ($this->
status >= self::STATUS_DRAFT) {
3267 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3268 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3269 $sql .=
' WHERE rowid='.((int) $this->
id);
3271 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3272 $resql = $this->db->query($sql);
3274 $this->errors[] = $this->db->error();
3279 $this->oldcopy = clone $this;
3280 $this->demand_reason_id = $demand_reason_id;
3283 if (!$notrigger && empty($error)) {
3293 $this->db->commit();
3296 foreach ($this->errors as $errmsg) {
3297 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3298 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3300 $this->db->rollback();
3304 $error_str =
'Propal status do not meet requirement '.$this->status;
3306 $this->error = $error_str;
3307 $this->errors[] = $this->error;
3321 $sql =
"SELECT c.rowid, ";
3322 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3323 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3324 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3325 $sql .=
" WHERE c.rowid = ".((int) $id);
3327 $result = $this->db->query($sql);
3330 if ($this->db->num_rows($result)) {
3331 $obj = $this->db->fetch_object($result);
3333 $this->
id = $obj->rowid;
3335 $this->date_creation = $this->db->jdate($obj->datec);
3336 $this->date_validation = $this->db->jdate($obj->datev);
3337 $this->date_signature = $this->db->jdate($obj->date_signature);
3338 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3340 $this->user_creation_id = $obj->fk_user_author;
3341 $this->user_validation_id = $obj->fk_user_valid;
3343 if ($obj->fk_user_signature) {
3344 $user_signature =
new User($this->db);
3345 $user_signature->fetch($obj->fk_user_signature);
3346 $this->user_signature = $user_signature;
3349 $this->user_closing_id = $obj->fk_user_cloture;
3351 $this->db->free($result);
3380 global $hookmanager;
3383 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3385 $langs->load(
"propal");
3386 $this->labelStatus[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceled");
3387 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3388 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3389 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3390 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3391 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3392 $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceledShort");
3393 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3394 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3395 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3396 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3397 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3401 if ($status == self::STATUS_CANCELED) {
3402 $statusType =
'status9';
3403 } elseif ($status == self::STATUS_DRAFT) {
3404 $statusType =
'status0';
3405 } elseif ($status == self::STATUS_VALIDATED) {
3406 $statusType =
'status1';
3407 } elseif ($status == self::STATUS_SIGNED) {
3408 $statusType =
'status4';
3409 } elseif ($status == self::STATUS_NOTSIGNED) {
3410 $statusType =
'status9';
3411 } elseif ($status == self::STATUS_BILLED) {
3412 $statusType =
'status6';
3415 $parameters = array(
'status' => $status,
'mode' => $mode);
3416 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3419 return $hookmanager->resPrint;
3422 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3437 global $conf, $langs;
3441 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3442 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3443 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3444 if ($mode ==
'opened') {
3445 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3447 if ($mode ==
'signed') {
3448 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3452 if (!$user->hasRight(
'societe',
'client',
'voir')) {
3453 $search_sale = $user->id;
3456 if ($search_sale && $search_sale !=
'-1') {
3457 if ($search_sale == -2) {
3458 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3459 } elseif ($search_sale > 0) {
3460 $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).
")";
3464 $resql = $this->db->query($sql);
3466 $langs->load(
"propal");
3471 $label = $labelShort =
'';
3472 if ($mode ==
'opened') {
3473 $delay_warning = $conf->propal->cloture->warning_delay;
3475 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3476 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3478 if ($mode ==
'signed') {
3479 $delay_warning = $conf->propal->facturation->warning_delay;
3481 $label = $langs->trans(
"PropalsToBill");
3482 $labelShort = $langs->trans(
"ToBill");
3486 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3487 $response->label = $label;
3488 $response->labelShort = $labelShort;
3489 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3490 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3494 while ($obj = $this->db->fetch_object($resql)) {
3495 $response->nbtodo++;
3496 $response->total += $obj->total_ht;
3498 if ($mode ==
'opened') {
3499 $datelimit = $this->db->jdate($obj->datefin);
3500 if ($datelimit < ($now - $delay_warning)) {
3501 $response->nbtodolate++;
3510 $this->error = $this->db->error();
3525 global $conf, $langs;
3530 $sql =
"SELECT rowid";
3531 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3532 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3533 $sql .= $this->db->plimit(100);
3535 $resql = $this->db->query($sql);
3537 $num_prods = $this->db->num_rows($resql);
3539 while ($i < $num_prods) {
3541 $row = $this->db->fetch_row($resql);
3542 $prodids[$i] = $row[0];
3548 $this->
ref =
'SPECIMEN';
3549 $this->ref_client =
'NEMICEPS';
3550 $this->specimen = 1;
3552 $this->date = time();
3553 $this->fin_validite = $this->date + 3600 * 24 * 30;
3554 $this->cond_reglement_id = 1;
3555 $this->cond_reglement_code =
'RECEP';
3556 $this->mode_reglement_id = 7;
3557 $this->mode_reglement_code =
'CHQ';
3558 $this->availability_id = 1;
3559 $this->availability_code =
'AV_NOW';
3560 $this->demand_reason_id = 1;
3561 $this->demand_reason_code =
'SRC_00';
3562 $this->note_public =
'This is a comment (public)';
3563 $this->note_private =
'This is a comment (private)';
3565 $this->multicurrency_tx = 1;
3566 $this->multicurrency_code = $conf->currency;
3571 while ($xnbp < $nbp) {
3573 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3575 $line->subprice = 100;
3578 $line->localtax1_tx = 0;
3579 $line->localtax2_tx = 0;
3581 $line->total_ht = 50;
3582 $line->total_ttc = 60;
3583 $line->total_tva = 10;
3584 $line->remise_percent = 50;
3586 $line->total_ht = 100;
3587 $line->total_ttc = 120;
3588 $line->total_tva = 20;
3589 $line->remise_percent = 00;
3592 if ($num_prods > 0) {
3593 $prodid = mt_rand(1, $num_prods);
3594 $line->fk_product = $prodids[$prodid];
3595 $line->product_ref =
'SPECIMEN';
3598 $this->lines[$xnbp] = $line;
3600 $this->total_ht += $line->total_ht;
3601 $this->total_tva += $line->total_tva;
3602 $this->total_ttc += $line->total_ttc;
3619 $this->nb = array();
3622 $sql =
"SELECT count(p.rowid) as nb";
3623 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3624 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3625 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3629 if (!$user->hasRight(
'societe',
'client',
'voir')) {
3630 $search_sale = $user->id;
3633 if ($search_sale && $search_sale !=
'-1') {
3634 if ($search_sale == -2) {
3635 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3636 } elseif ($search_sale > 0) {
3637 $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).
")";
3641 $resql = $this->db->query($sql);
3644 while ($obj = $this->db->fetch_object($resql)) {
3645 $this->nb[
"proposals"] = $obj->nb;
3647 $this->db->free($resql);
3651 $this->error = $this->db->error();
3666 global $conf, $langs;
3667 $langs->load(
"propal");
3671 if (!empty($classname)) {
3674 $file = $classname.
".php";
3677 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3678 foreach ($dirmodels as $reldir) {
3682 $mybool = ((bool) @include_once $dir.$file) || $mybool;
3690 $obj =
new $classname();
3691 '@phan-var-force ModeleNumRefPropales $obj';
3693 $numref = $obj->getNextValue($soc, $this);
3695 if ($numref !=
"") {
3698 $this->error = $obj->error;
3703 $langs->load(
"errors");
3704 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3717 global $conf, $langs, $user;
3719 $langs->load(
'propal');
3721 $nofetch = !empty($params[
'nofetch']);
3724 return [
'optimize' => $langs->trans(
"Proposal")];
3726 if ($user->hasRight(
'propal',
'lire')) {
3727 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3728 if (isset($this->
status)) {
3729 $datas[
'status'] =
' '.$this->getLibStatut(5);
3731 if (!empty($this->
ref)) {
3732 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3735 $langs->load(
'companies');
3736 if (empty($this->thirdparty)) {
3739 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3741 if (!empty($this->ref_customer)) {
3742 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
3745 $langs->load(
'project');
3746 if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) {
3748 if ($res > 0 && $this->project instanceof
Project) {
3749 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3753 if (!empty($this->total_ht)) {
3754 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3756 if (!empty($this->total_tva)) {
3757 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3759 if (!empty($this->total_ttc)) {
3760 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3762 if (!empty($this->date)) {
3763 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3765 if (!empty($this->delivery_date)) {
3766 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3784 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3786 global $langs, $conf, $user, $hookmanager;
3788 if (!empty($conf->dol_no_mouse_hover)) {
3795 'objecttype' => $this->element,
3796 'option' => $option,
3799 $classfortooltip =
'classfortooltip';
3802 $classfortooltip =
'classforajaxtooltip';
3803 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3810 if ($user->hasRight(
'propal',
'lire')) {
3811 if ($option ==
'') {
3812 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3813 } elseif ($option ==
'compta') {
3814 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3815 } elseif ($option ==
'expedition') {
3816 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3817 } elseif ($option ==
'document') {
3818 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3821 if ($option !=
'nolink') {
3823 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3824 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3825 $add_save_lastsearch_values = 1;
3827 if ($add_save_lastsearch_values) {
3828 $url .=
'&save_lastsearch_values=1';
3834 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3836 $label = $langs->trans(
"Proposal");
3837 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3839 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3840 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3843 $linkstart =
'<a href="'.$url.
'"';
3844 $linkstart .= $linkclose.
'>';
3847 $result .= $linkstart;
3849 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3851 if ($withpicto != 2) {
3852 $result .= $this->ref;
3854 $result .= $linkend;
3856 if ($addlinktonotes >= 0) {
3859 if ($addlinktonotes == 0) {
3860 if (!empty($this->note_private) || !empty($this->note_public)) {
3861 $txttoshow = $langs->trans(
'ViewPrivateNote');
3863 } elseif ($addlinktonotes == 1) {
3864 if (!empty($this->note_private)) {
3867 } elseif ($addlinktonotes == 2) {
3868 if (!empty($this->note_public)) {
3871 } elseif ($addlinktonotes == 3) {
3872 if ($user->socid > 0) {
3873 if (!empty($this->note_public)) {
3877 if (!empty($this->note_public)) {
3880 if (!empty($this->note_private)) {
3881 if (!empty($txttoshow)) {
3882 $txttoshow .=
'<br><br>';
3890 $result .=
' <span class="note inline-block">';
3891 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3894 $result .=
'</span>';
3899 $hookmanager->initHooks(array($this->element .
'dao'));
3900 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
3901 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3903 $result = $hookmanager->resPrint;
3905 $result .= $hookmanager->resPrint;
3918 return $this->
fetch_lines(0, 0, $sqlforgedfilters);
3932 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3934 global $conf, $langs;
3936 $langs->load(
"propale");
3937 $outputlangs->load(
"products");
3942 if ($this->model_pdf) {
3943 $modele = $this->model_pdf;
3949 $modelpath =
"core/modules/propale/doc/";
3951 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3999 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
4001 $return =
'<div class="box-flex-item box-flex-grow-zero">';
4002 $return .=
'<div class="info-box info-box-sm">';
4003 $return .=
'<div class="info-box-icon bg-infobox-action">';
4005 $return .=
'</div>';
4006 $return .=
'<div class="info-box-content">';
4007 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
4008 if ($selected >= 0) {
4009 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
4011 if (!empty($arraydata[
'projectlink'])) {
4012 $return .=
'<span class="info-box-ref"> | '.$arraydata[
'projectlink'].
'</span>';
4015 if (property_exists($this,
'thirdparty') && is_object($this->thirdparty)) {
4016 $return .=
'<div class="info-box-ref tdoverflowmax150">'.$this->thirdparty->getNomUrl(1).
'</div>';
4018 if (property_exists($this,
'total_ht')) {
4019 $return .=
'<span class="info-box-label amount" title="'.$langs->trans(
"AmountHT").
'">'.
price($this->total_ht).
'</span>';
4021 if (!empty($arraydata[
'authorlink'])) {
4022 $return .=
' <span class="info-box-label">'.$arraydata[
'authorlink'].
'</span>';
4024 if (method_exists($this,
'getLibStatut')) {
4025 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
4027 $return .=
'</div>';
4028 $return .=
'</div>';
4029 $return .=
'</div>';
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
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.
fetchProject()
Load the project with id $this->fk_project into this->project.
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)
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.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
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.