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;
157 public $date_validation;
162 public $date_signature;
167 public $user_signature;
184 public $delivery_date;
190 public $fin_validite;
195 public $user_author_id;
225 public $cond_reglement_code;
230 public $cond_reglement;
235 public $cond_reglement_doc;
240 public $mode_reglement_code;
245 public $mode_reglement;
252 public $deposit_percent;
264 public $address_type;
275 public $availability_id;
282 public $fk_availability;
287 public $availability_code;
292 public $availability;
297 public $duree_validite;
302 public $demand_reason_id;
307 public $demand_reason_code;
312 public $demand_reason;
317 public $warehouse_id;
322 public $lines = array();
329 public $labelStatus = array();
330 public $labelStatusShort = array();
361 public $fields = array(
362 'rowid' => array(
'type' =>
'integer',
'label' =>
'TechnicalID',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 10),
363 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'default' =>
'1',
'enabled' => 1,
'visible' => -2,
'notnull' => 1,
'position' => 15,
'index' => 1),
364 'ref' => array(
'type' =>
'varchar(30)',
'label' =>
'Ref',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'showoncombobox' => 1,
'position' => 20),
365 'ref_client' => array(
'type' =>
'varchar(255)',
'label' =>
'RefCustomer',
'enabled' => 1,
'visible' => -1,
'position' => 22),
366 'ref_ext' => array(
'type' =>
'varchar(255)',
'label' =>
'RefExt',
'enabled' => 1,
'visible' => 0,
'position' => 40),
367 'fk_soc' => array(
'type' =>
'integer:Societe:societe/class/societe.class.php',
'label' =>
'ThirdParty',
'enabled' =>
'isModEnabled("societe")',
'visible' => -1,
'position' => 23),
368 '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),
369 'tms' => array(
'type' =>
'timestamp',
'label' =>
'DateModification',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 25),
370 'datec' => array(
'type' =>
'datetime',
'label' =>
'DateCreation',
'enabled' => 1,
'visible' => -1,
'position' => 55),
371 'datep' => array(
'type' =>
'date',
'label' =>
'Date',
'enabled' => 1,
'visible' => -1,
'position' => 60),
372 'fin_validite' => array(
'type' =>
'datetime',
'label' =>
'DateEnd',
'enabled' => 1,
'visible' => -1,
'position' => 65),
373 'date_valid' => array(
'type' =>
'datetime',
'label' =>
'DateValidation',
'enabled' => 1,
'visible' => -1,
'position' => 70),
374 'date_cloture' => array(
'type' =>
'datetime',
'label' =>
'DateClosing',
'enabled' => 1,
'visible' => -1,
'position' => 75),
375 'fk_user_author' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user author',
'enabled' => 1,
'visible' => -1,
'position' => 80),
376 'fk_user_modif' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserModif',
'enabled' => 1,
'visible' => -2,
'notnull' => -1,
'position' => 85),
377 'fk_user_valid' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserValidation',
'enabled' => 1,
'visible' => -1,
'position' => 90),
378 'fk_user_cloture' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user cloture',
'enabled' => 1,
'visible' => -1,
'position' => 95),
379 'price' => array(
'type' =>
'double',
'label' =>
'Price',
'enabled' => 1,
'visible' => -1,
'position' => 105),
380 'total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalHT',
'enabled' => 1,
'visible' => -1,
'position' => 125,
'isameasure' => 1),
381 'total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'VAT',
'enabled' => 1,
'visible' => -1,
'position' => 130,
'isameasure' => 1),
382 'localtax1' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax1',
'enabled' => 1,
'visible' => -1,
'position' => 135,
'isameasure' => 1),
383 'localtax2' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax2',
'enabled' => 1,
'visible' => -1,
'position' => 140,
'isameasure' => 1),
384 'total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalTTC',
'enabled' => 1,
'visible' => -1,
'position' => 145,
'isameasure' => 1),
385 'fk_account' => array(
'type' =>
'integer',
'label' =>
'BankAccount',
'enabled' =>
'isModEnabled("bank")',
'visible' => -1,
'position' => 150),
386 'fk_currency' => array(
'type' =>
'varchar(3)',
'label' =>
'Currency',
'enabled' => 1,
'visible' => -1,
'position' => 155),
387 'fk_cond_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentTerm',
'enabled' => 1,
'visible' => -1,
'position' => 160),
388 'deposit_percent' => array(
'type' =>
'varchar(63)',
'label' =>
'DepositPercent',
'enabled' => 1,
'visible' => -1,
'position' => 161),
389 'fk_mode_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentMode',
'enabled' => 1,
'visible' => -1,
'position' => 165),
390 'note_private' => array(
'type' =>
'html',
'label' =>
'NotePrivate',
'enabled' => 1,
'visible' => 0,
'position' => 170),
391 'note_public' => array(
'type' =>
'html',
'label' =>
'NotePublic',
'enabled' => 1,
'visible' => 0,
'position' => 175),
392 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'PDFTemplate',
'enabled' => 1,
'visible' => 0,
'position' => 180),
393 'date_livraison' => array(
'type' =>
'date',
'label' =>
'DateDeliveryPlanned',
'enabled' => 1,
'visible' => -1,
'position' => 185),
394 'fk_shipping_method' => array(
'type' =>
'integer',
'label' =>
'ShippingMethod',
'enabled' => 1,
'visible' => -1,
'position' => 190),
395 'fk_warehouse' => array(
'type' =>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label' =>
'Fk warehouse',
'enabled' =>
'isModEnabled("stock")',
'visible' => -1,
'position' => 191),
396 'fk_availability' => array(
'type' =>
'integer',
'label' =>
'Availability',
'enabled' => 1,
'visible' => -1,
'position' => 195),
397 'fk_delivery_address' => array(
'type' =>
'integer',
'label' =>
'DeliveryAddress',
'enabled' => 1,
'visible' => 0,
'position' => 200),
398 'fk_input_reason' => array(
'type' =>
'integer',
'label' =>
'InputReason',
'enabled' => 1,
'visible' => -1,
'position' => 205),
399 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => -1,
'position' => 215),
400 'fk_incoterms' => array(
'type' =>
'integer',
'label' =>
'IncotermCode',
'enabled' =>
'isModEnabled("incoterm")',
'visible' => -1,
'position' => 220),
401 'location_incoterms' => array(
'type' =>
'varchar(255)',
'label' =>
'IncotermLabel',
'enabled' =>
'isModEnabled("incoterm")',
'visible' => -1,
'position' => 225),
402 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'MulticurrencyID',
'enabled' => 1,
'visible' => -1,
'position' => 230),
403 'multicurrency_code' => array(
'type' =>
'varchar(255)',
'label' =>
'MulticurrencyCurrency',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 235),
404 'multicurrency_tx' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyRate',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 240,
'isameasure' => 1),
405 'multicurrency_total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountHT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 245,
'isameasure' => 1),
406 'multicurrency_total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountVAT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 250,
'isameasure' => 1),
407 'multicurrency_total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountTTC',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 255,
'isameasure' => 1),
408 'last_main_doc' => array(
'type' =>
'varchar(255)',
'label' =>
'LastMainDoc',
'enabled' => 1,
'visible' => -1,
'position' => 260),
409 'fk_statut' => array(
'type' =>
'smallint(6)',
'label' =>
'Status',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 500),
410 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -2,
'position' => 900),
451 $this->ismultientitymanaged = 1;
452 $this->socid = $socid;
453 $this->
id = $propalid;
457 $this->fields[
'ref_ext'][
'visible'] =
getDolGlobalInt(
'MAIN_LIST_SHOW_REF_EXT');
473 public function add_product($idproduct, $qty, $remise_percent = 0)
476 global
$conf, $mysoc;
482 dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
483 if ($idproduct > 0) {
484 $prod =
new Product($this->db);
485 $prod->fetch($idproduct);
487 $productdesc = $prod->description;
489 $tva_tx = (string)
get_default_tva($mysoc, $this->thirdparty, $prod->id);
491 if (empty($tva_tx)) {
496 $localtax1_tx =
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
497 $localtax2_tx =
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
501 $price = $prod->multiprices[$this->thirdparty->price_level];
503 $price = $prod->price;
508 $line->fk_product = $idproduct;
509 $line->desc = $productdesc;
511 $line->subprice = $price;
512 $line->remise_percent = $remise_percent;
513 $line->vat_src_code = $vat_src_code;
514 $line->tva_tx = $tva_tx;
515 $line->fk_unit = $prod->fk_unit;
517 $line->info_bits = 1;
520 $this->lines[] = $line;
538 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
539 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
544 $result = $remise->fetch($idremise);
547 if ($remise->fk_facture) {
548 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
549 $this->db->rollback();
555 $line->context = $this->context;
557 $line->fk_propal = $this->id;
558 $line->fk_remise_except = $remise->id;
559 $line->desc = $remise->description;
560 $line->vat_src_code = $remise->vat_src_code;
561 $line->tva_tx = $remise->tva_tx;
562 $line->subprice = -(float) $remise->amount_ht;
563 $line->fk_product = 0;
565 $line->remise_percent = 0;
567 $line->info_bits = 2;
570 $line->price = -(float) $remise->amount_ht;
572 $line->total_ht = -(float) $remise->amount_ht;
573 $line->total_tva = -(float) $remise->amount_tva;
574 $line->total_ttc = -(float) $remise->amount_ttc;
576 $result = $line->insert();
583 $this->db->rollback();
587 $this->error = $line->error;
588 $this->errors = $line->errors;
589 $this->db->rollback();
593 $this->db->rollback();
635 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)
637 global $mysoc,
$conf, $langs;
639 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);
641 if ($this->statut == self::STATUS_DRAFT) {
642 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
645 if (empty($remise_percent)) {
651 if (empty($info_bits)) {
657 if (empty($fk_parent_line) || $fk_parent_line < 0) {
661 $remise_percent =
price2num($remise_percent);
664 $pu_ht_devise =
price2num($pu_ht_devise);
666 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
672 if ($price_base_type ==
'HT') {
683 if ($date_start && $date_end && $date_start > $date_end) {
684 $langs->load(
"errors");
685 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
691 $product_type = $type;
692 if (!empty($fk_product) && $fk_product > 0) {
693 $product =
new Product($this->db);
694 $result = $product->fetch($fk_product);
695 $product_type = $product->type;
697 if (
getDolGlobalString(
'STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL') && $product_type == 0 && $product->stock_reel < $qty) {
698 $langs->load(
"errors");
699 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
700 $this->db->rollback();
715 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
716 $vat_src_code = $reg[1];
717 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
720 $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);
722 $total_ht = $tabprice[0];
723 $total_tva = $tabprice[1];
724 $total_ttc = $tabprice[2];
725 $total_localtax1 = $tabprice[9];
726 $total_localtax2 = $tabprice[10];
727 $pu_ht = $tabprice[3];
728 $pu_tva = $tabprice[4];
729 $pu_ttc = $tabprice[5];
732 $multicurrency_total_ht = $tabprice[16];
733 $multicurrency_total_tva = $tabprice[17];
734 $multicurrency_total_ttc = $tabprice[18];
735 $pu_ht_devise = $tabprice[19];
739 if ($ranktouse == -1) {
740 $rangmax = $this->
line_max($fk_parent_line);
741 $ranktouse = $rangmax + 1;
748 if ((
float) $remise_percent > 0) {
749 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
750 $price = (float) $pu - $remise;
756 $this->line->context = $this->context;
758 $this->line->fk_propal = $this->id;
759 $this->line->label = $label;
760 $this->line->desc = $desc;
761 $this->line->qty = $qty;
763 $this->line->vat_src_code = $vat_src_code;
764 $this->line->tva_tx = $txtva;
765 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
766 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
767 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
768 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
769 $this->line->fk_product = $fk_product;
770 $this->line->product_type = $type;
771 $this->line->fk_remise_except = $fk_remise_except;
772 $this->line->remise_percent = $remise_percent;
773 $this->line->subprice = (float) $pu_ht;
774 $this->line->rang = $ranktouse;
775 $this->line->info_bits = $info_bits;
776 $this->line->total_ht = (float) $total_ht;
777 $this->line->total_tva = (float) $total_tva;
778 $this->line->total_localtax1 = (float) $total_localtax1;
779 $this->line->total_localtax2 = (float) $total_localtax2;
780 $this->line->total_ttc = (float) $total_ttc;
781 $this->line->special_code = $special_code;
782 $this->line->fk_parent_line = $fk_parent_line;
783 $this->line->fk_unit = $fk_unit;
785 $this->line->date_start = $date_start;
786 $this->line->date_end = $date_end;
788 $this->line->fk_fournprice = $fk_fournprice;
789 $this->line->pa_ht = $pa_ht;
791 $this->line->origin_id = $origin_id;
792 $this->line->origin = $origin;
795 $this->line->fk_multicurrency = $this->fk_multicurrency;
796 $this->line->multicurrency_code = $this->multicurrency_code;
797 $this->line->multicurrency_subprice = (float) $pu_ht_devise;
798 $this->line->multicurrency_total_ht = (float) $multicurrency_total_ht;
799 $this->line->multicurrency_total_tva = (float) $multicurrency_total_tva;
800 $this->line->multicurrency_total_ttc = (float) $multicurrency_total_ttc;
803 if (empty($qty) && empty($special_code)) {
804 $this->line->special_code = 3;
808 $this->line->price = $price;
810 if (is_array($array_options) && count($array_options) > 0) {
811 $this->line->array_options = $array_options;
814 $result = $this->line->insert();
816 if (!isset($this->context[
'createfromclone'])) {
817 if (!empty($fk_parent_line)) {
820 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
822 $linecount = count($this->lines);
823 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
828 $this->lines[] = $this->line;
832 if (empty($noupdateafterinsertline)) {
838 return $this->line->id;
840 $this->error = $this->db->error();
841 $this->db->rollback();
845 $this->error = $this->line->error;
846 $this->errors = $this->line->errors;
847 $this->db->rollback();
851 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
886 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)
888 global $mysoc, $langs;
890 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
891 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");
892 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
895 $remise_percent =
price2num($remise_percent);
898 $pu_ht_devise =
price2num($pu_ht_devise);
899 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
905 if (empty($qty) && empty($special_code)) {
908 if (!empty($qty) && $special_code == 3) {
915 if ($date_start && $date_end && $date_start > $date_end) {
916 $langs->load(
"errors");
917 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
921 if ($this->
status == self::STATUS_DRAFT) {
934 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
935 $vat_src_code = $reg[1];
936 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
941 $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);
942 $total_ht = $tabprice[0];
943 $total_tva = $tabprice[1];
944 $total_ttc = $tabprice[2];
945 $total_localtax1 = $tabprice[9];
946 $total_localtax2 = $tabprice[10];
947 $pu_ht = $tabprice[3];
948 $pu_tva = $tabprice[4];
949 $pu_ttc = $tabprice[5];
952 $multicurrency_total_ht = $tabprice[16];
953 $multicurrency_total_tva = $tabprice[17];
954 $multicurrency_total_ttc = $tabprice[18];
955 $pu_ht_devise = $tabprice[19];
960 if ((
float) $remise_percent > 0) {
961 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
962 $price = (float) $pu - $remise;
967 $line->fetch($rowid);
969 $staticline = clone $line;
971 $line->oldline = $staticline;
973 $this->line->context = $this->context;
974 $this->line->rang = $rang;
977 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
978 $rangmax = $this->
line_max($fk_parent_line);
979 $this->line->rang = $rangmax + 1;
982 $this->line->id = $rowid;
983 $this->line->label = $label;
984 $this->line->desc = $desc;
985 $this->line->qty = $qty;
986 $this->line->product_type = $type;
987 $this->line->vat_src_code = $vat_src_code;
988 $this->line->tva_tx = $txtva;
989 $this->line->localtax1_tx = $txlocaltax1;
990 $this->line->localtax2_tx = $txlocaltax2;
991 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
992 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
993 $this->line->remise_percent = $remise_percent;
994 $this->line->subprice = (float) $pu_ht;
995 $this->line->info_bits = $info_bits;
997 $this->line->total_ht = (float) $total_ht;
998 $this->line->total_tva = (float) $total_tva;
999 $this->line->total_localtax1 = (float) $total_localtax1;
1000 $this->line->total_localtax2 = (float) $total_localtax2;
1001 $this->line->total_ttc = (float) $total_ttc;
1002 $this->line->special_code = $special_code;
1003 $this->line->fk_parent_line = $fk_parent_line;
1004 $this->line->skip_update_total = $skip_update_total;
1005 $this->line->fk_unit = $fk_unit;
1007 $this->line->fk_fournprice = $fk_fournprice;
1008 $this->line->pa_ht = $pa_ht;
1010 $this->line->date_start = $date_start;
1011 $this->line->date_end = $date_end;
1013 if (is_array($array_options) && count($array_options) > 0) {
1015 foreach ($array_options as $key => $value) {
1016 $this->line->array_options[$key] = $array_options[$key];
1021 $this->line->multicurrency_subprice = (float) $pu_ht_devise;
1022 $this->line->multicurrency_total_ht = (float) $multicurrency_total_ht;
1023 $this->line->multicurrency_total_tva = (float) $multicurrency_total_tva;
1024 $this->line->multicurrency_total_ttc = (float) $multicurrency_total_ttc;
1026 $result = $this->line->update($notrigger);
1029 if (!empty($fk_parent_line)) {
1039 $this->db->commit();
1042 $this->error = $this->line->error;
1043 $this->errors = $this->line->errors;
1044 $this->db->rollback();
1048 dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
1065 if ($this->
status == self::STATUS_DRAFT) {
1070 $line->context = $this->context;
1073 $line->fetch($lineid);
1075 if ($id > 0 && $line->fk_propal != $id) {
1076 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
1081 $staticline = clone $line;
1082 $line->oldline = $staticline;
1084 if ($line->delete($user) > 0) {
1087 $this->db->commit();
1090 $this->error = $line->error;
1091 $this->errors = $line->errors;
1092 $this->db->rollback();
1096 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1110 public function create($user, $notrigger = 0)
1112 global
$conf, $hookmanager, $mysoc;
1118 if (empty($this->date)) {
1119 $this->date = $this->datep;
1121 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1122 if (empty($this->availability_id)) {
1123 $this->availability_id = 0;
1125 if (empty($this->demand_reason_id)) {
1126 $this->demand_reason_id = 0;
1130 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1135 if (empty($this->fk_multicurrency)) {
1136 $this->multicurrency_code =
$conf->currency;
1137 $this->fk_multicurrency = 0;
1138 $this->multicurrency_tx = 1;
1144 $delivery_date = $this->delivery_date;
1151 $this->error =
"Failed to fetch company";
1152 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1157 if (!empty($this->
ref)) {
1160 $this->error =
'ErrorRefAlreadyExists';
1161 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1162 $this->db->rollback();
1167 if (empty($this->date)) {
1168 $this->error =
"Date of proposal is required";
1169 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1177 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
1180 $sql .=
", total_tva";
1181 $sql .=
", total_ttc";
1185 $sql .=
", fk_user_author";
1186 $sql .=
", note_private";
1187 $sql .=
", note_public";
1188 $sql .=
", model_pdf";
1189 $sql .=
", fin_validite";
1190 $sql .=
", fk_cond_reglement";
1191 $sql .=
", deposit_percent";
1192 $sql .=
", fk_mode_reglement";
1193 $sql .=
", fk_account";
1194 $sql .=
", ref_client";
1195 $sql .=
", ref_ext";
1196 $sql .=
", date_livraison";
1197 $sql .=
", fk_shipping_method";
1198 $sql .=
", fk_warehouse";
1199 $sql .=
", fk_availability";
1200 $sql .=
", fk_input_reason";
1201 $sql .=
", fk_projet";
1202 $sql .=
", fk_incoterms";
1203 $sql .=
", location_incoterms";
1205 $sql .=
", fk_multicurrency";
1206 $sql .=
", multicurrency_code";
1207 $sql .=
", multicurrency_tx";
1209 $sql .=
" VALUES (";
1210 $sql .= $this->socid;
1214 $sql .=
", '".$this->db->idate($this->date).
"'";
1215 $sql .=
", '".$this->db->idate($now).
"'";
1216 $sql .=
", '(PROV)'";
1217 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1218 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1219 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1220 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1221 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1222 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1223 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1224 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1225 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1226 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1227 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1228 $sql .=
", ".(!
isDolTms($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1229 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1230 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1231 $sql .=
", ".$this->availability_id;
1232 $sql .=
", ".$this->demand_reason_id;
1233 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1234 $sql .=
", ".(int) $this->fk_incoterms;
1235 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1236 $sql .=
", ".(int) $this->entity;
1237 $sql .=
", ".(int) $this->fk_multicurrency;
1238 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1239 $sql .=
", ".(float) $this->multicurrency_tx;
1242 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1243 $resql = $this->db->query($sql);
1245 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1248 $this->
ref =
'(PROV'.$this->id.
')';
1249 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1251 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1252 $resql = $this->db->query($sql);
1257 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1258 $this->linked_objects = $this->linkedObjectsIds;
1262 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1263 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1264 if (is_array($tmp_origin_id)) {
1265 foreach ($tmp_origin_id as $origin_id) {
1268 $this->error = $this->db->lasterror();
1273 $origin_id = $tmp_origin_id;
1276 $this->error = $this->db->lasterror();
1288 $fk_parent_line = 0;
1289 $num = count($this->lines);
1291 for ($i = 0; $i < $num; $i++) {
1292 if (!is_object($this->lines[$i])) {
1294 $line = (object) $this->lines[$i];
1296 $line = $this->lines[$i];
1299 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1300 $fk_parent_line = 0;
1303 $vatrate = $line->tva_tx;
1304 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1305 $vatrate .=
' ('.$line->vat_src_code.
')';
1309 $originid = $line->origin_id;
1310 $origintype = $line->origin;
1312 $originid = $line->id;
1313 $origintype = $this->element;
1321 $line->localtax1_tx,
1322 $line->localtax2_tx,
1324 $line->remise_percent,
1328 $line->product_type,
1330 $line->special_code,
1332 $line->fk_fournprice,
1337 $line->array_options,
1348 $this->error = $this->db->error;
1354 $line->id = $result;
1357 if ($result > 0 && $line->product_type == 9) {
1358 $fk_parent_line = $result;
1388 if (!$error && !$notrigger) {
1397 $this->error = $this->db->lasterror();
1402 $this->error = $this->db->lasterror();
1407 $this->db->commit();
1408 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1411 $this->db->rollback();
1415 $this->error = $this->db->lasterror();
1416 $this->db->rollback();
1431 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1433 global
$conf, $hookmanager, $mysoc;
1442 $object =
new self($this->db);
1449 $objsoc =
new Societe($this->db);
1452 if (!empty($socid) && $socid !=
$object->socid) {
1453 if ($objsoc->fetch($socid) > 0) {
1455 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1456 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1457 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1458 $object->fk_delivery_address = 0;
1481 $objsoc->fetch(
$object->socid);
1485 if ($update_prices ===
true || $update_desc ===
true) {
1486 if ($objsoc->id > 0 && !empty(
$object->lines)) {
1489 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1492 foreach (
$object->lines as $line) {
1495 if ($line->fk_product > 0) {
1496 $prod =
new Product($this->db);
1497 $res = $prod->fetch($line->fk_product);
1499 if ($update_prices ===
true) {
1500 $pu_ht = $prod->price;
1502 $remise_percent = $objsoc->remise_percent;
1505 $pu_ht = $prod->multiprices[$objsoc->price_level];
1507 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1508 $tva_tx = (string) $prod->multiprices_tva_tx[$objsoc->price_level];
1513 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1514 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1517 if (count($prodcustprice->lines) > 0) {
1518 $pu_ht =
price($prodcustprice->lines[0]->price);
1519 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1520 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1521 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1527 $line->subprice = $pu_ht;
1528 $line->tva_tx = $tva_tx;
1529 $line->remise_percent = $remise_percent;
1531 if ($update_desc ===
true) {
1532 $line->desc = $prod->description;
1542 $object->entity = (!empty($forceentity) ? $forceentity :
$object->entity);
1546 $object->user_creation_id = $user->id;
1547 $object->user_validation_id = 0;
1560 $object->context[
'createfromclone'] =
'createfromclone';
1561 $result =
$object->create($user);
1563 $this->error =
$object->error;
1564 $this->errors = array_merge($this->errors,
$object->errors);
1570 if (
$object->copy_linked_contact($this,
'internal') < 0) {
1577 if ($this->socid ==
$object->socid) {
1578 if (
$object->copy_linked_contact($this,
'external') < 0) {
1586 if (is_object($hookmanager)) {
1587 $parameters = array(
'objFrom' => $this,
'clonedObj' =>
$object);
1589 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters,
$object, $action);
1597 unset(
$object->context[
'createfromclone']);
1601 $this->db->commit();
1604 $this->db->rollback();
1618 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1620 $sql =
"SELECT p.rowid, p.ref, p.entity, p.fk_soc";
1621 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1622 $sql .=
", p.datec";
1623 $sql .=
", p.date_signature as dates";
1624 $sql .=
", p.date_valid as datev";
1625 $sql .=
", p.datep as dp";
1626 $sql .=
", p.fin_validite as dfv";
1627 $sql .=
", p.date_livraison as delivery_date";
1628 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1629 $sql .=
", p.note_private, p.note_public";
1630 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1631 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1632 $sql .=
", p.fk_delivery_address";
1633 $sql .=
", p.fk_availability";
1634 $sql .=
", p.fk_input_reason";
1635 $sql .=
", p.fk_cond_reglement";
1636 $sql .=
", p.fk_mode_reglement";
1637 $sql .=
', p.fk_account';
1638 $sql .=
", p.fk_shipping_method";
1639 $sql .=
", p.fk_warehouse";
1640 $sql .=
", p.fk_incoterms, p.location_incoterms";
1641 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1642 $sql .=
", p.tms as date_modification";
1643 $sql .=
", i.libelle as label_incoterms";
1644 $sql .=
", c.label as statut_label";
1645 $sql .=
", ca.code as availability_code, ca.label as availability";
1646 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1647 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1648 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1649 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1650 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1651 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1652 $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').
')';
1653 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1654 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1655 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1658 if (!empty($forceentity)) {
1659 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1661 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1663 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1666 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1669 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1670 $resql = $this->db->query($sql);
1672 if ($this->db->num_rows($resql)) {
1673 $obj = $this->db->fetch_object($resql);
1675 $this->
id = $obj->rowid;
1676 $this->entity = $obj->entity;
1678 $this->
ref = $obj->ref;
1679 $this->ref_client = $obj->ref_client;
1680 $this->ref_customer = $obj->ref_client;
1681 $this->ref_ext = $obj->ref_ext;
1683 $this->total = $obj->total_ttc;
1684 $this->total_ttc = $obj->total_ttc;
1685 $this->total_ht = $obj->total_ht;
1686 $this->total_tva = $obj->total_tva;
1687 $this->total_localtax1 = $obj->localtax1;
1688 $this->total_localtax2 = $obj->localtax2;
1690 $this->socid = $obj->fk_soc;
1691 $this->thirdparty =
null;
1693 $this->fk_project = $obj->fk_project;
1694 $this->project =
null;
1696 $this->model_pdf = $obj->model_pdf;
1697 $this->last_main_doc = $obj->last_main_doc;
1698 $this->note = $obj->note_private;
1699 $this->note_private = $obj->note_private;
1700 $this->note_public = $obj->note_public;
1702 $this->
status = (int) $obj->fk_statut;
1703 $this->statut = $this->status;
1705 $this->datec = $this->db->jdate($obj->datec);
1706 $this->datev = $this->db->jdate($obj->datev);
1707 $this->date_creation = $this->db->jdate($obj->datec);
1708 $this->date_validation = $this->db->jdate($obj->datev);
1709 $this->date_modification = $this->db->jdate($obj->date_modification);
1710 $this->date_signature = $this->db->jdate($obj->dates);
1711 $this->date = $this->db->jdate($obj->dp);
1712 $this->datep = $this->db->jdate($obj->dp);
1713 $this->fin_validite = $this->db->jdate($obj->dfv);
1714 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1715 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1716 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1717 $this->availability_id = $obj->fk_availability;
1718 $this->availability_code = $obj->availability_code;
1720 $this->demand_reason_id = $obj->fk_input_reason;
1721 $this->demand_reason_code = $obj->demand_reason_code;
1723 $this->fk_address = $obj->fk_delivery_address;
1725 $this->mode_reglement_id = $obj->fk_mode_reglement;
1726 $this->mode_reglement_code = $obj->mode_reglement_code;
1727 $this->mode_reglement = $obj->mode_reglement;
1728 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1729 $this->cond_reglement_id = $obj->fk_cond_reglement;
1730 $this->cond_reglement_code = $obj->cond_reglement_code;
1731 $this->cond_reglement = $obj->cond_reglement;
1732 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1733 $this->deposit_percent = $obj->deposit_percent;
1735 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1737 $this->user_author_id = $obj->fk_user_author;
1738 $this->user_validation_id = $obj->fk_user_valid;
1739 $this->user_closing_id = $obj->fk_user_cloture;
1742 $this->fk_incoterms = $obj->fk_incoterms;
1743 $this->location_incoterms = $obj->location_incoterms;
1744 $this->label_incoterms = $obj->label_incoterms;
1747 $this->fk_multicurrency = $obj->fk_multicurrency;
1748 $this->multicurrency_code = $obj->multicurrency_code;
1749 $this->multicurrency_tx = $obj->multicurrency_tx;
1750 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1751 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1752 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1758 $this->db->free($resql);
1760 $this->lines = array();
1771 $this->error =
"Record Not Found";
1774 $this->error = $this->db->lasterror();
1793 if (isset($this->
ref)) {
1794 $this->
ref = trim($this->
ref);
1796 if (isset($this->ref_client)) {
1797 $this->ref_client = trim($this->ref_client);
1799 if (isset($this->note) || isset($this->note_private)) {
1800 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1802 if (isset($this->note_public)) {
1803 $this->note_public = trim($this->note_public);
1805 if (isset($this->model_pdf)) {
1806 $this->model_pdf = trim($this->model_pdf);
1808 if (isset($this->import_key)) {
1809 $this->import_key = trim($this->import_key);
1811 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1812 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1819 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1820 $sql .=
" ref = ".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1821 $sql .=
" ref_client = ".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1822 $sql .=
" ref_ext = ".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1823 $sql .=
" fk_soc = ".(!empty($this->socid) ? (int) $this->socid :
"null").
",";
1824 $sql .=
" datep = ".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1825 if (!empty($this->fin_validite)) {
1826 $sql .=
" fin_validite = ".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1828 $sql .=
" date_valid = ".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1829 $sql .=
" total_tva = ".(isset($this->total_tva) ? (float) $this->total_tva :
"null").
",";
1830 $sql .=
" localtax1 = ".(isset($this->total_localtax1) ? (float) $this->total_localtax1 :
"null").
",";
1831 $sql .=
" localtax2 = ".(isset($this->total_localtax2) ? (float) $this->total_localtax2 :
"null").
",";
1832 $sql .=
" total_ht = ".(isset($this->total_ht) ? (float) $this->total_ht :
"null").
",";
1833 $sql .=
" total_ttc = ".(isset($this->total_ttc) ? (float) $this->total_ttc :
"null").
",";
1834 $sql .=
" fk_statut = ".(isset($this->
status) ? (int) $this->
status :
"null").
",";
1835 $sql .=
" fk_user_author = ".(!empty($this->user_author_id) ? (int) $this->user_author_id :
"null").
",";
1836 $sql .=
" fk_user_valid = ".(!empty($this->user_validation_id) ? (int) $this->user_validation_id :
"null").
",";
1838 $sql .=
" fk_projet = ".(!empty($this->fk_project) ? (int) $this->fk_project :
"null").
",";
1839 $sql .=
" fk_cond_reglement = ".(!empty($this->cond_reglement_id) ? (int) $this->cond_reglement_id :
"null").
",";
1840 $sql .=
" deposit_percent = ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1841 $sql .=
" fk_mode_reglement = ".(!empty($this->mode_reglement_id) ? (int) $this->mode_reglement_id :
"null").
",";
1842 $sql .=
" fk_input_reason = ".(!empty($this->demand_reason_id) ? (int) $this->demand_reason_id :
"null").
",";
1843 $sql .=
" fk_shipping_method=".(isset($this->shipping_method_id) ? (int) $this->shipping_method_id :
"null").
",";
1844 $sql .=
" fk_availability=".(isset($this->availability_id) ? (int) $this->availability_id :
"null").
",";
1845 $sql .=
" note_private = ".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1846 $sql .=
" note_public = ".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1847 $sql .=
" model_pdf = ".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1848 $sql .=
" import_key = ".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1849 $sql .=
" WHERE rowid = ".((int) $this->
id);
1853 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1854 $resql = $this->db->query($sql);
1857 $this->errors[] =
"Error ".$this->db->lasterror();
1867 if (!$error && !$notrigger) {
1878 foreach ($this->errors as $errmsg) {
1879 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1880 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1882 $this->db->rollback();
1885 $this->db->commit();
1900 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $sqlforgedfilters =
'')
1903 $this->lines = array();
1905 $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,';
1906 $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,';
1907 $sql .=
' d.fk_unit,';
1908 $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,';
1909 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1910 $sql .=
' d.date_start, d.date_end,';
1911 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1912 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1913 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1914 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1915 if ($only_product) {
1916 $sql .=
' AND p.fk_product_type = 0';
1918 if ($sqlforgedfilters) {
1919 $sql .= $sqlforgedfilters;
1921 $sql .=
' ORDER by d.rang';
1923 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1924 $result = $this->db->query($sql);
1926 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1928 $num = $this->db->num_rows($result);
1932 $objp = $this->db->fetch_object($result);
1936 $line->rowid = $objp->rowid;
1937 $line->id = $objp->rowid;
1938 $line->fk_propal = $objp->fk_propal;
1939 $line->fk_parent_line = $objp->fk_parent_line;
1940 $line->product_type = $objp->product_type;
1941 $line->label = $objp->custom_label;
1942 $line->desc = $objp->description;
1943 $line->description = $objp->description;
1944 $line->qty = $objp->qty;
1945 $line->vat_src_code = $objp->vat_src_code;
1946 $line->tva_tx = $objp->tva_tx;
1947 $line->localtax1_tx = $objp->localtax1_tx;
1948 $line->localtax2_tx = $objp->localtax2_tx;
1949 $line->localtax1_type = $objp->localtax1_type;
1950 $line->localtax2_type = $objp->localtax2_type;
1951 $line->subprice = $objp->subprice;
1952 $line->fk_remise_except = $objp->fk_remise_except;
1953 $line->remise_percent = $objp->remise_percent;
1954 $line->price = $objp->price;
1956 $line->info_bits = $objp->info_bits;
1957 $line->total_ht = $objp->total_ht;
1958 $line->total_tva = $objp->total_tva;
1959 $line->total_localtax1 = $objp->total_localtax1;
1960 $line->total_localtax2 = $objp->total_localtax2;
1961 $line->total_ttc = $objp->total_ttc;
1962 $line->fk_fournprice = $objp->fk_fournprice;
1963 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1964 $line->pa_ht = $marginInfos[0];
1965 $line->marge_tx = $marginInfos[1];
1966 $line->marque_tx = $marginInfos[2];
1967 $line->special_code = $objp->special_code;
1968 $line->rang = $objp->rang;
1970 $line->fk_product = $objp->fk_product;
1972 $line->ref = $objp->product_ref;
1973 $line->libelle = $objp->product_label;
1975 $line->product_ref = $objp->product_ref;
1976 $line->product_label = $objp->product_label;
1977 $line->product_desc = $objp->product_desc;
1978 $line->product_tobatch = $objp->product_tobatch;
1979 $line->product_barcode = $objp->product_barcode;
1981 $line->fk_product_type = $objp->fk_product_type;
1982 $line->fk_unit = $objp->fk_unit;
1983 $line->weight = $objp->weight;
1984 $line->weight_units = $objp->weight_units;
1985 $line->volume = $objp->volume;
1986 $line->volume_units = $objp->volume_units;
1988 $line->date_start = $this->db->jdate($objp->date_start);
1989 $line->date_end = $this->db->jdate($objp->date_end);
1992 $line->fk_multicurrency = $objp->fk_multicurrency;
1993 $line->multicurrency_code = $objp->multicurrency_code;
1994 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1995 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1996 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1997 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1999 $line->fetch_optionals();
2002 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
2003 $tmpproduct =
new Product($this->db);
2004 $tmpproduct->fetch($objp->fk_product);
2005 $tmpproduct->getMultiLangs();
2007 $line->multilangs = $tmpproduct->multilangs;
2010 $this->lines[$i] = $line;
2015 $this->db->free($result);
2019 $this->error = $this->db->lasterror();
2031 public function valid($user, $notrigger = 0)
2035 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2040 if ($this->
status == self::STATUS_VALIDATED) {
2041 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
2045 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'creer'))
2046 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'propal_advance',
'validate')))) {
2047 $this->error =
'ErrorPermissionDenied';
2048 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
2057 $soc =
new Societe($this->db);
2058 $soc->fetch($this->socid);
2061 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2068 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2069 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2070 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2073 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2074 $resql = $this->db->query($sql);
2081 if (!$error && !$notrigger) {
2083 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2091 $this->oldref = $this->ref;
2094 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2096 $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).
"'";
2097 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int)
$conf->entity);
2098 $resql = $this->db->query($sql);
2101 $this->error = $this->db->lasterror();
2103 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2104 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2105 $resql = $this->db->query($sql);
2108 $this->error = $this->db->lasterror();
2114 $dirsource =
$conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2115 $dirdest =
$conf->propal->multidir_output[$this->entity].
'/'.$newref;
2116 if (!$error && file_exists($dirsource)) {
2117 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2118 if (@rename($dirsource, $dirdest)) {
2121 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2122 foreach ($listoffiles as $fileentry) {
2123 $dirsource = $fileentry[
'name'];
2124 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2125 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2126 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2127 @rename($dirsource, $dirdest);
2135 $this->user_validation_id = $user->id;
2136 $this->datev = $now;
2137 $this->date_validation = $now;
2139 $this->db->commit();
2142 $this->db->rollback();
2161 $this->error =
'ErrorBadParameter';
2162 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2166 if ($user->hasRight(
'propal',
'creer')) {
2171 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2172 $sql .=
" WHERE rowid = ".((int) $this->
id);
2175 $resql = $this->db->query($sql);
2177 $this->errors[] = $this->db->error();
2182 $this->oldcopy = clone $this;
2183 $this->date = $date;
2184 $this->datep = $date;
2187 if (!$notrigger && empty($error)) {
2197 $this->db->commit();
2200 foreach ($this->errors as $errmsg) {
2201 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2202 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2204 $this->db->rollback();
2224 if ($user->hasRight(
'propal',
'creer')) {
2229 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2230 $sql .=
" WHERE rowid = ".((int) $this->
id);
2234 $resql = $this->db->query($sql);
2236 $this->errors[] = $this->db->error();
2242 $this->oldcopy = clone $this;
2243 $this->fin_validite = $date_end_validity;
2246 if (!$notrigger && empty($error)) {
2256 $this->db->commit();
2259 foreach ($this->errors as $errmsg) {
2260 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2261 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2263 $this->db->rollback();
2297 if ($user->hasRight(
'propal',
'creer')) {
2302 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2303 $sql .=
" SET date_livraison = ".(isDolTms($delivery_date) ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2304 $sql .=
" WHERE rowid = ".((int) $this->
id);
2307 $resql = $this->db->query($sql);
2309 $this->errors[] = $this->db->error();
2314 $this->oldcopy = clone $this;
2315 $this->delivery_date = $delivery_date;
2318 if (!$notrigger && empty($error)) {
2328 $this->db->commit();
2331 foreach ($this->errors as $errmsg) {
2332 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2333 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2335 $this->db->rollback();
2355 if ($user->hasRight(
'propal',
'creer') && $this->status >= self::STATUS_DRAFT) {
2360 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2361 $sql .=
" SET fk_availability = ".((int) $id);
2362 $sql .=
" WHERE rowid = ".((int) $this->
id);
2364 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2365 $resql = $this->db->query($sql);
2367 $this->errors[] = $this->db->error();
2372 $this->oldcopy = clone $this;
2373 $this->fk_availability = $id;
2374 $this->availability_id = $id;
2377 if (!$notrigger && empty($error)) {
2387 $this->db->commit();
2390 foreach ($this->errors as $errmsg) {
2391 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2392 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2394 $this->db->rollback();
2398 $error_str =
'Propal status do not meet requirement '.$this->status;
2400 $this->error = $error_str;
2401 $this->errors[] = $this->error;
2418 if ($user->hasRight(
'propal',
'creer') && $this->status >= self::STATUS_DRAFT) {
2423 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2424 $sql .=
" SET fk_input_reason = ".((int) $id);
2425 $sql .=
" WHERE rowid = ".((int) $this->
id);
2428 $resql = $this->db->query($sql);
2430 $this->errors[] = $this->db->error();
2436 $this->oldcopy = clone $this;
2438 $this->demand_reason_id = $id;
2442 if (!$notrigger && empty($error)) {
2452 $this->db->commit();
2455 foreach ($this->errors as $errmsg) {
2456 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2457 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2459 $this->db->rollback();
2463 $error_str =
'Propal status do not meet requirement '.$this->status;
2465 $this->error = $error_str;
2466 $this->errors[] = $this->error;
2483 if ($user->hasRight(
'propal',
'creer')) {
2488 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2489 $sql .=
" WHERE rowid = ".((int) $this->
id);
2491 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2492 $resql = $this->db->query($sql);
2494 $this->errors[] = $this->db->error();
2499 $this->oldcopy = clone $this;
2500 $this->ref_client = $ref_client;
2503 if (!$notrigger && empty($error)) {
2513 $this->db->commit();
2516 foreach ($this->errors as $errmsg) {
2517 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2518 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2520 $this->db->rollback();
2538 public function reopen($user, $status, $note =
'', $notrigger = 0)
2542 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2543 $sql .=
" SET fk_statut = ".((int) $status).
",";
2544 if (!empty($note)) {
2545 $sql .=
" note_private = '".$this->db->escape($note).
"',";
2547 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2548 $sql .=
" WHERE rowid = ".((int) $this->
id);
2552 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2553 $resql = $this->db->query($sql);
2556 $this->errors[] =
"Error ".$this->db->lasterror();
2571 if (!empty($this->errors)) {
2572 foreach ($this->errors as $errmsg) {
2573 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2574 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2577 $this->db->rollback();
2580 $this->statut = $status;
2583 $this->db->commit();
2598 public function closeProposal($user, $status, $note_private =
'', $notrigger = 0, $note_public =
'')
2600 global $langs,
$conf;
2607 $newprivatenote =
dol_concatdesc($this->note_private, $note_private);
2608 $newpublicnote =
dol_concatdesc($this->note_public, $note_public);
2611 $date_signature = $now;
2612 $fk_user_signature = $user->id;
2614 $this->
info($this->
id);
2615 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2616 $date_signature = $now;
2617 $fk_user_signature = $user->id;
2619 $date_signature = $this->date_signature;
2620 $fk_user_signature = $this->user_signature->id;
2624 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2625 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"', note_public = '".$this->db->escape($newpublicnote).
"'";
2626 if ($status == self::STATUS_SIGNED) {
2627 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2629 $sql .=
" WHERE rowid = ".((int) $this->
id);
2631 $resql = $this->db->query($sql);
2635 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2637 if ($status == self::STATUS_SIGNED) {
2638 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2639 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_TOBILL') ?
$conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2642 $soc =
new Societe($this->db);
2643 $soc->id = $this->socid;
2644 $result = $soc->setAsCustomer();
2647 $this->error = $this->db->lasterror();
2648 $this->db->rollback();
2655 $outputlangs = $langs;
2658 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2659 $outputlangs->setDefaultLang($newlang);
2668 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2672 $this->oldcopy = clone $this;
2673 $this->statut = $status;
2675 $this->date_signature = $date_signature;
2676 $this->note_private = $newprivatenote;
2679 if (!$notrigger && empty($error)) {
2689 $this->db->commit();
2692 $this->statut = $this->oldcopy->status;
2693 $this->
status = $this->oldcopy->status;
2694 $this->date_signature = $this->oldcopy->date_signature;
2695 $this->note_private = $this->oldcopy->note_private;
2697 $this->db->rollback();
2701 $this->error = $this->db->lasterror();
2702 $this->db->rollback();
2717 global
$conf, $langs;
2724 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2730 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2731 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2732 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2735 $resql = $this->db->query($sql);
2737 $this->errors[] = $this->db->error();
2740 $num = $this->db->affected_rows($resql);
2748 $outputlangs = $langs;
2751 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2752 $outputlangs->setDefaultLang($newlang);
2761 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2764 $this->oldcopy = clone $this;
2767 $this->date_cloture = $now;
2768 $this->note_private = $newprivatenote;
2771 if (!$notrigger && empty($error)) {
2781 $this->db->commit();
2784 foreach ($this->errors as $errmsg) {
2785 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2786 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2788 $this->db->rollback();
2805 $sql =
"UPDATE ". MAIN_DB_PREFIX .
"propal";
2806 $sql .=
" SET fk_statut = " . self::STATUS_CANCELED .
",";
2807 $sql .=
" fk_user_modif = " . ((int) $user->id);
2808 $sql .=
" WHERE rowid = " . ((int) $this->
id);
2810 dol_syslog(get_class($this).
"::cancel", LOG_DEBUG);
2811 if ($this->db->query($sql)) {
2824 $this->db->commit();
2827 foreach ($this->errors as $errmsg) {
2828 dol_syslog(get_class($this).
"::cancel ".$errmsg, LOG_ERR);
2829 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2831 $this->db->rollback();
2835 $this->error = $this->db->error();
2836 $this->db->rollback();
2855 if ($this->
status <= self::STATUS_DRAFT) {
2859 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2863 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2864 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2865 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2866 $sql .=
" WHERE rowid = ".((int) $this->
id);
2868 $resql = $this->db->query($sql);
2870 $this->errors[] = $this->db->error();
2875 $this->oldcopy = clone $this;
2878 if (!$notrigger && empty($error)) {
2891 $this->db->commit();
2894 foreach ($this->errors as $errmsg) {
2895 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2896 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2898 $this->db->rollback();
2918 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2925 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2926 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2927 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2928 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2929 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2930 $sql .=
" AND p.fk_soc = s.rowid";
2931 $sql .=
" AND p.fk_statut = c.id";
2935 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
2936 $search_sale = $user->id;
2939 if ($search_sale && $search_sale !=
'-1') {
2940 if ($search_sale == -2) {
2941 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
2942 } elseif ($search_sale > 0) {
2943 $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).
")";
2948 $sql .=
" AND p.fk_soc = ".((int) $socid);
2951 $sql .=
" AND p.fk_statut = ".((int) self::STATUS_DRAFT);
2953 if ($notcurrentuser > 0) {
2954 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2956 $sql .= $this->db->order($sortfield, $sortorder);
2957 $sql .= $this->db->plimit($limit, $offset);
2959 $result = $this->db->query($sql);
2961 $num = $this->db->num_rows($result);
2965 $obj = $this->db->fetch_object($result);
2967 if ($shortlist == 1) {
2968 $ga[$obj->propalid] = $obj->ref;
2969 } elseif ($shortlist == 2) {
2970 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2972 $ga[$i][
'id'] = $obj->propalid;
2973 $ga[$i][
'ref'] = $obj->ref;
2974 $ga[$i][
'name'] = $obj->name;
3008 $linkedInvoices = array();
3011 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
3014 foreach ($objectid as $key =>
$object) {
3016 if ($objecttype ==
'facture') {
3021 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
3022 foreach ($subobjectid as $subkey => $subobject) {
3023 if ($subobjecttype ==
'facture') {
3024 $linkedInvoices[] = $subobject;
3032 if (count($linkedInvoices) > 0) {
3033 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
3034 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
3035 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
3037 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
3038 $resql = $this->db->query($sql);
3041 $tab_sqlobj = array();
3042 $nump = $this->db->num_rows($resql);
3043 for ($i = 0; $i < $nump; $i++) {
3044 $sqlobj = $this->db->fetch_object($resql);
3045 $tab_sqlobj[] = $sqlobj;
3047 $this->db->free($resql);
3049 $nump = count($tab_sqlobj);
3053 while ($i < $nump) {
3054 $obj = array_shift($tab_sqlobj);
3077 public function delete($user, $notrigger = 0)
3080 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3096 if (!$error && !empty($this->table_element_line)) {
3097 $tabletodelete = $this->table_element_line;
3098 $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).
")";
3099 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3100 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3102 $this->error = $this->db->lasterror();
3103 $this->errors[] = $this->error;
3104 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3129 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3135 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3136 $res = $this->db->query($sql);
3139 $this->error = $this->db->lasterror();
3140 $this->errors[] = $this->error;
3141 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3157 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3158 $dir =
$conf->propal->multidir_output[$this->entity].
"/".$ref;
3159 $file = $dir.
"/".$ref.
".pdf";
3160 if (file_exists($file)) {
3164 $this->error =
'ErrorFailToDeleteFile';
3165 $this->errors[] = $this->error;
3166 $this->db->rollback();
3170 if (file_exists($dir)) {
3173 $this->error =
'ErrorFailToDeleteDir';
3174 $this->errors[] = $this->error;
3175 $this->db->rollback();
3183 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3184 $this->db->commit();
3187 $this->db->rollback();
3204 if ($this->
status >= self::STATUS_DRAFT) {
3209 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3210 $sql .=
' SET fk_availability = '.((int) $availability_id);
3211 $sql .=
' WHERE rowid='.((int) $this->
id);
3213 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3214 $resql = $this->db->query($sql);
3216 $this->errors[] = $this->db->error();
3221 $this->oldcopy = clone $this;
3222 $this->availability_id = $availability_id;
3225 if (!$notrigger && empty($error)) {
3235 $this->db->commit();
3238 foreach ($this->errors as $errmsg) {
3239 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3240 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3242 $this->db->rollback();
3246 $error_str =
'Propal status do not meet requirement '.$this->status;
3248 $this->error = $error_str;
3249 $this->errors[] = $this->error;
3268 if ($this->
status >= self::STATUS_DRAFT) {
3273 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3274 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3275 $sql .=
' WHERE rowid='.((int) $this->
id);
3277 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3278 $resql = $this->db->query($sql);
3280 $this->errors[] = $this->db->error();
3285 $this->oldcopy = clone $this;
3286 $this->demand_reason_id = $demand_reason_id;
3289 if (!$notrigger && empty($error)) {
3299 $this->db->commit();
3302 foreach ($this->errors as $errmsg) {
3303 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3304 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3306 $this->db->rollback();
3310 $error_str =
'Propal status do not meet requirement '.$this->status;
3312 $this->error = $error_str;
3313 $this->errors[] = $this->error;
3327 $sql =
"SELECT c.rowid, ";
3328 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3329 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3330 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3331 $sql .=
" WHERE c.rowid = ".((int) $id);
3333 $result = $this->db->query($sql);
3336 if ($this->db->num_rows($result)) {
3337 $obj = $this->db->fetch_object($result);
3339 $this->
id = $obj->rowid;
3341 $this->date_creation = $this->db->jdate($obj->datec);
3342 $this->date_validation = $this->db->jdate($obj->datev);
3343 $this->date_signature = $this->db->jdate($obj->date_signature);
3344 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3346 $this->user_creation_id = $obj->fk_user_author;
3347 $this->user_validation_id = $obj->fk_user_valid;
3349 if ($obj->fk_user_signature) {
3350 $user_signature =
new User($this->db);
3351 $user_signature->fetch($obj->fk_user_signature);
3352 $this->user_signature = $user_signature;
3355 $this->user_closing_id = $obj->fk_user_cloture;
3357 $this->db->free($result);
3386 global $hookmanager;
3389 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3391 $langs->load(
"propal");
3392 $this->labelStatus[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceled");
3393 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3394 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3395 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3396 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3397 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3398 $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceledShort");
3399 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3400 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3401 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3402 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3403 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3407 if ($status == self::STATUS_CANCELED) {
3408 $statusType =
'status9';
3409 } elseif ($status == self::STATUS_DRAFT) {
3410 $statusType =
'status0';
3411 } elseif ($status == self::STATUS_VALIDATED) {
3412 $statusType =
'status1';
3413 } elseif ($status == self::STATUS_SIGNED) {
3414 $statusType =
'status4';
3415 } elseif ($status == self::STATUS_NOTSIGNED) {
3416 $statusType =
'status9';
3417 } elseif ($status == self::STATUS_BILLED) {
3418 $statusType =
'status6';
3421 $parameters = array(
'status' => $status,
'mode' => $mode);
3422 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3425 return $hookmanager->resPrint;
3428 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3443 global
$conf, $langs;
3447 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3448 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3449 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3450 if ($mode ==
'opened') {
3451 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3453 if ($mode ==
'signed') {
3454 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3458 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
3459 $search_sale = $user->id;
3462 if ($search_sale && $search_sale !=
'-1') {
3463 if ($search_sale == -2) {
3464 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3465 } elseif ($search_sale > 0) {
3466 $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).
")";
3470 $resql = $this->db->query($sql);
3472 $langs->load(
"propal");
3477 $label = $labelShort =
'';
3478 if ($mode ==
'opened') {
3479 $delay_warning =
$conf->propal->cloture->warning_delay;
3481 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3482 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3484 if ($mode ==
'signed') {
3485 $delay_warning =
$conf->propal->facturation->warning_delay;
3487 $label = $langs->trans(
"PropalsToBill");
3488 $labelShort = $langs->trans(
"ToBill");
3492 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3493 $response->label = $label;
3494 $response->labelShort = $labelShort;
3495 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3496 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3500 while ($obj = $this->db->fetch_object($resql)) {
3501 $response->nbtodo++;
3502 $response->total += $obj->total_ht;
3504 if ($mode ==
'opened') {
3505 $datelimit = $this->db->jdate($obj->datefin);
3506 if ($datelimit < ($now - $delay_warning)) {
3507 $response->nbtodolate++;
3516 $this->error = $this->db->error();
3531 global
$conf, $langs;
3536 $sql =
"SELECT rowid";
3537 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3538 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3539 $sql .= $this->db->plimit(100);
3541 $resql = $this->db->query($sql);
3543 $num_prods = $this->db->num_rows($resql);
3545 while ($i < $num_prods) {
3547 $row = $this->db->fetch_row($resql);
3548 $prodids[$i] = $row[0];
3554 $this->
ref =
'SPECIMEN';
3555 $this->ref_client =
'NEMICEPS';
3556 $this->specimen = 1;
3558 $this->date = time();
3559 $this->fin_validite = $this->date + 3600 * 24 * 30;
3560 $this->cond_reglement_id = 1;
3561 $this->cond_reglement_code =
'RECEP';
3562 $this->mode_reglement_id = 7;
3563 $this->mode_reglement_code =
'CHQ';
3564 $this->availability_id = 1;
3565 $this->availability_code =
'AV_NOW';
3566 $this->demand_reason_id = 1;
3567 $this->demand_reason_code =
'SRC_00';
3568 $this->note_public =
'This is a comment (public)';
3569 $this->note_private =
'This is a comment (private)';
3571 $this->multicurrency_tx = 1;
3572 $this->multicurrency_code =
$conf->currency;
3577 while ($xnbp < $nbp) {
3579 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3581 $line->subprice = 100;
3584 $line->localtax1_tx = 0;
3585 $line->localtax2_tx = 0;
3587 $line->total_ht = 50;
3588 $line->total_ttc = 60;
3589 $line->total_tva = 10;
3590 $line->remise_percent = 50;
3592 $line->total_ht = 100;
3593 $line->total_ttc = 120;
3594 $line->total_tva = 20;
3595 $line->remise_percent = 00;
3598 if ($num_prods > 0) {
3599 $prodid = mt_rand(1, $num_prods);
3600 $line->fk_product = $prodids[$prodid];
3601 $line->product_ref =
'SPECIMEN';
3604 $this->lines[$xnbp] = $line;
3606 $this->total_ht += $line->total_ht;
3607 $this->total_tva += $line->total_tva;
3608 $this->total_ttc += $line->total_ttc;
3625 $this->nb = array();
3628 $sql =
"SELECT count(p.rowid) as nb";
3629 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3630 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3631 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3635 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
3636 $search_sale = $user->id;
3639 if ($search_sale && $search_sale !=
'-1') {
3640 if ($search_sale == -2) {
3641 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3642 } elseif ($search_sale > 0) {
3643 $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).
")";
3647 $resql = $this->db->query($sql);
3650 while ($obj = $this->db->fetch_object($resql)) {
3651 $this->nb[
"proposals"] = $obj->nb;
3653 $this->db->free($resql);
3657 $this->error = $this->db->error();
3672 global
$conf, $langs;
3673 $langs->load(
"propal");
3677 if (!empty($classname)) {
3680 $file = $classname.
".php";
3683 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
3684 foreach ($dirmodels as $reldir) {
3688 $mybool = ((bool) @include_once $dir.$file) || $mybool;
3696 $obj =
new $classname();
3697 '@phan-var-force ModeleNumRefPropales $obj';
3699 $numref = $obj->getNextValue($soc, $this);
3701 if ($numref !=
"") {
3704 $this->error = $obj->error;
3709 $langs->load(
"errors");
3710 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3723 global
$conf, $langs, $user;
3725 $langs->load(
'propal');
3727 $nofetch = !empty($params[
'nofetch']);
3730 return [
'optimize' => $langs->trans(
"Proposal")];
3732 if ($user->hasRight(
'propal',
'lire')) {
3733 $datas[
'picto'] =
img_picto(
'', $this->picto,
'', 0, 0, 0,
'',
'paddingrightonly').
'<u>'.$langs->trans(
"Proposal").
'</u>';
3734 if (isset($this->
status)) {
3735 $datas[
'status'] =
' '.$this->getLibStatut(5);
3737 if (!empty($this->
ref)) {
3738 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3741 $langs->load(
'companies');
3742 if (empty($this->thirdparty)) {
3745 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3747 if (!empty($this->ref_customer)) {
3748 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
3751 $langs->load(
'project');
3752 if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) {
3754 if ($res > 0 && $this->project instanceof
Project) {
3755 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3759 if (!empty($this->total_ht)) {
3760 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1,
$conf->currency);
3762 if (!empty($this->total_tva)) {
3763 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1,
$conf->currency);
3765 if (!empty($this->total_ttc)) {
3766 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1,
$conf->currency);
3768 if (!empty($this->date)) {
3769 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3771 if (!empty($this->delivery_date)) {
3772 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3790 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3792 global $langs,
$conf, $user, $hookmanager;
3794 if (!empty(
$conf->dol_no_mouse_hover)) {
3801 'objecttype' => $this->element,
3802 'option' => $option,
3805 $classfortooltip =
'classfortooltip';
3808 $classfortooltip =
'classforajaxtooltip';
3809 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3816 if ($user->hasRight(
'propal',
'lire')) {
3817 if ($option ==
'') {
3818 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3819 } elseif ($option ==
'compta') {
3820 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3821 } elseif ($option ==
'expedition') {
3822 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3823 } elseif ($option ==
'document') {
3824 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3827 if ($option !=
'nolink') {
3829 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3830 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3831 $add_save_lastsearch_values = 1;
3833 if ($add_save_lastsearch_values) {
3834 $url .=
'&save_lastsearch_values=1';
3840 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3842 $label = $langs->trans(
"Proposal");
3843 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
3845 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
3846 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3849 $linkstart =
'<a href="'.$url.
'"';
3850 $linkstart .= $linkclose.
'>';
3853 $result .= $linkstart;
3855 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3857 if ($withpicto != 2) {
3858 $result .= $this->ref;
3860 $result .= $linkend;
3862 if ($addlinktonotes >= 0) {
3865 if ($addlinktonotes == 0) {
3866 if (!empty($this->note_private) || !empty($this->note_public)) {
3867 $txttoshow = $langs->trans(
'ViewPrivateNote');
3869 } elseif ($addlinktonotes == 1) {
3870 if (!empty($this->note_private)) {
3873 } elseif ($addlinktonotes == 2) {
3874 if (!empty($this->note_public)) {
3877 } elseif ($addlinktonotes == 3) {
3878 if ($user->socid > 0) {
3879 if (!empty($this->note_public)) {
3883 if (!empty($this->note_public)) {
3886 if (!empty($this->note_private)) {
3887 if (!empty($txttoshow)) {
3888 $txttoshow .=
'<br><br>';
3896 $result .=
' <span class="note inline-block">';
3897 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3900 $result .=
'</span>';
3905 $hookmanager->initHooks(array($this->element .
'dao'));
3906 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
3907 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3909 $result = $hookmanager->resPrint;
3911 $result .= $hookmanager->resPrint;
3924 return $this->
fetch_lines(0, 0, $sqlforgedfilters);
3938 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3940 global
$conf, $langs;
3942 $langs->load(
"propale");
3943 $outputlangs->load(
"products");
3948 if ($this->model_pdf) {
3949 $modele = $this->model_pdf;
3955 $modelpath =
"core/modules/propale/doc/";
3957 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4005 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
4007 $return =
'<div class="box-flex-item box-flex-grow-zero">';
4008 $return .=
'<div class="info-box info-box-sm">';
4009 $return .=
'<div class="info-box-icon bg-infobox-action">';
4011 $return .=
'</div>';
4012 $return .=
'<div class="info-box-content">';
4013 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
4014 if ($selected >= 0) {
4015 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
4017 if (!empty($arraydata[
'projectlink'])) {
4018 $return .=
'<span class="info-box-ref"> | '.$arraydata[
'projectlink'].
'</span>';
4021 if (property_exists($this,
'thirdparty') && is_object($this->thirdparty)) {
4022 $return .=
'<div class="info-box-ref tdoverflowmax150">'.$this->thirdparty->getNomUrl(1).
'</div>';
4024 if (property_exists($this,
'total_ht')) {
4025 $return .=
'<span class="info-box-label amount" title="'.$langs->trans(
"AmountHT").
'">'.
price($this->total_ht).
'</span>';
4027 if (!empty($arraydata[
'authorlink'])) {
4028 $return .=
' <span class="info-box-label">'.$arraydata[
'authorlink'].
'</span>';
4030 if (method_exists($this,
'getLibStatut')) {
4031 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
4033 $return .=
'</div>';
4034 $return .=
'</div>';
4035 $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_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_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
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.
setEntity($currentobject)
Set entity id to use when to create an object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
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.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_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...
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
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.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
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.