42require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
43require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobjectline.class.php";
44require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
46require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
47require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
48require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
65 public $element =
'propal';
70 public $table_element =
'propal';
75 public $table_element_line =
'propaldet';
80 public $fk_element =
'fk_propal';
85 public $picto =
'propal';
91 public $ismultientitymanaged = 1;
97 public $restrictiononfksoc = 1;
129 public $ref_customer;
160 public $date_creation;
171 public $date_validation;
176 public $date_signature;
181 public $user_signature;
197 public $delivery_date;
200 public $fin_validite;
202 public $user_author_id;
220 public $cond_reglement_code;
221 public $cond_reglement;
222 public $cond_reglement_doc;
224 public $mode_reglement_code;
225 public $mode_reglement;
227 public $deposit_percent;
235 public $address_type;
241 public $availability_id;
248 public $fk_availability;
253 public $availability_code;
258 public $availability;
260 public $duree_validite;
262 public $demand_reason_id;
263 public $demand_reason_code;
264 public $demand_reason;
266 public $warehouse_id;
268 public $extraparams = array();
273 public $lines = array();
280 public $labelStatus = array();
281 public $labelStatusShort = array();
312 public $fields = array(
313 'rowid' =>array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
314 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>15,
'index'=>1),
315 'ref' =>array(
'type'=>
'varchar(30)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>20),
316 'ref_client' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefCustomer',
'enabled'=>1,
'visible'=>-1,
'position'=>22),
317 'ref_ext' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefExt',
'enabled'=>1,
'visible'=>0,
'position'=>40),
318 'fk_soc' =>array(
'type'=>
'integer:Societe:societe/class/societe.class.php',
'label'=>
'ThirdParty',
'enabled'=>
'isModEnabled("societe")',
'visible'=>-1,
'position'=>23),
319 '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),
320 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>25),
321 'datec' =>array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
322 'datep' =>array(
'type'=>
'date',
'label'=>
'Date',
'enabled'=>1,
'visible'=>-1,
'position'=>60),
323 'fin_validite' =>array(
'type'=>
'datetime',
'label'=>
'DateEnd',
'enabled'=>1,
'visible'=>-1,
'position'=>65),
324 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'DateValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>70),
325 'date_cloture' =>array(
'type'=>
'datetime',
'label'=>
'DateClosing',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
326 'fk_user_author' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
327 'fk_user_modif' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'position'=>85),
328 'fk_user_valid' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
329 'fk_user_cloture' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Fk user cloture',
'enabled'=>1,
'visible'=>-1,
'position'=>95),
330 'price' =>array(
'type'=>
'double',
'label'=>
'Price',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
331 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalHT',
'enabled'=>1,
'visible'=>-1,
'position'=>125,
'isameasure'=>1),
332 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'VAT',
'enabled'=>1,
'visible'=>-1,
'position'=>130,
'isameasure'=>1),
333 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'LocalTax1',
'enabled'=>1,
'visible'=>-1,
'position'=>135,
'isameasure'=>1),
334 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'LocalTax2',
'enabled'=>1,
'visible'=>-1,
'position'=>140,
'isameasure'=>1),
335 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalTTC',
'enabled'=>1,
'visible'=>-1,
'position'=>145,
'isameasure'=>1),
336 'fk_account' =>array(
'type'=>
'integer',
'label'=>
'BankAccount',
'enabled'=>
'isModEnabled("banque")',
'visible'=>-1,
'position'=>150),
337 'fk_currency' =>array(
'type'=>
'varchar(3)',
'label'=>
'Currency',
'enabled'=>1,
'visible'=>-1,
'position'=>155),
338 'fk_cond_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentTerm',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
339 'deposit_percent' =>array(
'type'=>
'varchar(63)',
'label'=>
'DepositPercent',
'enabled'=>1,
'visible'=>-1,
'position'=>161),
340 'fk_mode_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentMode',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
341 'note_private' =>array(
'type'=>
'html',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>170),
342 'note_public' =>array(
'type'=>
'html',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>175),
343 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'PDFTemplate',
'enabled'=>1,
'visible'=>0,
'position'=>180),
344 'date_livraison' =>array(
'type'=>
'date',
'label'=>
'DateDeliveryPlanned',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
345 'fk_shipping_method' =>array(
'type'=>
'integer',
'label'=>
'ShippingMethod',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
346 'fk_warehouse' =>array(
'type'=>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label'=>
'Fk warehouse',
'enabled'=>
'isModEnabled("stock")',
'visible'=>-1,
'position'=>191),
347 'fk_availability' =>array(
'type'=>
'integer',
'label'=>
'Availability',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
348 'fk_delivery_address' =>array(
'type'=>
'integer',
'label'=>
'DeliveryAddress',
'enabled'=>1,
'visible'=>0,
'position'=>200),
349 'fk_input_reason' =>array(
'type'=>
'integer',
'label'=>
'InputReason',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
350 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>215),
351 'fk_incoterms' =>array(
'type'=>
'integer',
'label'=>
'IncotermCode',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>220),
352 'location_incoterms' =>array(
'type'=>
'varchar(255)',
'label'=>
'IncotermLabel',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>225),
353 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'MulticurrencyID',
'enabled'=>1,
'visible'=>-1,
'position'=>230),
354 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'MulticurrencyCurrency',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>235),
355 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyRate',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>240,
'isameasure'=>1),
356 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountHT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>245,
'isameasure'=>1),
357 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountVAT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>250,
'isameasure'=>1),
358 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountTTC',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>255,
'isameasure'=>1),
359 'last_main_doc' =>array(
'type'=>
'varchar(255)',
'label'=>
'LastMainDoc',
'enabled'=>1,
'visible'=>-1,
'position'=>260),
360 'fk_statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Status',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
361 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>900),
396 global $conf, $langs;
400 $this->socid = $socid;
401 $this->
id = $propalid;
403 $this->duree_validite =
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
419 public function add_product($idproduct, $qty, $remise_percent = 0)
422 global $conf, $mysoc;
428 dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
429 if ($idproduct > 0) {
430 $prod =
new Product($this->db);
431 $prod->fetch($idproduct);
433 $productdesc = $prod->description;
437 if (empty($tva_tx)) {
442 $localtax1_tx =
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
443 $localtax2_tx =
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
446 if ($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
447 $price = $prod->multiprices[$this->thirdparty->price_level];
454 $line->fk_product = $idproduct;
455 $line->desc = $productdesc;
458 $line->remise_percent = $remise_percent;
459 $line->vat_src_code = $vat_src_code;
460 $line->tva_tx = $tva_tx;
461 $line->fk_unit = $prod->fk_unit;
463 $line->info_bits = 1;
466 $this->lines[] = $line;
484 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
485 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
490 $result = $remise->fetch($idremise);
493 if ($remise->fk_facture) {
494 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
495 $this->db->rollback();
501 $this->line->context = $this->context;
503 $line->fk_propal = $this->id;
504 $line->fk_remise_except = $remise->id;
505 $line->desc = $remise->description;
506 $line->vat_src_code = $remise->vat_src_code;
507 $line->tva_tx = $remise->tva_tx;
508 $line->subprice = -$remise->amount_ht;
509 $line->fk_product = 0;
511 $line->remise_percent = 0;
513 $line->info_bits = 2;
516 $line->price = -$remise->amount_ht;
518 $line->total_ht = -$remise->amount_ht;
519 $line->total_tva = -$remise->amount_tva;
520 $line->total_ttc = -$remise->amount_ttc;
522 $result = $line->insert();
529 $this->db->rollback();
533 $this->error = $line->error;
534 $this->errors = $line->errors;
535 $this->db->rollback();
539 $this->db->rollback();
581 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)
583 global $mysoc, $conf, $langs;
585 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);
587 if ($this->
statut == self::STATUS_DRAFT) {
588 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
591 if (empty($remise_percent)) {
597 if (empty($info_bits)) {
603 if (empty($fk_parent_line) || $fk_parent_line < 0) {
607 $remise_percent =
price2num($remise_percent);
610 $pu_ht_devise =
price2num($pu_ht_devise);
612 if (!preg_match(
'/\((.*)\)/', $txtva)) {
618 if ($price_base_type ==
'HT') {
629 if ($date_start && $date_end && $date_start > $date_end) {
630 $langs->load(
"errors");
631 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
637 $product_type = $type;
638 if (!empty($fk_product) && $fk_product > 0) {
639 $product =
new Product($this->db);
640 $result = $product->fetch($fk_product);
641 $product_type = $product->type;
643 if (
getDolGlobalString(
'STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL') && $product_type == 0 && $product->stock_reel < $qty) {
644 $langs->load(
"errors");
645 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
646 $this->db->rollback();
662 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
663 $vat_src_code = $reg[1];
664 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
667 $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);
669 $total_ht = $tabprice[0];
670 $total_tva = $tabprice[1];
671 $total_ttc = $tabprice[2];
672 $total_localtax1 = $tabprice[9];
673 $total_localtax2 = $tabprice[10];
674 $pu_ht = $tabprice[3];
675 $pu_tva = $tabprice[4];
676 $pu_ttc = $tabprice[5];
679 $multicurrency_total_ht = $tabprice[16];
680 $multicurrency_total_tva = $tabprice[17];
681 $multicurrency_total_ttc = $tabprice[18];
682 $pu_ht_devise = $tabprice[19];
686 if ($ranktouse == -1) {
687 $rangmax = $this->
line_max($fk_parent_line);
688 $ranktouse = $rangmax + 1;
695 if ($remise_percent > 0) {
696 $remise = round(($pu * $remise_percent / 100), 2);
703 $this->line->context = $this->context;
705 $this->line->fk_propal = $this->id;
706 $this->line->label = $label;
707 $this->line->desc = $desc;
708 $this->line->qty = $qty;
710 $this->line->vat_src_code = $vat_src_code;
711 $this->line->tva_tx = $txtva;
712 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
713 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
714 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
715 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
716 $this->line->fk_product = $fk_product;
717 $this->line->product_type = $type;
718 $this->line->fk_remise_except = $fk_remise_except;
719 $this->line->remise_percent = $remise_percent;
720 $this->line->subprice = $pu_ht;
721 $this->line->rang = $ranktouse;
722 $this->line->info_bits = $info_bits;
723 $this->line->total_ht = $total_ht;
724 $this->line->total_tva = $total_tva;
725 $this->line->total_localtax1 = $total_localtax1;
726 $this->line->total_localtax2 = $total_localtax2;
727 $this->line->total_ttc = $total_ttc;
728 $this->line->special_code = $special_code;
729 $this->line->fk_parent_line = $fk_parent_line;
730 $this->line->fk_unit = $fk_unit;
732 $this->line->date_start = $date_start;
733 $this->line->date_end = $date_end;
735 $this->line->fk_fournprice = $fk_fournprice;
736 $this->line->pa_ht = $pa_ht;
738 $this->line->origin_id = $origin_id;
739 $this->line->origin = $origin;
742 $this->line->fk_multicurrency = $this->fk_multicurrency;
743 $this->line->multicurrency_code = $this->multicurrency_code;
744 $this->line->multicurrency_subprice = $pu_ht_devise;
745 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
746 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
747 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
750 if (empty($qty) && empty($special_code)) {
751 $this->line->special_code = 3;
755 $this->line->price =
$price;
757 if (is_array($array_options) && count($array_options) > 0) {
758 $this->line->array_options = $array_options;
761 $result = $this->line->insert();
764 if (!empty($fk_parent_line)) {
766 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
767 $linecount = count($this->lines);
768 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
774 if (empty($noupdateafterinsertline)) {
780 return $this->line->id;
782 $this->error = $this->db->error();
783 $this->db->rollback();
787 $this->error = $this->line->error;
788 $this->errors = $this->line->errors;
789 $this->db->rollback();
793 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
828 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)
830 global $mysoc, $langs;
832 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
833 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");
834 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
837 $remise_percent =
price2num($remise_percent);
840 $pu_ht_devise =
price2num($pu_ht_devise);
841 if (!preg_match(
'/\((.*)\)/', $txtva)) {
847 if (empty($qty) && empty($special_code)) {
850 if (!empty($qty) && $special_code == 3) {
857 if ($date_start && $date_end && $date_start > $date_end) {
858 $langs->load(
"errors");
859 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
863 if ($this->
statut == self::STATUS_DRAFT) {
876 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
877 $vat_src_code = $reg[1];
878 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
883 $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);
884 $total_ht = $tabprice[0];
885 $total_tva = $tabprice[1];
886 $total_ttc = $tabprice[2];
887 $total_localtax1 = $tabprice[9];
888 $total_localtax2 = $tabprice[10];
889 $pu_ht = $tabprice[3];
890 $pu_tva = $tabprice[4];
891 $pu_ttc = $tabprice[5];
894 $multicurrency_total_ht = $tabprice[16];
895 $multicurrency_total_tva = $tabprice[17];
896 $multicurrency_total_ttc = $tabprice[18];
897 $pu_ht_devise = $tabprice[19];
902 if ($remise_percent > 0) {
903 $remise = round(($pu * $remise_percent / 100), 2);
909 $line->fetch($rowid);
911 $staticline = clone $line;
913 $line->oldline = $staticline;
915 $this->line->context = $this->context;
916 $this->line->rang = $rang;
919 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
920 $rangmax = $this->
line_max($fk_parent_line);
921 $this->line->rang = $rangmax + 1;
924 $this->line->id = $rowid;
925 $this->line->label = $label;
926 $this->line->desc = $desc;
927 $this->line->qty = $qty;
928 $this->line->product_type = $type;
929 $this->line->vat_src_code = $vat_src_code;
930 $this->line->tva_tx = $txtva;
931 $this->line->localtax1_tx = $txlocaltax1;
932 $this->line->localtax2_tx = $txlocaltax2;
933 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
934 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
935 $this->line->remise_percent = $remise_percent;
936 $this->line->subprice = $pu_ht;
937 $this->line->info_bits = $info_bits;
939 $this->line->total_ht = $total_ht;
940 $this->line->total_tva = $total_tva;
941 $this->line->total_localtax1 = $total_localtax1;
942 $this->line->total_localtax2 = $total_localtax2;
943 $this->line->total_ttc = $total_ttc;
944 $this->line->special_code = $special_code;
945 $this->line->fk_parent_line = $fk_parent_line;
946 $this->line->skip_update_total = $skip_update_total;
947 $this->line->fk_unit = $fk_unit;
949 $this->line->fk_fournprice = $fk_fournprice;
950 $this->line->pa_ht = $pa_ht;
952 $this->line->date_start = $date_start;
953 $this->line->date_end = $date_end;
955 if (is_array($array_options) && count($array_options) > 0) {
957 foreach ($array_options as $key => $value) {
958 $this->line->array_options[$key] = $array_options[$key];
963 $this->line->multicurrency_subprice = $pu_ht_devise;
964 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
965 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
966 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
968 $result = $this->line->update($notrigger);
971 if (!empty($fk_parent_line)) {
984 $this->error = $this->line->error;
985 $this->errors = $this->line->errors;
986 $this->db->rollback();
990 dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
1007 if ($this->
statut == self::STATUS_DRAFT) {
1012 $line->context = $this->context;
1015 $line->fetch($lineid);
1017 if ($id > 0 && $line->fk_propal != $id) {
1018 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
1023 $staticline = clone $line;
1024 $line->oldline = $staticline;
1026 if ($line->delete($user) > 0) {
1029 $this->db->commit();
1032 $this->error = $line->error;
1033 $this->errors = $line->errors;
1034 $this->db->rollback();
1038 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1052 public function create($user, $notrigger = 0)
1054 global $conf, $hookmanager, $mysoc;
1060 if (empty($this->date)) {
1063 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1064 if (empty($this->availability_id)) {
1065 $this->availability_id = 0;
1067 if (empty($this->demand_reason_id)) {
1068 $this->demand_reason_id = 0;
1072 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1077 if (empty($this->fk_multicurrency)) {
1078 $this->multicurrency_code = $conf->currency;
1079 $this->fk_multicurrency = 0;
1080 $this->multicurrency_tx = 1;
1084 $delivery_date = $this->delivery_date;
1091 $this->error =
"Failed to fetch company";
1092 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1097 if (!empty($this->
ref)) {
1100 $this->error =
'ErrorRefAlreadyExists';
1101 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1102 $this->db->rollback();
1107 if (empty($this->date)) {
1108 $this->error =
"Date of proposal is required";
1109 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1117 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
1120 $sql .=
", total_tva";
1121 $sql .=
", total_ttc";
1125 $sql .=
", fk_user_author";
1126 $sql .=
", note_private";
1127 $sql .=
", note_public";
1128 $sql .=
", model_pdf";
1129 $sql .=
", fin_validite";
1130 $sql .=
", fk_cond_reglement";
1131 $sql .=
", deposit_percent";
1132 $sql .=
", fk_mode_reglement";
1133 $sql .=
", fk_account";
1134 $sql .=
", ref_client";
1135 $sql .=
", ref_ext";
1136 $sql .=
", date_livraison";
1137 $sql .=
", fk_shipping_method";
1138 $sql .=
", fk_warehouse";
1139 $sql .=
", fk_availability";
1140 $sql .=
", fk_input_reason";
1141 $sql .=
", fk_projet";
1142 $sql .=
", fk_incoterms";
1143 $sql .=
", location_incoterms";
1145 $sql .=
", fk_multicurrency";
1146 $sql .=
", multicurrency_code";
1147 $sql .=
", multicurrency_tx";
1149 $sql .=
" VALUES (";
1150 $sql .= $this->socid;
1154 $sql .=
", '".$this->db->idate($this->date).
"'";
1155 $sql .=
", '".$this->db->idate($now).
"'";
1156 $sql .=
", '(PROV)'";
1157 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1158 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1159 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1160 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1161 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1162 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1163 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1164 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1165 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1166 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1167 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1168 $sql .=
", ".(empty($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1169 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1170 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1171 $sql .=
", ".$this->availability_id;
1172 $sql .=
", ".$this->demand_reason_id;
1173 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1174 $sql .=
", ".(int) $this->fk_incoterms;
1175 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1176 $sql .=
", ".setEntity($this);
1177 $sql .=
", ".(int) $this->fk_multicurrency;
1178 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1179 $sql .=
", ".(float) $this->multicurrency_tx;
1182 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1183 $resql = $this->db->query($sql);
1185 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1188 $this->
ref =
'(PROV'.$this->id.
')';
1189 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1191 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1192 $resql = $this->db->query($sql);
1197 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1198 $this->linked_objects = $this->linkedObjectsIds;
1202 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1203 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1204 if (is_array($tmp_origin_id)) {
1205 foreach ($tmp_origin_id as $origin_id) {
1208 $this->error = $this->db->lasterror();
1213 $origin_id = $tmp_origin_id;
1216 $this->error = $this->db->lasterror();
1228 $fk_parent_line = 0;
1229 $num = count($this->lines);
1231 for ($i = 0; $i < $num; $i++) {
1232 if (!is_object($this->lines[$i])) {
1234 $line = (object) $this->lines[$i];
1236 $line = $this->lines[$i];
1239 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1240 $fk_parent_line = 0;
1243 $vatrate = $line->tva_tx;
1244 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1245 $vatrate .=
' ('.$line->vat_src_code.
')';
1249 $originid = $line->origin_id;
1250 $origintype = $line->origin;
1252 $originid = $line->id;
1253 $origintype = $this->element;
1261 $line->localtax1_tx,
1262 $line->localtax2_tx,
1264 $line->remise_percent,
1268 $line->product_type,
1270 $line->special_code,
1272 $line->fk_fournprice,
1277 $line->array_options,
1288 $this->error = $this->db->error;
1294 $line->id = $result;
1297 if ($result > 0 && $line->product_type == 9) {
1298 $fk_parent_line = $result;
1328 if (!$error && !$notrigger) {
1337 $this->error = $this->db->lasterror();
1342 $this->error = $this->db->lasterror();
1347 $this->db->commit();
1348 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1351 $this->db->rollback();
1355 $this->error = $this->db->lasterror();
1356 $this->db->rollback();
1371 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1373 global $conf, $hookmanager, $mysoc;
1382 $object =
new self($this->db);
1387 $object->fetch($this->
id);
1389 $objsoc =
new Societe($this->db);
1392 if (!empty($socid) && $socid != $object->socid) {
1393 if ($objsoc->fetch($socid) > 0) {
1394 $object->socid = $objsoc->id;
1395 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1396 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1397 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1398 $object->fk_delivery_address =
'';
1410 $object->fk_project =
'';
1415 $object->ref_client =
'';
1420 $objsoc->fetch($object->socid);
1424 if ($update_prices ===
true || $update_desc ===
true) {
1425 if ($objsoc->id > 0 && !empty($object->lines)) {
1428 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1431 foreach ($object->lines as $line) {
1434 if ($line->fk_product > 0) {
1435 $prod =
new Product($this->db);
1436 $res = $prod->fetch($line->fk_product);
1438 if ($update_prices ===
true) {
1439 $pu_ht = $prod->price;
1441 $remise_percent = $objsoc->remise_percent;
1444 $pu_ht = $prod->multiprices[$objsoc->price_level];
1446 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1447 $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
1452 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1453 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1456 if (count($prodcustprice->lines) > 0) {
1457 $pu_ht =
price($prodcustprice->lines[0]->price);
1458 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1459 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1460 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1466 $line->subprice = $pu_ht;
1467 $line->tva_tx = $tva_tx;
1468 $line->remise_percent = $remise_percent;
1470 if ($update_desc ===
true) {
1471 $line->desc = $prod->description;
1481 $object->entity = (!empty($forceentity) ? $forceentity : $object->entity);
1485 $object->user_author = $user->id;
1486 $object->user_validation_id = 0;
1487 $object->date = $now;
1488 $object->datep = $now;
1489 $object->fin_validite = $object->date + ($object->duree_validite * 24 * 3600);
1491 $object->ref_client =
'';
1494 $object->note_private =
'';
1495 $object->note_public =
'';
1498 $object->context[
'createfromclone'] =
'createfromclone';
1499 $result = $object->create($user);
1501 $this->error = $object->error;
1502 $this->errors = array_merge($this->errors, $object->errors);
1508 if ($object->copy_linked_contact($this,
'internal') < 0) {
1515 if ($this->socid == $object->socid) {
1516 if ($object->copy_linked_contact($this,
'external') < 0) {
1524 if (is_object($hookmanager)) {
1525 $parameters = array(
'objFrom'=>$this,
'clonedObj'=>$object);
1527 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1535 unset($object->context[
'createfromclone']);
1539 $this->db->commit();
1542 $this->db->rollback();
1556 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1558 $sql =
"SELECT p.rowid, p.ref, p.entity, p.fk_soc";
1559 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1560 $sql .=
", p.datec";
1561 $sql .=
", p.date_signature as dates";
1562 $sql .=
", p.date_valid as datev";
1563 $sql .=
", p.datep as dp";
1564 $sql .=
", p.fin_validite as dfv";
1565 $sql .=
", p.date_livraison as delivery_date";
1566 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1567 $sql .=
", p.note_private, p.note_public";
1568 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1569 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1570 $sql .=
", p.fk_delivery_address";
1571 $sql .=
", p.fk_availability";
1572 $sql .=
", p.fk_input_reason";
1573 $sql .=
", p.fk_cond_reglement";
1574 $sql .=
", p.fk_mode_reglement";
1575 $sql .=
', p.fk_account';
1576 $sql .=
", p.fk_shipping_method";
1577 $sql .=
", p.fk_warehouse";
1578 $sql .=
", p.fk_incoterms, p.location_incoterms";
1579 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1580 $sql .=
", p.tms as date_modification";
1581 $sql .=
", i.libelle as label_incoterms";
1582 $sql .=
", c.label as statut_label";
1583 $sql .=
", ca.code as availability_code, ca.label as availability";
1584 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1585 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1586 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1587 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1588 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1589 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1590 $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').
')';
1591 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1592 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1593 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1596 if (!empty($forceentity)) {
1597 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1599 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1601 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1604 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1607 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1608 $resql = $this->db->query($sql);
1610 if ($this->db->num_rows($resql)) {
1611 $obj = $this->db->fetch_object($resql);
1613 $this->
id = $obj->rowid;
1614 $this->entity = $obj->entity;
1616 $this->
ref = $obj->ref;
1617 $this->ref_client = $obj->ref_client;
1618 $this->ref_customer = $obj->ref_client;
1619 $this->ref_ext = $obj->ref_ext;
1621 $this->total = $obj->total_ttc;
1622 $this->total_ttc = $obj->total_ttc;
1623 $this->total_ht = $obj->total_ht;
1624 $this->total_tva = $obj->total_tva;
1625 $this->total_localtax1 = $obj->localtax1;
1626 $this->total_localtax2 = $obj->localtax2;
1628 $this->socid = $obj->fk_soc;
1629 $this->thirdparty =
null;
1631 $this->fk_project = $obj->fk_project;
1632 $this->project =
null;
1634 $this->model_pdf = $obj->model_pdf;
1635 $this->last_main_doc = $obj->last_main_doc;
1636 $this->note = $obj->note_private;
1637 $this->note_private = $obj->note_private;
1638 $this->note_public = $obj->note_public;
1640 $this->
status = (int) $obj->fk_statut;
1641 $this->
statut = $this->status;
1643 $this->datec = $this->db->jdate($obj->datec);
1644 $this->datev = $this->db->jdate($obj->datev);
1645 $this->date_creation = $this->db->jdate($obj->datec);
1646 $this->date_validation = $this->db->jdate($obj->datev);
1647 $this->date_modification = $this->db->jdate($obj->date_modification);
1648 $this->date_signature = $this->db->jdate($obj->dates);
1649 $this->date = $this->db->jdate($obj->dp);
1650 $this->datep = $this->db->jdate($obj->dp);
1651 $this->fin_validite = $this->db->jdate($obj->dfv);
1652 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1653 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1654 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1655 $this->availability_id = $obj->fk_availability;
1656 $this->availability_code = $obj->availability_code;
1658 $this->demand_reason_id = $obj->fk_input_reason;
1659 $this->demand_reason_code = $obj->demand_reason_code;
1661 $this->fk_address = $obj->fk_delivery_address;
1663 $this->mode_reglement_id = $obj->fk_mode_reglement;
1664 $this->mode_reglement_code = $obj->mode_reglement_code;
1665 $this->mode_reglement = $obj->mode_reglement;
1666 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1667 $this->cond_reglement_id = $obj->fk_cond_reglement;
1668 $this->cond_reglement_code = $obj->cond_reglement_code;
1669 $this->cond_reglement = $obj->cond_reglement;
1670 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1671 $this->deposit_percent = $obj->deposit_percent;
1673 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1675 $this->user_author_id = $obj->fk_user_author;
1676 $this->user_validation_id = $obj->fk_user_valid;
1677 $this->user_closing_id = $obj->fk_user_cloture;
1680 $this->fk_incoterms = $obj->fk_incoterms;
1681 $this->location_incoterms = $obj->location_incoterms;
1682 $this->label_incoterms = $obj->label_incoterms;
1685 $this->fk_multicurrency = $obj->fk_multicurrency;
1686 $this->multicurrency_code = $obj->multicurrency_code;
1687 $this->multicurrency_tx = $obj->multicurrency_tx;
1688 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1689 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1690 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1696 $this->db->free($resql);
1698 $this->lines = array();
1709 $this->error =
"Record Not Found";
1712 $this->error = $this->db->lasterror();
1731 if (isset($this->
ref)) {
1732 $this->
ref = trim($this->
ref);
1734 if (isset($this->ref_client)) {
1735 $this->ref_client = trim($this->ref_client);
1737 if (isset($this->note) || isset($this->note_private)) {
1738 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1740 if (isset($this->note_public)) {
1741 $this->note_public = trim($this->note_public);
1743 if (isset($this->model_pdf)) {
1744 $this->model_pdf = trim($this->model_pdf);
1746 if (isset($this->import_key)) {
1747 $this->import_key = trim($this->import_key);
1749 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1750 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1757 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1758 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1759 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1760 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1761 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1762 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1763 if (!empty($this->fin_validite)) {
1764 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1766 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1767 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1768 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1769 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1770 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1771 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1772 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->
statut :
"null").
",";
1773 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1774 $sql .=
" fk_user_valid = ".(!empty($this->user_validation_id) ? (int) $this->user_validation_id :
"null").
",";
1775 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1776 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1777 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1778 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1779 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1780 $sql .=
" fk_shipping_method=".(isset($this->shipping_method_id) ? (int) $this->shipping_method_id :
"null").
",";
1781 $sql .=
" fk_availability=".(isset($this->availability_id) ? (int) $this->availability_id :
"null").
",";
1782 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1783 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1784 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1785 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1786 $sql .=
" WHERE rowid=".((int) $this->
id);
1790 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1791 $resql = $this->db->query($sql);
1794 $this->errors[] =
"Error ".$this->db->lasterror();
1804 if (!$error && !$notrigger) {
1815 foreach ($this->errors as $errmsg) {
1816 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1817 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1819 $this->db->rollback();
1822 $this->db->commit();
1837 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $sqlforgedfilters =
'')
1840 $this->lines = array();
1842 $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,';
1843 $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,';
1844 $sql .=
' d.fk_unit,';
1845 $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,';
1846 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1847 $sql .=
' d.date_start, d.date_end,';
1848 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1849 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1850 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1851 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1852 if ($only_product) {
1853 $sql .=
' AND p.fk_product_type = 0';
1855 if ($sqlforgedfilters) {
1856 $sql .= $sqlforgedfilters;
1858 $sql .=
' ORDER by d.rang';
1860 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1861 $result = $this->db->query($sql);
1863 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1865 $num = $this->db->num_rows($result);
1869 $objp = $this->db->fetch_object($result);
1873 $line->rowid = $objp->rowid;
1874 $line->id = $objp->rowid;
1875 $line->fk_propal = $objp->fk_propal;
1876 $line->fk_parent_line = $objp->fk_parent_line;
1877 $line->product_type = $objp->product_type;
1878 $line->label = $objp->custom_label;
1879 $line->desc = $objp->description;
1880 $line->description = $objp->description;
1881 $line->qty = $objp->qty;
1882 $line->vat_src_code = $objp->vat_src_code;
1883 $line->tva_tx = $objp->tva_tx;
1884 $line->localtax1_tx = $objp->localtax1_tx;
1885 $line->localtax2_tx = $objp->localtax2_tx;
1886 $line->localtax1_type = $objp->localtax1_type;
1887 $line->localtax2_type = $objp->localtax2_type;
1888 $line->subprice = $objp->subprice;
1889 $line->fk_remise_except = $objp->fk_remise_except;
1890 $line->remise_percent = $objp->remise_percent;
1891 $line->price = $objp->price;
1893 $line->info_bits = $objp->info_bits;
1894 $line->total_ht = $objp->total_ht;
1895 $line->total_tva = $objp->total_tva;
1896 $line->total_localtax1 = $objp->total_localtax1;
1897 $line->total_localtax2 = $objp->total_localtax2;
1898 $line->total_ttc = $objp->total_ttc;
1899 $line->fk_fournprice = $objp->fk_fournprice;
1900 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1901 $line->pa_ht = $marginInfos[0];
1902 $line->marge_tx = $marginInfos[1];
1903 $line->marque_tx = $marginInfos[2];
1904 $line->special_code = $objp->special_code;
1905 $line->rang = $objp->rang;
1907 $line->fk_product = $objp->fk_product;
1909 $line->ref = $objp->product_ref;
1910 $line->libelle = $objp->product_label;
1912 $line->product_ref = $objp->product_ref;
1913 $line->product_label = $objp->product_label;
1914 $line->product_desc = $objp->product_desc;
1915 $line->product_tobatch = $objp->product_tobatch;
1916 $line->product_barcode = $objp->product_barcode;
1918 $line->fk_product_type = $objp->fk_product_type;
1919 $line->fk_unit = $objp->fk_unit;
1920 $line->weight = $objp->weight;
1921 $line->weight_units = $objp->weight_units;
1922 $line->volume = $objp->volume;
1923 $line->volume_units = $objp->volume_units;
1925 $line->date_start = $this->db->jdate($objp->date_start);
1926 $line->date_end = $this->db->jdate($objp->date_end);
1929 $line->fk_multicurrency = $objp->fk_multicurrency;
1930 $line->multicurrency_code = $objp->multicurrency_code;
1931 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1932 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1933 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1934 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1936 $line->fetch_optionals();
1939 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1940 $tmpproduct =
new Product($this->db);
1941 $tmpproduct->fetch($objp->fk_product);
1942 $tmpproduct->getMultiLangs();
1944 $line->multilangs = $tmpproduct->multilangs;
1947 $this->lines[$i] = $line;
1952 $this->db->free($result);
1956 $this->error = $this->db->lasterror();
1968 public function valid($user, $notrigger = 0)
1972 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1977 if ($this->
statut == self::STATUS_VALIDATED) {
1978 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1982 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'creer'))
1983 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'propal_advance',
'validate')))) {
1984 $this->error =
'ErrorPermissionDenied';
1985 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
1994 $soc =
new Societe($this->db);
1995 $soc->fetch($this->socid);
1998 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2005 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2006 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2007 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2010 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2011 $resql = $this->db->query($sql);
2018 if (!$error && !$notrigger) {
2020 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2028 $this->oldref = $this->ref;
2031 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2033 $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).
"'";
2034 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2035 $resql = $this->db->query($sql);
2038 $this->error = $this->db->lasterror();
2040 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2041 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2042 $resql = $this->db->query($sql);
2045 $this->error = $this->db->lasterror();
2051 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2052 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2053 if (!$error && file_exists($dirsource)) {
2054 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2055 if (@rename($dirsource, $dirdest)) {
2058 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2059 foreach ($listoffiles as $fileentry) {
2060 $dirsource = $fileentry[
'name'];
2061 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2062 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2063 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2064 @rename($dirsource, $dirdest);
2072 $this->user_validation_id = $user->id;
2073 $this->datev = $now;
2074 $this->date_validation = $now;
2076 $this->db->commit();
2079 $this->db->rollback();
2098 $this->error =
'ErrorBadParameter';
2099 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2103 if ($user->hasRight(
'propal',
'creer')) {
2108 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2109 $sql .=
" WHERE rowid = ".((int) $this->
id);
2112 $resql = $this->db->query($sql);
2114 $this->errors[] = $this->db->error();
2119 $this->oldcopy = clone $this;
2120 $this->date = $date;
2121 $this->datep = $date;
2124 if (!$notrigger && empty($error)) {
2134 $this->db->commit();
2137 foreach ($this->errors as $errmsg) {
2138 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2139 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2141 $this->db->rollback();
2161 if ($user->hasRight(
'propal',
'creer')) {
2166 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2167 $sql .=
" WHERE rowid = ".((int) $this->
id);
2171 $resql = $this->db->query($sql);
2173 $this->errors[] = $this->db->error();
2179 $this->oldcopy = clone $this;
2180 $this->fin_validite = $date_end_validity;
2183 if (!$notrigger && empty($error)) {
2193 $this->db->commit();
2196 foreach ($this->errors as $errmsg) {
2197 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2198 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2200 $this->db->rollback();
2234 if ($user->hasRight(
'propal',
'creer')) {
2239 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2240 $sql .=
" SET date_livraison = ".($delivery_date !=
'' ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2241 $sql .=
" WHERE rowid = ".((int) $this->
id);
2244 $resql = $this->db->query($sql);
2246 $this->errors[] = $this->db->error();
2251 $this->oldcopy = clone $this;
2252 $this->delivery_date = $delivery_date;
2255 if (!$notrigger && empty($error)) {
2265 $this->db->commit();
2268 foreach ($this->errors as $errmsg) {
2269 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2270 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2272 $this->db->rollback();
2292 if ($user->hasRight(
'propal',
'creer') && $this->statut >= self::STATUS_DRAFT) {
2297 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2298 $sql .=
" SET fk_availability = ".((int) $id);
2299 $sql .=
" WHERE rowid = ".((int) $this->
id);
2301 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2302 $resql = $this->db->query($sql);
2304 $this->errors[] = $this->db->error();
2309 $this->oldcopy = clone $this;
2310 $this->fk_availability = $id;
2311 $this->availability_id = $id;
2314 if (!$notrigger && empty($error)) {
2324 $this->db->commit();
2327 foreach ($this->errors as $errmsg) {
2328 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2329 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2331 $this->db->rollback();
2335 $error_str =
'Propal status do not meet requirement '.$this->statut;
2337 $this->error = $error_str;
2338 $this->errors[] = $this->error;
2355 if ($user->hasRight(
'propal',
'creer') && $this->statut >= self::STATUS_DRAFT) {
2360 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2361 $sql .=
" SET fk_input_reason = ".((int) $id);
2362 $sql .=
" WHERE rowid = ".((int) $this->
id);
2365 $resql = $this->db->query($sql);
2367 $this->errors[] = $this->db->error();
2373 $this->oldcopy = clone $this;
2375 $this->demand_reason_id = $id;
2379 if (!$notrigger && empty($error)) {
2389 $this->db->commit();
2392 foreach ($this->errors as $errmsg) {
2393 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2394 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2396 $this->db->rollback();
2400 $error_str =
'Propal status do not meet requirement '.$this->statut;
2402 $this->error = $error_str;
2403 $this->errors[] = $this->error;
2420 if ($user->hasRight(
'propal',
'creer')) {
2425 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2426 $sql .=
" WHERE rowid = ".((int) $this->
id);
2428 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2429 $resql = $this->db->query($sql);
2431 $this->errors[] = $this->db->error();
2436 $this->oldcopy = clone $this;
2437 $this->ref_client = $ref_client;
2440 if (!$notrigger && empty($error)) {
2450 $this->db->commit();
2453 foreach ($this->errors as $errmsg) {
2454 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2455 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2457 $this->db->rollback();
2609 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2610 $sql .=
" SET fk_statut = ".((int) $status).
",";
2611 if (!empty(
$note)) {
2612 $sql .=
" note_private = '".$this->db->escape(
$note).
"',";
2614 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2615 $sql .=
" WHERE rowid = ".((int) $this->
id);
2619 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2620 $resql = $this->db->query($sql);
2623 $this->errors[] =
"Error ".$this->db->lasterror();
2638 if (!empty($this->errors)) {
2639 foreach ($this->errors as $errmsg) {
2640 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2641 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2644 $this->db->rollback();
2650 $this->db->commit();
2666 global $langs,$conf;
2676 $date_signature = $now;
2677 $fk_user_signature = $user->id;
2679 $this->
info($this->
id);
2680 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2681 $date_signature = $now;
2682 $fk_user_signature = $user->id;
2684 $date_signature = $this->date_signature;
2685 $fk_user_signature = $this->user_signature->id;
2689 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2690 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"'";
2691 if ($status == self::STATUS_SIGNED) {
2692 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2694 $sql .=
" WHERE rowid = ".((int) $this->
id);
2696 $resql = $this->db->query($sql);
2699 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_CLOSED') ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2700 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2702 if ($status == self::STATUS_SIGNED) {
2703 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2704 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_TOBILL') ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2708 $soc->id = $this->socid;
2709 $result = $soc->setAsCustomer();
2712 $this->error=$this->db->lasterror();
2713 $this->db->rollback();
2720 $outputlangs = $langs;
2722 $outputlangs =
new Translate(
"", $conf);
2723 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2724 $outputlangs->setDefaultLang($newlang);
2733 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2737 $this->oldcopy= clone $this;
2740 $this->date_signature = $date_signature;
2741 $this->note_private = $newprivatenote;
2744 if (!$notrigger && empty($error)) {
2754 $this->db->commit();
2757 $this->
statut = $this->oldcopy->statut;
2758 $this->
status = $this->oldcopy->statut;
2759 $this->date_signature = $this->oldcopy->date_signature;
2760 $this->note_private = $this->oldcopy->note_private;
2762 $this->db->rollback();
2766 $this->error = $this->db->lasterror();
2767 $this->db->rollback();
2782 global $conf, $langs;
2789 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2795 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2796 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2797 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2800 $resql = $this->db->query($sql);
2802 $this->errors[] = $this->db->error();
2805 $num = $this->db->affected_rows($resql);
2809 $modelpdf = $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2813 $outputlangs = $langs;
2815 $outputlangs =
new Translate(
"", $conf);
2816 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2817 $outputlangs->setDefaultLang($newlang);
2826 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2829 $this->oldcopy = clone $this;
2831 $this->date_cloture = $now;
2832 $this->note_private = $newprivatenote;
2835 if (!$notrigger && empty($error)) {
2845 $this->db->commit();
2848 foreach ($this->errors as $errmsg) {
2849 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2850 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2852 $this->db->rollback();
2871 if ($this->
statut <= self::STATUS_DRAFT) {
2875 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2879 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2880 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2881 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2882 $sql .=
" WHERE rowid = ".((int) $this->
id);
2884 $resql = $this->db->query($sql);
2886 $this->errors[] = $this->db->error();
2891 $this->oldcopy = clone $this;
2894 if (!$notrigger && empty($error)) {
2907 $this->db->commit();
2910 foreach ($this->errors as $errmsg) {
2911 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2912 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2914 $this->db->rollback();
2934 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2941 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2942 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2943 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2944 if (!$user->hasRight(
'societe',
'client',
'voir') && !$socid) {
2945 $sql .=
", sc.fk_soc, sc.fk_user";
2947 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2948 if (!$user->hasRight(
'societe',
'client',
'voir') && !$socid) {
2949 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
2951 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2952 $sql .=
" AND p.fk_soc = s.rowid";
2953 $sql .=
" AND p.fk_statut = c.id";
2954 if (!$user->hasRight(
'societe',
'client',
'voir') && !$socid) {
2955 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
2958 $sql .=
" AND s.rowid = ".((int) $socid);
2961 $sql .=
" AND p.fk_statut = ".self::STATUS_DRAFT;
2963 if ($notcurrentuser > 0) {
2964 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2966 $sql .= $this->db->order($sortfield, $sortorder);
2967 $sql .= $this->db->plimit($limit, $offset);
2969 $result = $this->db->query($sql);
2971 $num = $this->db->num_rows($result);
2975 $obj = $this->db->fetch_object($result);
2977 if ($shortlist == 1) {
2978 $ga[$obj->propalid] = $obj->ref;
2979 } elseif ($shortlist == 2) {
2980 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2982 $ga[$i][
'id'] = $obj->propalid;
2983 $ga[$i][
'ref'] = $obj->ref;
2984 $ga[$i][
'name'] = $obj->name;
3018 $linkedInvoices = array();
3021 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
3024 foreach ($objectid as $key => $object) {
3026 if ($objecttype ==
'facture') {
3027 $linkedInvoices[] = $object;
3031 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
3032 foreach ($subobjectid as $subkey => $subobject) {
3033 if ($subobjecttype ==
'facture') {
3034 $linkedInvoices[] = $subobject;
3042 if (count($linkedInvoices) > 0) {
3043 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
3044 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
3045 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
3047 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
3048 $resql = $this->db->query($sql);
3051 $tab_sqlobj = array();
3052 $nump = $this->db->num_rows($resql);
3053 for ($i = 0; $i < $nump; $i++) {
3054 $sqlobj = $this->db->fetch_object($resql);
3055 $tab_sqlobj[] = $sqlobj;
3057 $this->db->free($resql);
3059 $nump = count($tab_sqlobj);
3063 while ($i < $nump) {
3064 $obj = array_shift($tab_sqlobj);
3087 public function delete($user, $notrigger = 0)
3090 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3106 if (!$error && !empty($this->table_element_line)) {
3107 $tabletodelete = $this->table_element_line;
3108 $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).
")";
3109 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3110 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3112 $this->error = $this->db->lasterror();
3113 $this->errors[] = $this->error;
3114 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3139 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3145 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3146 $res = $this->db->query($sql);
3149 $this->error = $this->db->lasterror();
3150 $this->errors[] = $this->error;
3151 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3167 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3168 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3169 $file = $dir.
"/".$ref.
".pdf";
3170 if (file_exists($file)) {
3174 $this->error =
'ErrorFailToDeleteFile';
3175 $this->errors[] = $this->error;
3176 $this->db->rollback();
3180 if (file_exists($dir)) {
3183 $this->error =
'ErrorFailToDeleteDir';
3184 $this->errors[] = $this->error;
3185 $this->db->rollback();
3193 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3194 $this->db->commit();
3197 $this->db->rollback();
3214 if ($this->
statut >= self::STATUS_DRAFT) {
3219 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3220 $sql .=
' SET fk_availability = '.((int) $availability_id);
3221 $sql .=
' WHERE rowid='.((int) $this->
id);
3223 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3224 $resql = $this->db->query($sql);
3226 $this->errors[] = $this->db->error();
3231 $this->oldcopy = clone $this;
3232 $this->availability_id = $availability_id;
3235 if (!$notrigger && empty($error)) {
3245 $this->db->commit();
3248 foreach ($this->errors as $errmsg) {
3249 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3250 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3252 $this->db->rollback();
3256 $error_str =
'Propal status do not meet requirement '.$this->statut;
3258 $this->error = $error_str;
3259 $this->errors[] = $this->error;
3278 if ($this->
status >= self::STATUS_DRAFT) {
3283 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3284 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3285 $sql .=
' WHERE rowid='.((int) $this->
id);
3287 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3288 $resql = $this->db->query($sql);
3290 $this->errors[] = $this->db->error();
3295 $this->oldcopy = clone $this;
3296 $this->demand_reason_id = $demand_reason_id;
3299 if (!$notrigger && empty($error)) {
3309 $this->db->commit();
3312 foreach ($this->errors as $errmsg) {
3313 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3314 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3316 $this->db->rollback();
3320 $error_str =
'Propal status do not meet requirement '.$this->statut;
3322 $this->error = $error_str;
3323 $this->errors[] = $this->error;
3337 $sql =
"SELECT c.rowid, ";
3338 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3339 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3340 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3341 $sql .=
" WHERE c.rowid = ".((int) $id);
3343 $result = $this->db->query($sql);
3346 if ($this->db->num_rows($result)) {
3347 $obj = $this->db->fetch_object($result);
3349 $this->
id = $obj->rowid;
3351 $this->date_creation = $this->db->jdate($obj->datec);
3352 $this->date_validation = $this->db->jdate($obj->datev);
3353 $this->date_signature = $this->db->jdate($obj->date_signature);
3354 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3356 $this->user_creation_id = $obj->fk_user_author;
3357 $this->user_validation_id = $obj->fk_user_valid;
3359 if ($obj->fk_user_signature) {
3360 $user_signature =
new User($this->db);
3361 $user_signature->fetch($obj->fk_user_signature);
3362 $this->user_signature = $user_signature;
3365 $this->user_closing_id = $obj->fk_user_cloture;
3367 $this->db->free($result);
3396 global $conf, $hookmanager;
3399 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3401 $langs->load(
"propal");
3402 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3403 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3404 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3405 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3406 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3407 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3408 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3409 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3410 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3411 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3415 if ($status == self::STATUS_DRAFT) {
3416 $statusType =
'status0';
3417 } elseif ($status == self::STATUS_VALIDATED) {
3418 $statusType =
'status1';
3419 } elseif ($status == self::STATUS_SIGNED) {
3420 $statusType =
'status4';
3421 } elseif ($status == self::STATUS_NOTSIGNED) {
3422 $statusType =
'status9';
3423 } elseif ($status == self::STATUS_BILLED) {
3424 $statusType =
'status6';
3428 $parameters = array(
'status' => $status,
'mode' => $mode);
3429 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3432 return $hookmanager->resPrint;
3435 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3450 global $conf, $langs;
3454 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3455 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3456 if (!$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
3457 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
3458 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3461 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3462 if ($mode ==
'opened') {
3463 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3465 if ($mode ==
'signed') {
3466 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3469 $sql .=
" AND p.fk_soc = ".((int) $user->socid);
3472 $resql = $this->db->query($sql);
3474 $langs->load(
"propal");
3479 $label = $labelShort =
'';
3480 if ($mode ==
'opened') {
3481 $delay_warning = $conf->propal->cloture->warning_delay;
3483 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3484 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3486 if ($mode ==
'signed') {
3487 $delay_warning = $conf->propal->facturation->warning_delay;
3489 $label = $langs->trans(
"PropalsToBill");
3490 $labelShort = $langs->trans(
"ToBill");
3494 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3495 $response->label = $label;
3496 $response->labelShort = $labelShort;
3497 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3498 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3502 while ($obj = $this->db->fetch_object($resql)) {
3503 $response->nbtodo++;
3504 $response->total += $obj->total_ht;
3506 if ($mode ==
'opened') {
3507 $datelimit = $this->db->jdate($obj->datefin);
3508 if ($datelimit < ($now - $delay_warning)) {
3509 $response->nbtodolate++;
3518 $this->error = $this->db->error();
3533 global $conf, $langs;
3538 $sql =
"SELECT rowid";
3539 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3540 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3541 $sql .= $this->db->plimit(100);
3543 $resql = $this->db->query($sql);
3545 $num_prods = $this->db->num_rows($resql);
3547 while ($i < $num_prods) {
3549 $row = $this->db->fetch_row($resql);
3550 $prodids[$i] = $row[0];
3556 $this->
ref =
'SPECIMEN';
3557 $this->ref_client =
'NEMICEPS';
3558 $this->specimen = 1;
3560 $this->date = time();
3561 $this->fin_validite = $this->date + 3600 * 24 * 30;
3562 $this->cond_reglement_id = 1;
3563 $this->cond_reglement_code =
'RECEP';
3564 $this->mode_reglement_id = 7;
3565 $this->mode_reglement_code =
'CHQ';
3566 $this->availability_id = 1;
3567 $this->availability_code =
'AV_NOW';
3568 $this->demand_reason_id = 1;
3569 $this->demand_reason_code =
'SRC_00';
3570 $this->note_public =
'This is a comment (public)';
3571 $this->note_private =
'This is a comment (private)';
3573 $this->multicurrency_tx = 1;
3574 $this->multicurrency_code = $conf->currency;
3579 while ($xnbp < $nbp) {
3581 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3583 $line->subprice = 100;
3586 $line->localtax1_tx = 0;
3587 $line->localtax2_tx = 0;
3589 $line->total_ht = 50;
3590 $line->total_ttc = 60;
3591 $line->total_tva = 10;
3592 $line->remise_percent = 50;
3594 $line->total_ht = 100;
3595 $line->total_ttc = 120;
3596 $line->total_tva = 20;
3597 $line->remise_percent = 00;
3600 if ($num_prods > 0) {
3601 $prodid = mt_rand(1, $num_prods);
3602 $line->fk_product = $prodids[$prodid];
3603 $line->product_ref =
'SPECIMEN';
3606 $this->lines[$xnbp] = $line;
3608 $this->total_ht += $line->total_ht;
3609 $this->total_tva += $line->total_tva;
3610 $this->total_ttc += $line->total_ttc;
3627 $this->nb = array();
3630 $sql =
"SELECT count(p.rowid) as nb";
3631 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3632 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3633 if (!$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
3634 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3635 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3638 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3640 $resql = $this->db->query($sql);
3643 while ($obj = $this->db->fetch_object($resql)) {
3644 $this->nb[
"proposals"] = $obj->nb;
3646 $this->db->free($resql);
3650 $this->error = $this->db->error();
3665 global $conf, $langs;
3666 $langs->load(
"propal");
3668 $classname = $conf->global->PROPALE_ADDON;
3670 if (!empty($classname)) {
3673 $file = $classname.
".php";
3676 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3677 foreach ($dirmodels as $reldir) {
3681 $mybool |= @include_once $dir.$file;
3689 $obj =
new $classname();
3691 $numref = $obj->getNextValue($soc, $this);
3693 if ($numref !=
"") {
3696 $this->error = $obj->error;
3701 $langs->load(
"errors");
3702 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3715 global $conf, $langs, $user;
3717 $langs->load(
'propal');
3719 $nofetch = !empty($params[
'nofetch']);
3722 return [
'optimize' => $langs->trans(
"Proposal")];
3724 if ($user->hasRight(
'propal',
'lire')) {
3725 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3726 if (isset($this->
statut)) {
3727 $datas[
'status'] =
' '.$this->getLibStatut(5);
3729 if (!empty($this->
ref)) {
3730 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3733 $langs->load(
'companies');
3734 if (empty($this->thirdparty)) {
3737 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3739 if (!empty($this->ref_client)) {
3740 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_client;
3743 $langs->load(
'project');
3744 if (empty($this->project)) {
3747 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3751 if (!empty($this->total_ht)) {
3752 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3754 if (!empty($this->total_tva)) {
3755 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3757 if (!empty($this->total_ttc)) {
3758 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3760 if (!empty($this->date)) {
3761 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3763 if (!empty($this->delivery_date)) {
3764 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3782 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3784 global $langs, $conf, $user, $hookmanager;
3786 if (!empty($conf->dol_no_mouse_hover)) {
3793 'objecttype' => $this->element,
3794 'option' => $option,
3797 $classfortooltip =
'classfortooltip';
3800 $classfortooltip =
'classforajaxtooltip';
3801 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3808 if ($user->hasRight(
'propal',
'lire')) {
3809 if ($option ==
'') {
3810 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3811 } elseif ($option ==
'compta') {
3812 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3813 } elseif ($option ==
'expedition') {
3814 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3815 } elseif ($option ==
'document') {
3816 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3819 if ($option !=
'nolink') {
3821 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3822 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3823 $add_save_lastsearch_values = 1;
3825 if ($add_save_lastsearch_values) {
3826 $url .=
'&save_lastsearch_values=1';
3832 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3834 $label = $langs->trans(
"Proposal");
3835 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3837 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3838 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3841 $linkstart =
'<a href="'.$url.
'"';
3842 $linkstart .= $linkclose.
'>';
3845 $result .= $linkstart;
3847 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3849 if ($withpicto != 2) {
3850 $result .= $this->ref;
3852 $result .= $linkend;
3854 if ($addlinktonotes >= 0) {
3857 if ($addlinktonotes == 0) {
3858 if (!empty($this->note_private) || !empty($this->note_public)) {
3859 $txttoshow = $langs->trans(
'ViewPrivateNote');
3861 } elseif ($addlinktonotes == 1) {
3862 if (!empty($this->note_private)) {
3865 } elseif ($addlinktonotes == 2) {
3866 if (!empty($this->note_public)) {
3869 } elseif ($addlinktonotes == 3) {
3870 if ($user->socid > 0) {
3871 if (!empty($this->note_public)) {
3875 if (!empty($this->note_public)) {
3878 if (!empty($this->note_private)) {
3879 if (!empty($txttoshow)) {
3880 $txttoshow .=
'<br><br>';
3888 $result .=
' <span class="note inline-block">';
3889 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3892 $result .=
'</span>';
3897 $hookmanager->initHooks(array($this->element .
'dao'));
3898 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
3899 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3901 $result = $hookmanager->resPrint;
3903 $result .= $hookmanager->resPrint;
3916 return $this->
fetch_lines(0, 0, $sqlforgedfilters);
3930 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3932 global $conf, $langs;
3934 $langs->load(
"propale");
3935 $outputlangs->load(
"products");
3940 if ($this->model_pdf) {
3941 $modele = $this->model_pdf;
3943 $modele = $conf->global->PROPALE_ADDON_PDF;
3947 $modelpath =
"core/modules/propale/doc/";
3949 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3997 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
3999 $return =
'<div class="box-flex-item box-flex-grow-zero">';
4000 $return .=
'<div class="info-box info-box-sm">';
4001 $return .=
'<span class="info-box-icon bg-infobox-action">';
4003 $return .=
'</span>';
4004 $return .=
'<div class="info-box-content">';
4005 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
4006 if ($selected >= 0) {
4007 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
4009 if (!empty($arraydata[
'projectlink'])) {
4010 $return .=
'<span class="info-box-ref"> | '.$arraydata[
'projectlink'].
'</span>';
4012 if (!empty($arraydata[
'authorlink'])) {
4013 $return .=
'<br><span class="info-box-label">'.$arraydata[
'authorlink'].
'</span>';
4015 if (property_exists($this,
'total_ht')) {
4016 $return .=
'<br><span class="info-box-label amount" title="'.$langs->trans(
"AmountHT").
'">'.
price($this->total_ht).
'</span>';
4018 if (method_exists($this,
'getLibStatut')) {
4019 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
4021 $return .=
'</div>';
4022 $return .=
'</div>';
4023 $return .=
'</div>';
4036 public $element =
'propaldet';
4041 public $table_element =
'propaldet';
4047 public $fk_parent_line;
4065 public $vat_src_code;
4068 public $remise_percent;
4069 public $fk_remise_except;
4073 public $fk_fournprice;
4078 public $special_code;
4083 public $info_bits = 0;
4112 public $product_ref;
4127 public $product_label;
4132 public $product_desc;
4138 public $product_tobatch;
4144 public $product_barcode;
4146 public $localtax1_tx;
4147 public $localtax2_tx;
4148 public $localtax1_type;
4149 public $localtax2_type;
4150 public $total_localtax1;
4151 public $total_localtax2;
4156 public $skip_update_total;
4159 public $fk_multicurrency;
4160 public $multicurrency_code;
4161 public $multicurrency_subprice;
4162 public $multicurrency_total_ht;
4163 public $multicurrency_total_tva;
4164 public $multicurrency_total_ttc;
4185 $sql =
'SELECT pd.rowid, pd.fk_propal, pd.fk_parent_line, pd.fk_product, pd.label as custom_label, pd.description, pd.price, pd.qty, pd.vat_src_code, pd.tva_tx,';
4186 $sql .=
' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
4187 $sql .=
' pd.info_bits, pd.total_ht, pd.total_tva, pd.total_ttc, pd.fk_product_fournisseur_price as fk_fournprice, pd.buy_price_ht as pa_ht, pd.special_code, pd.rang,';
4188 $sql .=
' pd.fk_unit,';
4189 $sql .=
' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,';
4190 $sql .=
' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,';
4191 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
4192 $sql .=
' pd.date_start, pd.date_end, pd.product_type';
4193 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as pd';
4194 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON pd.fk_product = p.rowid';
4195 $sql .=
' WHERE pd.rowid = '.((int) $rowid);
4197 $result = $this->db->query($sql);
4199 $objp = $this->db->fetch_object($result);
4202 $this->
id = $objp->rowid;
4203 $this->
rowid = $objp->rowid;
4204 $this->fk_propal = $objp->fk_propal;
4205 $this->fk_parent_line = $objp->fk_parent_line;
4206 $this->label = $objp->custom_label;
4207 $this->desc = $objp->description;
4208 $this->qty = $objp->qty;
4209 $this->
price = $objp->price;
4210 $this->subprice = $objp->subprice;
4211 $this->vat_src_code = $objp->vat_src_code;
4212 $this->tva_tx = $objp->tva_tx;
4213 $this->remise = $objp->remise;
4214 $this->remise_percent = $objp->remise_percent;
4215 $this->fk_remise_except = $objp->fk_remise_except;
4216 $this->fk_product = $objp->fk_product;
4217 $this->info_bits = $objp->info_bits;
4219 $this->total_ht = $objp->total_ht;
4220 $this->total_tva = $objp->total_tva;
4221 $this->total_ttc = $objp->total_ttc;
4223 $this->fk_fournprice = $objp->fk_fournprice;
4225 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
4226 $this->pa_ht = $marginInfos[0];
4227 $this->marge_tx = $marginInfos[1];
4228 $this->marque_tx = $marginInfos[2];
4230 $this->special_code = $objp->special_code;
4231 $this->product_type = $objp->product_type;
4232 $this->rang = $objp->rang;
4234 $this->
ref = $objp->product_ref;
4235 $this->product_ref = $objp->product_ref;
4236 $this->libelle = $objp->product_label;
4237 $this->product_label = $objp->product_label;
4238 $this->product_desc = $objp->product_desc;
4239 $this->fk_unit = $objp->fk_unit;
4241 $this->date_start = $this->db->jdate($objp->date_start);
4242 $this->date_end = $this->db->jdate($objp->date_end);
4245 $this->fk_multicurrency = $objp->fk_multicurrency;
4246 $this->multicurrency_code = $objp->multicurrency_code;
4247 $this->multicurrency_subprice = $objp->multicurrency_subprice;
4248 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
4249 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
4250 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
4254 $this->db->free($result);
4273 global $conf, $user;
4277 dol_syslog(get_class($this).
"::insert rang=".$this->rang);
4279 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4282 if (empty($this->tva_tx)) {
4285 if (empty($this->localtax1_tx)) {
4286 $this->localtax1_tx = 0;
4288 if (empty($this->localtax2_tx)) {
4289 $this->localtax2_tx = 0;
4291 if (empty($this->localtax1_type)) {
4292 $this->localtax1_type = 0;
4294 if (empty($this->localtax2_type)) {
4295 $this->localtax2_type = 0;
4297 if (empty($this->total_localtax1)) {
4298 $this->total_localtax1 = 0;
4300 if (empty($this->total_localtax2)) {
4301 $this->total_localtax2 = 0;
4303 if (empty($this->rang)) {
4306 if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) {
4307 $this->remise_percent = 0;
4309 if (empty($this->info_bits)) {
4310 $this->info_bits = 0;
4312 if (empty($this->special_code)) {
4313 $this->special_code = 0;
4315 if (empty($this->fk_parent_line)) {
4316 $this->fk_parent_line = 0;
4318 if (empty($this->fk_fournprice)) {
4319 $this->fk_fournprice = 0;
4321 if (!is_numeric($this->qty)) {
4324 if (empty($this->pa_ht)) {
4327 if (empty($this->multicurrency_subprice)) {
4328 $this->multicurrency_subprice = 0;
4330 if (empty($this->multicurrency_total_ht)) {
4331 $this->multicurrency_total_ht = 0;
4333 if (empty($this->multicurrency_total_tva)) {
4334 $this->multicurrency_total_tva = 0;
4336 if (empty($this->multicurrency_total_ttc)) {
4337 $this->multicurrency_total_ttc = 0;
4341 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4342 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4345 $this->pa_ht = $result;
4350 if ($this->product_type < 0) {
4357 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'propaldet';
4358 $sql .=
' (fk_propal, fk_parent_line, label, description, fk_product, product_type,';
4359 $sql .=
' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
4360 $sql .=
' subprice, remise_percent, ';
4361 $sql .=
' info_bits, ';
4362 $sql .=
' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,';
4363 $sql .=
' fk_unit,';
4364 $sql .=
' date_start, date_end';
4365 $sql .=
', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)';
4366 $sql .=
" VALUES (".$this->fk_propal.
",";
4367 $sql .=
" ".($this->fk_parent_line > 0 ?
"'".$this->db->escape($this->fk_parent_line).
"'" :
"null").
",";
4368 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
4369 $sql .=
" '".$this->db->escape($this->desc).
"',";
4370 $sql .=
" ".($this->fk_product ?
"'".$this->db->escape($this->fk_product).
"'" :
"null").
",";
4371 $sql .=
" '".$this->db->escape($this->product_type).
"',";
4372 $sql .=
" ".($this->fk_remise_except ?
"'".$this->db->escape($this->fk_remise_except).
"'" :
"null").
",";
4373 $sql .=
" ".price2num($this->qty,
'MS').
",";
4374 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
4375 $sql .=
" ".price2num($this->tva_tx).
",";
4376 $sql .=
" ".price2num($this->localtax1_tx).
",";
4377 $sql .=
" ".price2num($this->localtax2_tx).
",";
4378 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
4379 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
4380 $sql .=
" ".(price2num($this->subprice) !==
'' ?
price2num($this->subprice,
'MU') :
"null").
",";
4381 $sql .=
" ".price2num($this->remise_percent, 3).
",";
4382 $sql .=
" ".(isset($this->info_bits) ? ((int) $this->info_bits) :
"null").
",";
4383 $sql .=
" ".price2num($this->total_ht,
'MT').
",";
4384 $sql .=
" ".price2num($this->total_tva,
'MT').
",";
4385 $sql .=
" ".price2num($this->total_localtax1,
'MT').
",";
4386 $sql .=
" ".price2num($this->total_localtax2,
'MT').
",";
4387 $sql .=
" ".price2num($this->total_ttc,
'MT').
",";
4388 $sql .=
" ".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null").
",";
4389 $sql .=
" ".(isset($this->pa_ht) ?
"'".price2num($this->pa_ht).
"'" :
"null").
",";
4390 $sql .=
' '.((int) $this->special_code).
',';
4391 $sql .=
' '.((int) $this->rang).
',';
4392 $sql .=
' '.(empty($this->fk_unit) ?
'NULL' : ((int) $this->fk_unit)).
',';
4393 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
',';
4394 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4395 $sql .=
", ".($this->fk_multicurrency > 0 ? ((int) $this->fk_multicurrency) :
'null');
4396 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
4397 $sql .=
", ".price2num($this->multicurrency_subprice,
'CU');
4398 $sql .=
", ".price2num($this->multicurrency_total_ht,
'CT');
4399 $sql .=
", ".price2num($this->multicurrency_total_tva,
'CT');
4400 $sql .=
", ".price2num($this->multicurrency_total_ttc,
'CT');
4403 dol_syslog(get_class($this).
'::insert', LOG_DEBUG);
4404 $resql = $this->db->query($sql);
4406 $this->
rowid = $this->db->last_insert_id(MAIN_DB_PREFIX.
'propaldet');
4409 $this->
id = $this->rowid;
4416 if (!$error && !$notrigger) {
4418 $result = $this->
call_trigger(
'LINEPROPAL_INSERT', $user);
4420 $this->db->rollback();
4427 $this->db->commit();
4431 foreach ($this->errors as $errmsg) {
4432 dol_syslog(get_class($this).
"::insert ".$errmsg, LOG_ERR);
4433 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4435 $this->db->rollback();
4438 $this->error = $this->db->error().
" sql=".$sql;
4439 $this->db->rollback();
4451 public function delete(
User $user, $notrigger = 0)
4460 $result = $this->
call_trigger(
'LINEPROPAL_DELETE', $user);
4468 $sql =
"DELETE FROM " . MAIN_DB_PREFIX .
"propaldet WHERE rowid = " . ((int) $this->
rowid);
4469 dol_syslog(
"PropaleLigne::delete", LOG_DEBUG);
4470 if ($this->db->query($sql)) {
4473 $this->
id = $this->rowid;
4477 dol_syslog(get_class($this) .
"::delete error -4 " . $this->error, LOG_ERR);
4481 $this->error = $this->db->error() .
" sql=" . $sql;
4487 $this->db->rollback();
4490 $this->db->commit();
4503 global $conf, $user;
4507 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4509 if (empty($this->
id) && !empty($this->
rowid)) {
4510 $this->
id = $this->rowid;
4514 if (empty($this->tva_tx)) {
4517 if (empty($this->localtax1_tx)) {
4518 $this->localtax1_tx = 0;
4520 if (empty($this->localtax2_tx)) {
4521 $this->localtax2_tx = 0;
4523 if (empty($this->total_localtax1)) {
4524 $this->total_localtax1 = 0;
4526 if (empty($this->total_localtax2)) {
4527 $this->total_localtax2 = 0;
4529 if (empty($this->localtax1_type)) {
4530 $this->localtax1_type = 0;
4532 if (empty($this->localtax2_type)) {
4533 $this->localtax2_type = 0;
4535 if (empty($this->marque_tx)) {
4536 $this->marque_tx = 0;
4538 if (empty($this->marge_tx)) {
4539 $this->marge_tx = 0;
4541 if (empty($this->
price)) {
4544 if (empty($this->remise_percent)) {
4545 $this->remise_percent = 0;
4547 if (empty($this->info_bits)) {
4548 $this->info_bits = 0;
4550 if (empty($this->special_code)) {
4551 $this->special_code = 0;
4553 if (empty($this->fk_parent_line)) {
4554 $this->fk_parent_line = 0;
4556 if (empty($this->fk_fournprice)) {
4557 $this->fk_fournprice = 0;
4559 if (empty($this->subprice)) {
4560 $this->subprice = 0;
4562 if (empty($this->pa_ht)) {
4567 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4568 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4571 $this->pa_ht = $result;
4578 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4579 $sql .=
" description='".$this->db->escape($this->desc).
"'";
4580 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
4581 $sql .=
", product_type=".$this->product_type;
4582 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"'";
4583 $sql .=
", tva_tx='".price2num($this->tva_tx).
"'";
4584 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
4585 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
4586 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
4587 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
4588 $sql .=
", qty='".price2num($this->qty).
"'";
4589 $sql .=
", subprice=".price2num($this->subprice);
4590 $sql .=
", remise_percent=".price2num($this->remise_percent);
4592 $sql .=
", remise=".(float)
price2num($this->remise);
4593 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
4594 if (empty($this->skip_update_total)) {
4595 $sql .=
", total_ht=".price2num($this->total_ht);
4596 $sql .=
", total_tva=".price2num($this->total_tva);
4597 $sql .=
", total_ttc=".price2num($this->total_ttc);
4598 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
4599 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
4601 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
4602 $sql .=
", buy_price_ht=".price2num($this->pa_ht);
4603 if (strlen($this->special_code)) {
4604 $sql .=
", special_code=".$this->special_code;
4606 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
4607 if (!empty($this->rang)) {
4608 $sql .=
", rang=".((int) $this->rang);
4610 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
4611 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4612 $sql .=
", fk_unit=".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
4615 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
4616 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
4617 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
4618 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
4620 $sql .=
" WHERE rowid = ".((int) $this->
id);
4622 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
4623 $resql = $this->db->query($sql);
4632 if (!$error && !$notrigger) {
4634 $result = $this->
call_trigger(
'LINEPROPAL_MODIFY', $user);
4636 $this->db->rollback();
4643 $this->db->commit();
4647 foreach ($this->errors as $errmsg) {
4648 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
4649 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4651 $this->db->rollback();
4654 $this->error = $this->db->error();
4655 $this->db->rollback();
4673 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4674 $sql .=
" total_ht=".price2num($this->total_ht,
'MT');
4675 $sql .=
",total_tva=".price2num($this->total_tva,
'MT');
4676 $sql .=
",total_ttc=".price2num($this->total_ttc,
'MT');
4677 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
4679 dol_syslog(
"PropaleLigne::update_total", LOG_DEBUG);
4681 $resql = $this->db->query($sql);
4683 $this->db->commit();
4686 $this->error = $this->db->error();
4687 $this->db->rollback();
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true)
Save a new position (field rang) for details lines.
deleteEcmFiles($mode=0)
Delete related files of object in database.
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
defineBuyPrice($unitPrice=0.0, $discountPercent=0.0, $fk_product=0)
Get buy price to use for margin calculation.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
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 an object id/ref exists If you don't need/want to instantiate object and just need to know if o...
updateRangOfLine($rowid, $rang)
Update position of line (rang)
fetch_project()
Load the project with id $this->fk_project into this->project.
update_price($exclspec=0, $roundingadjust='none', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
deleteExtraFields()
Delete all extra fields values for the current object.
fetchObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $clause='OR', $alsosametype=1, $orderby='sourcetype', $loadalsoobjects=1)
Fetch array of objects linked to current object (object of enabled modules only).
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
static commonReplaceProduct(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product id with another one.
line_max($fk_parent_line=0)
Get max value used for position of line (rang)
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage absolute discounts.
Class to manage Dolibarr database access.
static getIdFromCode($dbs, $code)
Get id of currency from code.
static getIdAndTxFromCode($dbs, $code, $date_document='')
Get id and rate of currency from code.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
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 clicable link of object (with eventually picto)
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
InvoiceArrayList($id)
Returns an array with id and ref of related invoices.
availability($availability_id, $notrigger=0)
Change the delivery time.
const STATUS_NOTSIGNED
Not signed quote.
setDeliveryDate($user, $delivery_date, $notrigger=0)
Set delivery date.
load_state_board()
Charge indicateurs this->nb de tableau de bord.
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.
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, ...)
insert_discount($idremise)
Adding line of fixed discount in the proposal in DB.
getNextNumRef($soc)
Returns the reference to the following non used Proposal used depending on the active numbering modul...
LibStatut($status, $mode=1)
Return label of a status (draft, validated, ...)
valid($user, $notrigger=0)
Set status to validated.
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
set_ref_client($user, $ref_client, $notrigger=0)
Set customer reference number.
setDraft($user, $notrigger=0)
Set draft status.
set_echeance($user, $date_end_validity, $notrigger=0)
Define end validity date.
set_demand_reason($user, $id, $notrigger=0)
Set source of demand.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
deleteline($lineid, $id=0)
Delete detail line.
create($user, $notrigger=0)
Create commercial proposal into database this->ref can be set or empty.
liste_array($shortlist=0, $draft=0, $notcurrentuser=0, $socid=0, $limit=0, $offset=0, $sortfield='p.datep', $sortorder='DESC')
Return list of proposal (eventually filtered on user) into an array.
add_product($idproduct, $qty, $remise_percent=0)
Add line into array ->lines $this->thirdparty should be loaded.
initAsSpecimen()
Initialise an instance with random values.
closeProposal($user, $status, $note='', $notrigger=0)
Close/set the commercial proposal to status signed or refused (fill also date signature)
reopen($user, $status, $note='', $notrigger=0)
Set an overall discount on the proposal.
__construct($db, $socid=0, $propalid=0)
Constructor.
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
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.
createFromClone(User $user, $socid=0, $forceentity=null, $update_prices=false, $update_desc=false)
Load an object from its id and create a new one in database.
Class to manage commercial proposal lines.
__construct($db)
Class line Contructor.
update($notrigger=0)
Update propal line object into DB.
fetch($rowid)
Retrieve the propal line object.
insert($notrigger=0)
Insert object line propal in database.
update_total()
Update DB line fields total_xxx Used by migration.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
trait CommonIncoterm
Superclass for incoterm classes.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_delete_preview($object)
Delete all preview files linked to object instance.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller="", $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e rowid
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e e e e e statut
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocaltax1_rate, $uselocaltax2_rate, $remise_percent_global, $price_base_type, $info_bits, $type, $seller='', $localtaxes_array='', $progress=100, $multicurrency_tx=1, $pu_devise=0, $multicurrency_code='')
Calculate totals (net, vat, ...) of a line.