41require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
42require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobjectline.class.php";
43require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
44require_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
46require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
47require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
64 public $element =
'propal';
69 public $table_element =
'propal';
74 public $table_element_line =
'propaldet';
79 public $fk_element =
'fk_propal';
84 public $picto =
'propal';
90 public $ismultientitymanaged = 1;
96 public $restrictiononfksoc = 1;
128 public $ref_customer;
159 public $date_creation;
170 public $date_validation;
175 public $date_signature;
180 public $user_signature;
196 public $delivery_date;
199 public $fin_validite;
201 public $user_author_id;
219 public $cond_reglement_code;
220 public $cond_reglement;
221 public $cond_reglement_doc;
223 public $mode_reglement_code;
224 public $mode_reglement;
226 public $deposit_percent;
234 public $address_type;
240 public $availability_id;
247 public $fk_availability;
252 public $availability_code;
257 public $availability;
259 public $duree_validite;
261 public $demand_reason_id;
262 public $demand_reason_code;
263 public $demand_reason;
265 public $warehouse_id;
267 public $extraparams = array();
272 public $lines = array();
279 public $labelStatus = array();
280 public $labelStatusShort = array();
311 public $fields = array(
312 'rowid' =>array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
313 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>15,
'index'=>1),
314 'ref' =>array(
'type'=>
'varchar(30)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>20),
315 'ref_client' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefCustomer',
'enabled'=>1,
'visible'=>-1,
'position'=>22),
316 'ref_ext' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefExt',
'enabled'=>1,
'visible'=>0,
'position'=>40),
317 'fk_soc' =>array(
'type'=>
'integer:Societe:societe/class/societe.class.php',
'label'=>
'ThirdParty',
'enabled'=>
'isModEnabled("societe")',
'visible'=>-1,
'position'=>23),
318 '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),
319 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>25),
320 'datec' =>array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
321 'datep' =>array(
'type'=>
'date',
'label'=>
'Date',
'enabled'=>1,
'visible'=>-1,
'position'=>60),
322 'fin_validite' =>array(
'type'=>
'datetime',
'label'=>
'DateEnd',
'enabled'=>1,
'visible'=>-1,
'position'=>65),
323 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'DateValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>70),
324 'date_cloture' =>array(
'type'=>
'datetime',
'label'=>
'DateClosing',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
325 'fk_user_author' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
326 'fk_user_modif' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'position'=>85),
327 'fk_user_valid' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
328 'fk_user_cloture' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Fk user cloture',
'enabled'=>1,
'visible'=>-1,
'position'=>95),
329 'price' =>array(
'type'=>
'double',
'label'=>
'Price',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
330 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalHT',
'enabled'=>1,
'visible'=>-1,
'position'=>125,
'isameasure'=>1),
331 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'VAT',
'enabled'=>1,
'visible'=>-1,
'position'=>130,
'isameasure'=>1),
332 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'LocalTax1',
'enabled'=>1,
'visible'=>-1,
'position'=>135,
'isameasure'=>1),
333 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'LocalTax2',
'enabled'=>1,
'visible'=>-1,
'position'=>140,
'isameasure'=>1),
334 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalTTC',
'enabled'=>1,
'visible'=>-1,
'position'=>145,
'isameasure'=>1),
335 'fk_account' =>array(
'type'=>
'integer',
'label'=>
'BankAccount',
'enabled'=>
'isModEnabled("banque")',
'visible'=>-1,
'position'=>150),
336 'fk_currency' =>array(
'type'=>
'varchar(3)',
'label'=>
'Currency',
'enabled'=>1,
'visible'=>-1,
'position'=>155),
337 'fk_cond_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentTerm',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
338 'deposit_percent' =>array(
'type'=>
'varchar(63)',
'label'=>
'DepositPercent',
'enabled'=>1,
'visible'=>-1,
'position'=>161),
339 'fk_mode_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentMode',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
340 'note_private' =>array(
'type'=>
'html',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>170),
341 'note_public' =>array(
'type'=>
'html',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>175),
342 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'PDFTemplate',
'enabled'=>1,
'visible'=>0,
'position'=>180),
343 'date_livraison' =>array(
'type'=>
'date',
'label'=>
'DateDeliveryPlanned',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
344 'fk_shipping_method' =>array(
'type'=>
'integer',
'label'=>
'ShippingMethod',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
345 'fk_warehouse' =>array(
'type'=>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label'=>
'Fk warehouse',
'enabled'=>
'isModEnabled("stock")',
'visible'=>-1,
'position'=>191),
346 'fk_availability' =>array(
'type'=>
'integer',
'label'=>
'Availability',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
347 'fk_delivery_address' =>array(
'type'=>
'integer',
'label'=>
'DeliveryAddress',
'enabled'=>1,
'visible'=>0,
'position'=>200),
348 'fk_input_reason' =>array(
'type'=>
'integer',
'label'=>
'InputReason',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
349 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>215),
350 'fk_incoterms' =>array(
'type'=>
'integer',
'label'=>
'IncotermCode',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>220),
351 'location_incoterms' =>array(
'type'=>
'varchar(255)',
'label'=>
'IncotermLabel',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>225),
352 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'MulticurrencyID',
'enabled'=>1,
'visible'=>-1,
'position'=>230),
353 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'MulticurrencyCurrency',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>235),
354 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyRate',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>240,
'isameasure'=>1),
355 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountHT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>245,
'isameasure'=>1),
356 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountVAT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>250,
'isameasure'=>1),
357 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountTTC',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>255,
'isameasure'=>1),
358 'last_main_doc' =>array(
'type'=>
'varchar(255)',
'label'=>
'LastMainDoc',
'enabled'=>1,
'visible'=>-1,
'position'=>260),
359 'fk_statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Status',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
360 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>900),
395 global $conf, $langs;
399 $this->socid = $socid;
400 $this->
id = $propalid;
402 $this->duree_validite =
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
418 public function add_product($idproduct, $qty, $remise_percent = 0)
421 global $conf, $mysoc;
427 dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
428 if ($idproduct > 0) {
429 $prod =
new Product($this->db);
430 $prod->fetch($idproduct);
432 $productdesc = $prod->description;
436 if (empty($tva_tx)) {
441 $localtax1_tx =
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
442 $localtax2_tx =
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
445 if ($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
446 $price = $prod->multiprices[$this->thirdparty->price_level];
453 $line->fk_product = $idproduct;
454 $line->desc = $productdesc;
457 $line->remise_percent = $remise_percent;
458 $line->vat_src_code = $vat_src_code;
459 $line->tva_tx = $tva_tx;
460 $line->fk_unit = $prod->fk_unit;
462 $line->info_bits = 1;
465 $this->lines[] = $line;
483 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
484 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
489 $result = $remise->fetch($idremise);
492 if ($remise->fk_facture) {
493 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
494 $this->db->rollback();
500 $this->line->context = $this->context;
502 $line->fk_propal = $this->id;
503 $line->fk_remise_except = $remise->id;
504 $line->desc = $remise->description;
505 $line->vat_src_code = $remise->vat_src_code;
506 $line->tva_tx = $remise->tva_tx;
507 $line->subprice = -$remise->amount_ht;
508 $line->fk_product = 0;
510 $line->remise_percent = 0;
512 $line->info_bits = 2;
515 $line->price = -$remise->amount_ht;
517 $line->total_ht = -$remise->amount_ht;
518 $line->total_tva = -$remise->amount_tva;
519 $line->total_ttc = -$remise->amount_ttc;
521 $result = $line->insert();
528 $this->db->rollback();
532 $this->error = $line->error;
533 $this->errors = $line->errors;
534 $this->db->rollback();
538 $this->db->rollback();
580 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)
582 global $mysoc, $conf, $langs;
584 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);
586 if ($this->
statut == self::STATUS_DRAFT) {
587 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
590 if (empty($remise_percent)) {
596 if (empty($info_bits)) {
602 if (empty($fk_parent_line) || $fk_parent_line < 0) {
606 $remise_percent =
price2num($remise_percent);
609 $pu_ht_devise =
price2num($pu_ht_devise);
611 if (!preg_match(
'/\((.*)\)/', $txtva)) {
617 if ($price_base_type ==
'HT') {
628 if ($date_start && $date_end && $date_start > $date_end) {
629 $langs->load(
"errors");
630 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
636 $product_type = $type;
637 if (!empty($fk_product) && $fk_product > 0) {
638 $product =
new Product($this->db);
639 $result = $product->fetch($fk_product);
640 $product_type = $product->type;
642 if (
getDolGlobalString(
'STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL') && $product_type == 0 && $product->stock_reel < $qty) {
643 $langs->load(
"errors");
644 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
645 $this->db->rollback();
661 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
662 $vat_src_code = $reg[1];
663 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
666 $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);
668 $total_ht = $tabprice[0];
669 $total_tva = $tabprice[1];
670 $total_ttc = $tabprice[2];
671 $total_localtax1 = $tabprice[9];
672 $total_localtax2 = $tabprice[10];
673 $pu_ht = $tabprice[3];
674 $pu_tva = $tabprice[4];
675 $pu_ttc = $tabprice[5];
678 $multicurrency_total_ht = $tabprice[16];
679 $multicurrency_total_tva = $tabprice[17];
680 $multicurrency_total_ttc = $tabprice[18];
681 $pu_ht_devise = $tabprice[19];
685 if ($ranktouse == -1) {
686 $rangmax = $this->
line_max($fk_parent_line);
687 $ranktouse = $rangmax + 1;
694 if ($remise_percent > 0) {
695 $remise = round(($pu * $remise_percent / 100), 2);
702 $this->line->context = $this->context;
704 $this->line->fk_propal = $this->id;
705 $this->line->label = $label;
706 $this->line->desc = $desc;
707 $this->line->qty = $qty;
709 $this->line->vat_src_code = $vat_src_code;
710 $this->line->tva_tx = $txtva;
711 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
712 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
713 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
714 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
715 $this->line->fk_product = $fk_product;
716 $this->line->product_type = $type;
717 $this->line->fk_remise_except = $fk_remise_except;
718 $this->line->remise_percent = $remise_percent;
719 $this->line->subprice = $pu_ht;
720 $this->line->rang = $ranktouse;
721 $this->line->info_bits = $info_bits;
722 $this->line->total_ht = $total_ht;
723 $this->line->total_tva = $total_tva;
724 $this->line->total_localtax1 = $total_localtax1;
725 $this->line->total_localtax2 = $total_localtax2;
726 $this->line->total_ttc = $total_ttc;
727 $this->line->special_code = $special_code;
728 $this->line->fk_parent_line = $fk_parent_line;
729 $this->line->fk_unit = $fk_unit;
731 $this->line->date_start = $date_start;
732 $this->line->date_end = $date_end;
734 $this->line->fk_fournprice = $fk_fournprice;
735 $this->line->pa_ht = $pa_ht;
737 $this->line->origin_id = $origin_id;
738 $this->line->origin = $origin;
741 $this->line->fk_multicurrency = $this->fk_multicurrency;
742 $this->line->multicurrency_code = $this->multicurrency_code;
743 $this->line->multicurrency_subprice = $pu_ht_devise;
744 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
745 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
746 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
749 if (empty($qty) && empty($special_code)) {
750 $this->line->special_code = 3;
754 $this->line->price =
$price;
756 if (is_array($array_options) && count($array_options) > 0) {
757 $this->line->array_options = $array_options;
760 $result = $this->line->insert();
763 if (!empty($fk_parent_line)) {
765 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
766 $linecount = count($this->lines);
767 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
773 if (empty($noupdateafterinsertline)) {
779 return $this->line->id;
781 $this->error = $this->db->error();
782 $this->db->rollback();
786 $this->error = $this->line->error;
787 $this->errors = $this->line->errors;
788 $this->db->rollback();
792 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
827 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)
829 global $mysoc, $langs;
831 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
832 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");
833 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
836 $remise_percent =
price2num($remise_percent);
839 $pu_ht_devise =
price2num($pu_ht_devise);
840 if (!preg_match(
'/\((.*)\)/', $txtva)) {
846 if (empty($qty) && empty($special_code)) {
849 if (!empty($qty) && $special_code == 3) {
856 if ($date_start && $date_end && $date_start > $date_end) {
857 $langs->load(
"errors");
858 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
862 if ($this->
statut == self::STATUS_DRAFT) {
875 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
876 $vat_src_code = $reg[1];
877 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
882 $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);
883 $total_ht = $tabprice[0];
884 $total_tva = $tabprice[1];
885 $total_ttc = $tabprice[2];
886 $total_localtax1 = $tabprice[9];
887 $total_localtax2 = $tabprice[10];
888 $pu_ht = $tabprice[3];
889 $pu_tva = $tabprice[4];
890 $pu_ttc = $tabprice[5];
893 $multicurrency_total_ht = $tabprice[16];
894 $multicurrency_total_tva = $tabprice[17];
895 $multicurrency_total_ttc = $tabprice[18];
896 $pu_ht_devise = $tabprice[19];
901 if ($remise_percent > 0) {
902 $remise = round(($pu * $remise_percent / 100), 2);
908 $line->fetch($rowid);
910 $staticline = clone $line;
912 $line->oldline = $staticline;
914 $this->line->context = $this->context;
915 $this->line->rang = $rang;
918 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
919 $rangmax = $this->
line_max($fk_parent_line);
920 $this->line->rang = $rangmax + 1;
923 $this->line->id = $rowid;
924 $this->line->label = $label;
925 $this->line->desc = $desc;
926 $this->line->qty = $qty;
927 $this->line->product_type = $type;
928 $this->line->vat_src_code = $vat_src_code;
929 $this->line->tva_tx = $txtva;
930 $this->line->localtax1_tx = $txlocaltax1;
931 $this->line->localtax2_tx = $txlocaltax2;
932 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
933 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
934 $this->line->remise_percent = $remise_percent;
935 $this->line->subprice = $pu_ht;
936 $this->line->info_bits = $info_bits;
938 $this->line->total_ht = $total_ht;
939 $this->line->total_tva = $total_tva;
940 $this->line->total_localtax1 = $total_localtax1;
941 $this->line->total_localtax2 = $total_localtax2;
942 $this->line->total_ttc = $total_ttc;
943 $this->line->special_code = $special_code;
944 $this->line->fk_parent_line = $fk_parent_line;
945 $this->line->skip_update_total = $skip_update_total;
946 $this->line->fk_unit = $fk_unit;
948 $this->line->fk_fournprice = $fk_fournprice;
949 $this->line->pa_ht = $pa_ht;
951 $this->line->date_start = $date_start;
952 $this->line->date_end = $date_end;
954 if (is_array($array_options) && count($array_options) > 0) {
956 foreach ($array_options as $key => $value) {
957 $this->line->array_options[$key] = $array_options[$key];
962 $this->line->multicurrency_subprice = $pu_ht_devise;
963 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
964 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
965 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
967 $result = $this->line->update($notrigger);
970 if (!empty($fk_parent_line)) {
983 $this->error = $this->line->error;
984 $this->errors = $this->line->errors;
985 $this->db->rollback();
989 dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
1006 if ($this->
statut == self::STATUS_DRAFT) {
1011 $line->context = $this->context;
1014 $line->fetch($lineid);
1016 if ($id > 0 && $line->fk_propal != $id) {
1017 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
1022 $staticline = clone $line;
1023 $line->oldline = $staticline;
1025 if ($line->delete($user) > 0) {
1028 $this->db->commit();
1031 $this->error = $line->error;
1032 $this->errors = $line->errors;
1033 $this->db->rollback();
1037 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1051 public function create($user, $notrigger = 0)
1053 global $conf, $hookmanager, $mysoc;
1059 if (empty($this->date)) {
1062 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1063 if (empty($this->availability_id)) {
1064 $this->availability_id = 0;
1066 if (empty($this->demand_reason_id)) {
1067 $this->demand_reason_id = 0;
1071 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1076 if (empty($this->fk_multicurrency)) {
1077 $this->multicurrency_code = $conf->currency;
1078 $this->fk_multicurrency = 0;
1079 $this->multicurrency_tx = 1;
1083 $delivery_date = $this->delivery_date;
1090 $this->error =
"Failed to fetch company";
1091 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1096 if (!empty($this->
ref)) {
1099 $this->error =
'ErrorRefAlreadyExists';
1100 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1101 $this->db->rollback();
1106 if (empty($this->date)) {
1107 $this->error =
"Date of proposal is required";
1108 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1116 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
1119 $sql .=
", total_tva";
1120 $sql .=
", total_ttc";
1124 $sql .=
", fk_user_author";
1125 $sql .=
", note_private";
1126 $sql .=
", note_public";
1127 $sql .=
", model_pdf";
1128 $sql .=
", fin_validite";
1129 $sql .=
", fk_cond_reglement";
1130 $sql .=
", deposit_percent";
1131 $sql .=
", fk_mode_reglement";
1132 $sql .=
", fk_account";
1133 $sql .=
", ref_client";
1134 $sql .=
", ref_ext";
1135 $sql .=
", date_livraison";
1136 $sql .=
", fk_shipping_method";
1137 $sql .=
", fk_warehouse";
1138 $sql .=
", fk_availability";
1139 $sql .=
", fk_input_reason";
1140 $sql .=
", fk_projet";
1141 $sql .=
", fk_incoterms";
1142 $sql .=
", location_incoterms";
1144 $sql .=
", fk_multicurrency";
1145 $sql .=
", multicurrency_code";
1146 $sql .=
", multicurrency_tx";
1148 $sql .=
" VALUES (";
1149 $sql .= $this->socid;
1153 $sql .=
", '".$this->db->idate($this->date).
"'";
1154 $sql .=
", '".$this->db->idate($now).
"'";
1155 $sql .=
", '(PROV)'";
1156 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1157 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1158 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1159 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1160 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1161 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1162 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1163 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1164 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1165 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1166 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1167 $sql .=
", ".(empty($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1168 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1169 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1170 $sql .=
", ".$this->availability_id;
1171 $sql .=
", ".$this->demand_reason_id;
1172 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1173 $sql .=
", ".(int) $this->fk_incoterms;
1174 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1175 $sql .=
", ".setEntity($this);
1176 $sql .=
", ".(int) $this->fk_multicurrency;
1177 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1178 $sql .=
", ".(float) $this->multicurrency_tx;
1181 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1182 $resql = $this->db->query($sql);
1184 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1187 $this->
ref =
'(PROV'.$this->id.
')';
1188 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1190 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1191 $resql = $this->db->query($sql);
1196 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1197 $this->linked_objects = $this->linkedObjectsIds;
1201 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1202 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1203 if (is_array($tmp_origin_id)) {
1204 foreach ($tmp_origin_id as $origin_id) {
1207 $this->error = $this->db->lasterror();
1212 $origin_id = $tmp_origin_id;
1215 $this->error = $this->db->lasterror();
1227 $fk_parent_line = 0;
1228 $num = count($this->lines);
1230 for ($i = 0; $i < $num; $i++) {
1231 if (!is_object($this->lines[$i])) {
1233 $line = (object) $this->lines[$i];
1235 $line = $this->lines[$i];
1238 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1239 $fk_parent_line = 0;
1242 $vatrate = $line->tva_tx;
1243 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1244 $vatrate .=
' ('.$line->vat_src_code.
')';
1248 $originid = $line->origin_id;
1249 $origintype = $line->origin;
1251 $originid = $line->id;
1252 $origintype = $this->element;
1260 $line->localtax1_tx,
1261 $line->localtax2_tx,
1263 $line->remise_percent,
1267 $line->product_type,
1269 $line->special_code,
1271 $line->fk_fournprice,
1276 $line->array_options,
1287 $this->error = $this->db->error;
1293 $line->id = $result;
1296 if ($result > 0 && $line->product_type == 9) {
1297 $fk_parent_line = $result;
1327 if (!$error && !$notrigger) {
1336 $this->error = $this->db->lasterror();
1341 $this->error = $this->db->lasterror();
1346 $this->db->commit();
1347 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1350 $this->db->rollback();
1354 $this->error = $this->db->lasterror();
1355 $this->db->rollback();
1370 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1372 global $conf, $hookmanager, $mysoc;
1381 $object =
new self($this->db);
1386 $object->fetch($this->
id);
1388 $objsoc =
new Societe($this->db);
1391 if (!empty($socid) && $socid != $object->socid) {
1392 if ($objsoc->fetch($socid) > 0) {
1393 $object->socid = $objsoc->id;
1394 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1395 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1396 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1397 $object->fk_delivery_address =
'';
1409 $object->fk_project =
'';
1414 $object->ref_client =
'';
1419 $objsoc->fetch($object->socid);
1423 if ($update_prices ===
true || $update_desc ===
true) {
1424 if ($objsoc->id > 0 && !empty($object->lines)) {
1427 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1430 foreach ($object->lines as $line) {
1433 if ($line->fk_product > 0) {
1434 $prod =
new Product($this->db);
1435 $res = $prod->fetch($line->fk_product);
1437 if ($update_prices ===
true) {
1438 $pu_ht = $prod->price;
1440 $remise_percent = $objsoc->remise_percent;
1443 $pu_ht = $prod->multiprices[$objsoc->price_level];
1445 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1446 $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
1451 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1452 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1455 if (count($prodcustprice->lines) > 0) {
1456 $pu_ht =
price($prodcustprice->lines[0]->price);
1457 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1458 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1459 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1465 $line->subprice = $pu_ht;
1466 $line->tva_tx = $tva_tx;
1467 $line->remise_percent = $remise_percent;
1469 if ($update_desc ===
true) {
1470 $line->desc = $prod->description;
1480 $object->entity = (!empty($forceentity) ? $forceentity : $object->entity);
1484 $object->user_author = $user->id;
1485 $object->user_validation_id = 0;
1486 $object->date = $now;
1487 $object->datep = $now;
1488 $object->fin_validite = $object->date + ($object->duree_validite * 24 * 3600);
1490 $object->ref_client =
'';
1493 $object->note_private =
'';
1494 $object->note_public =
'';
1497 $object->context[
'createfromclone'] =
'createfromclone';
1498 $result = $object->create($user);
1500 $this->error = $object->error;
1501 $this->errors = array_merge($this->errors, $object->errors);
1507 if ($object->copy_linked_contact($this,
'internal') < 0) {
1514 if ($this->socid == $object->socid) {
1515 if ($object->copy_linked_contact($this,
'external') < 0) {
1523 if (is_object($hookmanager)) {
1524 $parameters = array(
'objFrom'=>$this,
'clonedObj'=>$object);
1526 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1534 unset($object->context[
'createfromclone']);
1538 $this->db->commit();
1541 $this->db->rollback();
1555 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1557 $sql =
"SELECT p.rowid, p.ref, p.entity, p.fk_soc";
1558 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1559 $sql .=
", p.datec";
1560 $sql .=
", p.date_signature as dates";
1561 $sql .=
", p.date_valid as datev";
1562 $sql .=
", p.datep as dp";
1563 $sql .=
", p.fin_validite as dfv";
1564 $sql .=
", p.date_livraison as delivery_date";
1565 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1566 $sql .=
", p.note_private, p.note_public";
1567 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1568 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1569 $sql .=
", p.fk_delivery_address";
1570 $sql .=
", p.fk_availability";
1571 $sql .=
", p.fk_input_reason";
1572 $sql .=
", p.fk_cond_reglement";
1573 $sql .=
", p.fk_mode_reglement";
1574 $sql .=
', p.fk_account';
1575 $sql .=
", p.fk_shipping_method";
1576 $sql .=
", p.fk_warehouse";
1577 $sql .=
", p.fk_incoterms, p.location_incoterms";
1578 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1579 $sql .=
", p.tms as date_modification";
1580 $sql .=
", i.libelle as label_incoterms";
1581 $sql .=
", c.label as statut_label";
1582 $sql .=
", ca.code as availability_code, ca.label as availability";
1583 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1584 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1585 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1586 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1587 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1588 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1589 $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').
')';
1590 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1591 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1592 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1595 if (!empty($forceentity)) {
1596 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1598 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1600 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1603 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1606 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1607 $resql = $this->db->query($sql);
1609 if ($this->db->num_rows($resql)) {
1610 $obj = $this->db->fetch_object($resql);
1612 $this->
id = $obj->rowid;
1613 $this->entity = $obj->entity;
1615 $this->
ref = $obj->ref;
1616 $this->ref_client = $obj->ref_client;
1617 $this->ref_customer = $obj->ref_client;
1618 $this->ref_ext = $obj->ref_ext;
1620 $this->total = $obj->total_ttc;
1621 $this->total_ttc = $obj->total_ttc;
1622 $this->total_ht = $obj->total_ht;
1623 $this->total_tva = $obj->total_tva;
1624 $this->total_localtax1 = $obj->localtax1;
1625 $this->total_localtax2 = $obj->localtax2;
1627 $this->socid = $obj->fk_soc;
1628 $this->thirdparty =
null;
1630 $this->fk_project = $obj->fk_project;
1631 $this->project =
null;
1633 $this->model_pdf = $obj->model_pdf;
1634 $this->last_main_doc = $obj->last_main_doc;
1635 $this->note = $obj->note_private;
1636 $this->note_private = $obj->note_private;
1637 $this->note_public = $obj->note_public;
1639 $this->
status = (int) $obj->fk_statut;
1640 $this->
statut = $this->status;
1642 $this->datec = $this->db->jdate($obj->datec);
1643 $this->datev = $this->db->jdate($obj->datev);
1644 $this->date_creation = $this->db->jdate($obj->datec);
1645 $this->date_validation = $this->db->jdate($obj->datev);
1646 $this->date_modification = $this->db->jdate($obj->date_modification);
1647 $this->date_signature = $this->db->jdate($obj->dates);
1648 $this->date = $this->db->jdate($obj->dp);
1649 $this->datep = $this->db->jdate($obj->dp);
1650 $this->fin_validite = $this->db->jdate($obj->dfv);
1651 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1652 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1653 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1654 $this->availability_id = $obj->fk_availability;
1655 $this->availability_code = $obj->availability_code;
1657 $this->demand_reason_id = $obj->fk_input_reason;
1658 $this->demand_reason_code = $obj->demand_reason_code;
1660 $this->fk_address = $obj->fk_delivery_address;
1662 $this->mode_reglement_id = $obj->fk_mode_reglement;
1663 $this->mode_reglement_code = $obj->mode_reglement_code;
1664 $this->mode_reglement = $obj->mode_reglement;
1665 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1666 $this->cond_reglement_id = $obj->fk_cond_reglement;
1667 $this->cond_reglement_code = $obj->cond_reglement_code;
1668 $this->cond_reglement = $obj->cond_reglement;
1669 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1670 $this->deposit_percent = $obj->deposit_percent;
1672 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1674 $this->user_author_id = $obj->fk_user_author;
1675 $this->user_validation_id = $obj->fk_user_valid;
1676 $this->user_closing_id = $obj->fk_user_cloture;
1679 $this->fk_incoterms = $obj->fk_incoterms;
1680 $this->location_incoterms = $obj->location_incoterms;
1681 $this->label_incoterms = $obj->label_incoterms;
1684 $this->fk_multicurrency = $obj->fk_multicurrency;
1685 $this->multicurrency_code = $obj->multicurrency_code;
1686 $this->multicurrency_tx = $obj->multicurrency_tx;
1687 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1688 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1689 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1695 $this->db->free($resql);
1697 $this->lines = array();
1708 $this->error =
"Record Not Found";
1711 $this->error = $this->db->lasterror();
1730 if (isset($this->
ref)) {
1731 $this->
ref = trim($this->
ref);
1733 if (isset($this->ref_client)) {
1734 $this->ref_client = trim($this->ref_client);
1736 if (isset($this->note) || isset($this->note_private)) {
1737 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1739 if (isset($this->note_public)) {
1740 $this->note_public = trim($this->note_public);
1742 if (isset($this->model_pdf)) {
1743 $this->model_pdf = trim($this->model_pdf);
1745 if (isset($this->import_key)) {
1746 $this->import_key = trim($this->import_key);
1748 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1749 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1756 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1757 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1758 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1759 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1760 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1761 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1762 if (!empty($this->fin_validite)) {
1763 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1765 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1766 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1767 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1768 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1769 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1770 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1771 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->
statut :
"null").
",";
1772 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1773 $sql .=
" fk_user_valid=".(isset($this->user_validation_id) ? $this->user_validation_id :
"null").
",";
1774 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1775 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1776 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1777 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1778 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1779 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1780 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1781 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1782 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1783 $sql .=
" WHERE rowid=".((int) $this->
id);
1787 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1788 $resql = $this->db->query($sql);
1791 $this->errors[] =
"Error ".$this->db->lasterror();
1801 if (!$error && !$notrigger) {
1812 foreach ($this->errors as $errmsg) {
1813 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1814 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1816 $this->db->rollback();
1819 $this->db->commit();
1834 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $sqlforgedfilters =
'')
1837 $this->lines = array();
1839 $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,';
1840 $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,';
1841 $sql .=
' d.fk_unit,';
1842 $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,';
1843 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1844 $sql .=
' d.date_start, d.date_end,';
1845 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1846 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1847 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1848 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1849 if ($only_product) {
1850 $sql .=
' AND p.fk_product_type = 0';
1852 if ($sqlforgedfilters) {
1853 $sql .= $sqlforgedfilters;
1855 $sql .=
' ORDER by d.rang';
1857 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1858 $result = $this->db->query($sql);
1860 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1862 $num = $this->db->num_rows($result);
1866 $objp = $this->db->fetch_object($result);
1870 $line->rowid = $objp->rowid;
1871 $line->id = $objp->rowid;
1872 $line->fk_propal = $objp->fk_propal;
1873 $line->fk_parent_line = $objp->fk_parent_line;
1874 $line->product_type = $objp->product_type;
1875 $line->label = $objp->custom_label;
1876 $line->desc = $objp->description;
1877 $line->description = $objp->description;
1878 $line->qty = $objp->qty;
1879 $line->vat_src_code = $objp->vat_src_code;
1880 $line->tva_tx = $objp->tva_tx;
1881 $line->localtax1_tx = $objp->localtax1_tx;
1882 $line->localtax2_tx = $objp->localtax2_tx;
1883 $line->localtax1_type = $objp->localtax1_type;
1884 $line->localtax2_type = $objp->localtax2_type;
1885 $line->subprice = $objp->subprice;
1886 $line->fk_remise_except = $objp->fk_remise_except;
1887 $line->remise_percent = $objp->remise_percent;
1888 $line->price = $objp->price;
1890 $line->info_bits = $objp->info_bits;
1891 $line->total_ht = $objp->total_ht;
1892 $line->total_tva = $objp->total_tva;
1893 $line->total_localtax1 = $objp->total_localtax1;
1894 $line->total_localtax2 = $objp->total_localtax2;
1895 $line->total_ttc = $objp->total_ttc;
1896 $line->fk_fournprice = $objp->fk_fournprice;
1897 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1898 $line->pa_ht = $marginInfos[0];
1899 $line->marge_tx = $marginInfos[1];
1900 $line->marque_tx = $marginInfos[2];
1901 $line->special_code = $objp->special_code;
1902 $line->rang = $objp->rang;
1904 $line->fk_product = $objp->fk_product;
1906 $line->ref = $objp->product_ref;
1907 $line->libelle = $objp->product_label;
1909 $line->product_ref = $objp->product_ref;
1910 $line->product_label = $objp->product_label;
1911 $line->product_desc = $objp->product_desc;
1912 $line->product_tobatch = $objp->product_tobatch;
1913 $line->product_barcode = $objp->product_barcode;
1915 $line->fk_product_type = $objp->fk_product_type;
1916 $line->fk_unit = $objp->fk_unit;
1917 $line->weight = $objp->weight;
1918 $line->weight_units = $objp->weight_units;
1919 $line->volume = $objp->volume;
1920 $line->volume_units = $objp->volume_units;
1922 $line->date_start = $this->db->jdate($objp->date_start);
1923 $line->date_end = $this->db->jdate($objp->date_end);
1926 $line->fk_multicurrency = $objp->fk_multicurrency;
1927 $line->multicurrency_code = $objp->multicurrency_code;
1928 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1929 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1930 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1931 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1933 $line->fetch_optionals();
1936 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1937 $tmpproduct =
new Product($this->db);
1938 $tmpproduct->fetch($objp->fk_product);
1939 $tmpproduct->getMultiLangs();
1941 $line->multilangs = $tmpproduct->multilangs;
1944 $this->lines[$i] = $line;
1949 $this->db->free($result);
1953 $this->error = $this->db->lasterror();
1965 public function valid($user, $notrigger = 0)
1969 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1974 if ($this->
statut == self::STATUS_VALIDATED) {
1975 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1979 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'creer'))
1980 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'propal_advance',
'validate')))) {
1981 $this->error =
'ErrorPermissionDenied';
1982 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
1991 $soc =
new Societe($this->db);
1992 $soc->fetch($this->socid);
1995 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2002 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2003 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2004 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2007 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2008 $resql = $this->db->query($sql);
2015 if (!$error && !$notrigger) {
2017 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2025 $this->oldref = $this->ref;
2028 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2030 $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).
"'";
2031 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2032 $resql = $this->db->query($sql);
2035 $this->error = $this->db->lasterror();
2037 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2038 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2039 $resql = $this->db->query($sql);
2042 $this->error = $this->db->lasterror();
2048 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2049 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2050 if (!$error && file_exists($dirsource)) {
2051 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2052 if (@rename($dirsource, $dirdest)) {
2055 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2056 foreach ($listoffiles as $fileentry) {
2057 $dirsource = $fileentry[
'name'];
2058 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2059 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2060 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2061 @rename($dirsource, $dirdest);
2070 $this->user_validation_id = $user->id;
2071 $this->datev = $now;
2072 $this->date_validation = $now;
2074 $this->db->commit();
2077 $this->db->rollback();
2096 $this->error =
'ErrorBadParameter';
2097 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2101 if ($user->hasRight(
'propal',
'creer')) {
2106 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2107 $sql .=
" WHERE rowid = ".((int) $this->
id);
2110 $resql = $this->db->query($sql);
2112 $this->errors[] = $this->db->error();
2117 $this->oldcopy = clone $this;
2118 $this->date = $date;
2119 $this->datep = $date;
2122 if (!$notrigger && empty($error)) {
2132 $this->db->commit();
2135 foreach ($this->errors as $errmsg) {
2136 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2137 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2139 $this->db->rollback();
2159 if ($user->hasRight(
'propal',
'creer')) {
2164 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2165 $sql .=
" WHERE rowid = ".((int) $this->
id);
2169 $resql = $this->db->query($sql);
2171 $this->errors[] = $this->db->error();
2177 $this->oldcopy = clone $this;
2178 $this->fin_validite = $date_end_validity;
2181 if (!$notrigger && empty($error)) {
2191 $this->db->commit();
2194 foreach ($this->errors as $errmsg) {
2195 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2196 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2198 $this->db->rollback();
2232 if ($user->hasRight(
'propal',
'creer')) {
2237 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2238 $sql .=
" SET date_livraison = ".($delivery_date !=
'' ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2239 $sql .=
" WHERE rowid = ".((int) $this->
id);
2242 $resql = $this->db->query($sql);
2244 $this->errors[] = $this->db->error();
2249 $this->oldcopy = clone $this;
2250 $this->delivery_date = $delivery_date;
2253 if (!$notrigger && empty($error)) {
2263 $this->db->commit();
2266 foreach ($this->errors as $errmsg) {
2267 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2268 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2270 $this->db->rollback();
2290 if ($user->hasRight(
'propal',
'creer') && $this->statut >= self::STATUS_DRAFT) {
2295 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2296 $sql .=
" SET fk_availability = ".((int) $id);
2297 $sql .=
" WHERE rowid = ".((int) $this->
id);
2299 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2300 $resql = $this->db->query($sql);
2302 $this->errors[] = $this->db->error();
2307 $this->oldcopy = clone $this;
2308 $this->fk_availability = $id;
2309 $this->availability_id = $id;
2312 if (!$notrigger && empty($error)) {
2322 $this->db->commit();
2325 foreach ($this->errors as $errmsg) {
2326 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2327 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2329 $this->db->rollback();
2333 $error_str =
'Propal status do not meet requirement '.$this->statut;
2335 $this->error = $error_str;
2336 $this->errors[] = $this->error;
2353 if ($user->hasRight(
'propal',
'creer') && $this->statut >= self::STATUS_DRAFT) {
2358 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2359 $sql .=
" SET fk_input_reason = ".((int) $id);
2360 $sql .=
" WHERE rowid = ".((int) $this->
id);
2363 $resql = $this->db->query($sql);
2365 $this->errors[] = $this->db->error();
2371 $this->oldcopy = clone $this;
2373 $this->demand_reason_id = $id;
2377 if (!$notrigger && empty($error)) {
2387 $this->db->commit();
2390 foreach ($this->errors as $errmsg) {
2391 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2392 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2394 $this->db->rollback();
2398 $error_str =
'Propal status do not meet requirement '.$this->statut;
2400 $this->error = $error_str;
2401 $this->errors[] = $this->error;
2418 if ($user->hasRight(
'propal',
'creer')) {
2423 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2424 $sql .=
" WHERE rowid = ".((int) $this->
id);
2426 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2427 $resql = $this->db->query($sql);
2429 $this->errors[] = $this->db->error();
2434 $this->oldcopy = clone $this;
2435 $this->ref_client = $ref_client;
2438 if (!$notrigger && empty($error)) {
2448 $this->db->commit();
2451 foreach ($this->errors as $errmsg) {
2452 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2453 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2455 $this->db->rollback();
2607 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2608 $sql .=
" SET fk_statut = ".((int) $status).
",";
2609 if (!empty(
$note)) {
2610 $sql .=
" note_private = '".$this->db->escape(
$note).
"',";
2612 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2613 $sql .=
" WHERE rowid = ".((int) $this->
id);
2617 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2618 $resql = $this->db->query($sql);
2621 $this->errors[] =
"Error ".$this->db->lasterror();
2636 if (!empty($this->errors)) {
2637 foreach ($this->errors as $errmsg) {
2638 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2639 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2642 $this->db->rollback();
2648 $this->db->commit();
2664 global $langs,$conf;
2674 $date_signature = $now;
2675 $fk_user_signature = $user->id;
2677 $this->
info($this->
id);
2678 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2679 $date_signature = $now;
2680 $fk_user_signature = $user->id;
2682 $date_signature = $this->date_signature;
2683 $fk_user_signature = $this->user_signature->id;
2687 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2688 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"'";
2689 if ($status == self::STATUS_SIGNED) {
2690 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2692 $sql .=
" WHERE rowid = ".((int) $this->
id);
2694 $resql = $this->db->query($sql);
2697 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_CLOSED') ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2698 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2700 if ($status == self::STATUS_SIGNED) {
2701 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2702 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_TOBILL') ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2706 $soc->id = $this->socid;
2707 $result = $soc->setAsCustomer();
2710 $this->error=$this->db->lasterror();
2711 $this->db->rollback();
2718 $outputlangs = $langs;
2720 $outputlangs =
new Translate(
"", $conf);
2721 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2722 $outputlangs->setDefaultLang($newlang);
2731 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2735 $this->oldcopy= clone $this;
2738 $this->date_signature = $date_signature;
2739 $this->note_private = $newprivatenote;
2742 if (!$notrigger && empty($error)) {
2752 $this->db->commit();
2755 $this->
statut = $this->oldcopy->statut;
2756 $this->
status = $this->oldcopy->statut;
2757 $this->date_signature = $this->oldcopy->date_signature;
2758 $this->note_private = $this->oldcopy->note_private;
2760 $this->db->rollback();
2764 $this->error = $this->db->lasterror();
2765 $this->db->rollback();
2780 global $conf, $langs;
2787 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2793 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2794 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2795 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2798 $resql = $this->db->query($sql);
2800 $this->errors[] = $this->db->error();
2803 $num = $this->db->affected_rows($resql);
2807 $modelpdf = $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2811 $outputlangs = $langs;
2813 $outputlangs =
new Translate(
"", $conf);
2814 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2815 $outputlangs->setDefaultLang($newlang);
2824 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2827 $this->oldcopy = clone $this;
2829 $this->date_cloture = $now;
2830 $this->note_private = $newprivatenote;
2833 if (!$notrigger && empty($error)) {
2843 $this->db->commit();
2846 foreach ($this->errors as $errmsg) {
2847 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2848 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2850 $this->db->rollback();
2869 if ($this->
statut <= self::STATUS_DRAFT) {
2873 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2877 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2878 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2879 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2880 $sql .=
" WHERE rowid = ".((int) $this->
id);
2882 $resql = $this->db->query($sql);
2884 $this->errors[] = $this->db->error();
2889 $this->oldcopy = clone $this;
2892 if (!$notrigger && empty($error)) {
2905 $this->db->commit();
2908 foreach ($this->errors as $errmsg) {
2909 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2910 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2912 $this->db->rollback();
2932 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2939 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2940 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2941 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2942 if (!$user->hasRight(
'societe',
'client',
'voir') && !$socid) {
2943 $sql .=
", sc.fk_soc, sc.fk_user";
2945 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2946 if (!$user->hasRight(
'societe',
'client',
'voir') && !$socid) {
2947 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
2949 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2950 $sql .=
" AND p.fk_soc = s.rowid";
2951 $sql .=
" AND p.fk_statut = c.id";
2952 if (!$user->hasRight(
'societe',
'client',
'voir') && !$socid) {
2953 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
2956 $sql .=
" AND s.rowid = ".((int) $socid);
2959 $sql .=
" AND p.fk_statut = ".self::STATUS_DRAFT;
2961 if ($notcurrentuser > 0) {
2962 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2964 $sql .= $this->db->order($sortfield, $sortorder);
2965 $sql .= $this->db->plimit($limit, $offset);
2967 $result = $this->db->query($sql);
2969 $num = $this->db->num_rows($result);
2973 $obj = $this->db->fetch_object($result);
2975 if ($shortlist == 1) {
2976 $ga[$obj->propalid] = $obj->ref;
2977 } elseif ($shortlist == 2) {
2978 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2980 $ga[$i][
'id'] = $obj->propalid;
2981 $ga[$i][
'ref'] = $obj->ref;
2982 $ga[$i][
'name'] = $obj->name;
3016 $linkedInvoices = array();
3019 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
3022 foreach ($objectid as $key => $object) {
3024 if ($objecttype ==
'facture') {
3025 $linkedInvoices[] = $object;
3029 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
3030 foreach ($subobjectid as $subkey => $subobject) {
3031 if ($subobjecttype ==
'facture') {
3032 $linkedInvoices[] = $subobject;
3040 if (count($linkedInvoices) > 0) {
3041 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
3042 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
3043 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
3045 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
3046 $resql = $this->db->query($sql);
3049 $tab_sqlobj = array();
3050 $nump = $this->db->num_rows($resql);
3051 for ($i = 0; $i < $nump; $i++) {
3052 $sqlobj = $this->db->fetch_object($resql);
3053 $tab_sqlobj[] = $sqlobj;
3055 $this->db->free($resql);
3057 $nump = count($tab_sqlobj);
3061 while ($i < $nump) {
3062 $obj = array_shift($tab_sqlobj);
3085 public function delete($user, $notrigger = 0)
3088 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3104 if (!$error && !empty($this->table_element_line)) {
3105 $tabletodelete = $this->table_element_line;
3106 $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).
")";
3107 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3108 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3110 $this->error = $this->db->lasterror();
3111 $this->errors[] = $this->error;
3112 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3137 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3143 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3144 $res = $this->db->query($sql);
3147 $this->error = $this->db->lasterror();
3148 $this->errors[] = $this->error;
3149 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3165 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3166 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3167 $file = $dir.
"/".$ref.
".pdf";
3168 if (file_exists($file)) {
3172 $this->error =
'ErrorFailToDeleteFile';
3173 $this->errors[] = $this->error;
3174 $this->db->rollback();
3178 if (file_exists($dir)) {
3181 $this->error =
'ErrorFailToDeleteDir';
3182 $this->errors[] = $this->error;
3183 $this->db->rollback();
3191 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3192 $this->db->commit();
3195 $this->db->rollback();
3212 if ($this->
statut >= self::STATUS_DRAFT) {
3217 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3218 $sql .=
' SET fk_availability = '.((int) $availability_id);
3219 $sql .=
' WHERE rowid='.((int) $this->
id);
3221 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3222 $resql = $this->db->query($sql);
3224 $this->errors[] = $this->db->error();
3229 $this->oldcopy = clone $this;
3230 $this->availability_id = $availability_id;
3233 if (!$notrigger && empty($error)) {
3243 $this->db->commit();
3246 foreach ($this->errors as $errmsg) {
3247 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3248 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3250 $this->db->rollback();
3254 $error_str =
'Propal status do not meet requirement '.$this->statut;
3256 $this->error = $error_str;
3257 $this->errors[] = $this->error;
3276 if ($this->
status >= self::STATUS_DRAFT) {
3281 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3282 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3283 $sql .=
' WHERE rowid='.((int) $this->
id);
3285 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3286 $resql = $this->db->query($sql);
3288 $this->errors[] = $this->db->error();
3293 $this->oldcopy = clone $this;
3294 $this->demand_reason_id = $demand_reason_id;
3297 if (!$notrigger && empty($error)) {
3307 $this->db->commit();
3310 foreach ($this->errors as $errmsg) {
3311 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3312 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3314 $this->db->rollback();
3318 $error_str =
'Propal status do not meet requirement '.$this->statut;
3320 $this->error = $error_str;
3321 $this->errors[] = $this->error;
3335 $sql =
"SELECT c.rowid, ";
3336 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3337 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3338 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3339 $sql .=
" WHERE c.rowid = ".((int) $id);
3341 $result = $this->db->query($sql);
3344 if ($this->db->num_rows($result)) {
3345 $obj = $this->db->fetch_object($result);
3347 $this->
id = $obj->rowid;
3349 $this->date_creation = $this->db->jdate($obj->datec);
3350 $this->date_validation = $this->db->jdate($obj->datev);
3351 $this->date_signature = $this->db->jdate($obj->date_signature);
3352 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3354 $this->user_creation_id = $obj->fk_user_author;
3355 $this->user_validation_id = $obj->fk_user_valid;
3357 if ($obj->fk_user_signature) {
3358 $user_signature =
new User($this->db);
3359 $user_signature->fetch($obj->fk_user_signature);
3360 $this->user_signature = $user_signature;
3363 $this->user_closing_id = $obj->fk_user_cloture;
3365 $this->db->free($result);
3394 global $conf, $hookmanager;
3397 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3399 $langs->load(
"propal");
3400 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3401 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3402 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3403 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3404 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3405 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3406 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3407 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3408 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3409 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3413 if ($status == self::STATUS_DRAFT) {
3414 $statusType =
'status0';
3415 } elseif ($status == self::STATUS_VALIDATED) {
3416 $statusType =
'status1';
3417 } elseif ($status == self::STATUS_SIGNED) {
3418 $statusType =
'status4';
3419 } elseif ($status == self::STATUS_NOTSIGNED) {
3420 $statusType =
'status9';
3421 } elseif ($status == self::STATUS_BILLED) {
3422 $statusType =
'status6';
3426 $parameters = array(
'status' => $status,
'mode' => $mode);
3427 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3430 return $hookmanager->resPrint;
3433 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3448 global $conf, $langs;
3452 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3453 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3454 if (!$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
3455 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
3456 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3459 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3460 if ($mode ==
'opened') {
3461 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3463 if ($mode ==
'signed') {
3464 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3467 $sql .=
" AND p.fk_soc = ".((int) $user->socid);
3470 $resql = $this->db->query($sql);
3472 $langs->load(
"propal");
3477 $label = $labelShort =
'';
3478 if ($mode ==
'opened') {
3479 $delay_warning = $conf->propal->cloture->warning_delay;
3481 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3482 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3484 if ($mode ==
'signed') {
3485 $delay_warning = $conf->propal->facturation->warning_delay;
3487 $label = $langs->trans(
"PropalsToBill");
3488 $labelShort = $langs->trans(
"ToBill");
3492 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3493 $response->label = $label;
3494 $response->labelShort = $labelShort;
3495 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3496 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3500 while ($obj = $this->db->fetch_object($resql)) {
3501 $response->nbtodo++;
3502 $response->total += $obj->total_ht;
3504 if ($mode ==
'opened') {
3505 $datelimit = $this->db->jdate($obj->datefin);
3506 if ($datelimit < ($now - $delay_warning)) {
3507 $response->nbtodolate++;
3516 $this->error = $this->db->error();
3531 global $conf, $langs;
3536 $sql =
"SELECT rowid";
3537 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3538 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3539 $sql .= $this->db->plimit(100);
3541 $resql = $this->db->query($sql);
3543 $num_prods = $this->db->num_rows($resql);
3545 while ($i < $num_prods) {
3547 $row = $this->db->fetch_row($resql);
3548 $prodids[$i] = $row[0];
3554 $this->
ref =
'SPECIMEN';
3555 $this->ref_client =
'NEMICEPS';
3556 $this->specimen = 1;
3558 $this->date = time();
3559 $this->fin_validite = $this->date + 3600 * 24 * 30;
3560 $this->cond_reglement_id = 1;
3561 $this->cond_reglement_code =
'RECEP';
3562 $this->mode_reglement_id = 7;
3563 $this->mode_reglement_code =
'CHQ';
3564 $this->availability_id = 1;
3565 $this->availability_code =
'AV_NOW';
3566 $this->demand_reason_id = 1;
3567 $this->demand_reason_code =
'SRC_00';
3568 $this->note_public =
'This is a comment (public)';
3569 $this->note_private =
'This is a comment (private)';
3571 $this->multicurrency_tx = 1;
3572 $this->multicurrency_code = $conf->currency;
3577 while ($xnbp < $nbp) {
3579 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3581 $line->subprice = 100;
3584 $line->localtax1_tx = 0;
3585 $line->localtax2_tx = 0;
3587 $line->total_ht = 50;
3588 $line->total_ttc = 60;
3589 $line->total_tva = 10;
3590 $line->remise_percent = 50;
3592 $line->total_ht = 100;
3593 $line->total_ttc = 120;
3594 $line->total_tva = 20;
3595 $line->remise_percent = 00;
3598 if ($num_prods > 0) {
3599 $prodid = mt_rand(1, $num_prods);
3600 $line->fk_product = $prodids[$prodid];
3601 $line->product_ref =
'SPECIMEN';
3604 $this->lines[$xnbp] = $line;
3606 $this->total_ht += $line->total_ht;
3607 $this->total_tva += $line->total_tva;
3608 $this->total_ttc += $line->total_ttc;
3625 $this->nb = array();
3628 $sql =
"SELECT count(p.rowid) as nb";
3629 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3630 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3631 if (!$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
3632 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3633 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3636 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3638 $resql = $this->db->query($sql);
3641 while ($obj = $this->db->fetch_object($resql)) {
3642 $this->nb[
"proposals"] = $obj->nb;
3644 $this->db->free($resql);
3648 $this->error = $this->db->error();
3663 global $conf, $langs;
3664 $langs->load(
"propal");
3666 $classname = $conf->global->PROPALE_ADDON;
3668 if (!empty($classname)) {
3671 $file = $classname.
".php";
3674 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3675 foreach ($dirmodels as $reldir) {
3679 $mybool |= @include_once $dir.$file;
3687 $obj =
new $classname();
3689 $numref = $obj->getNextValue($soc, $this);
3691 if ($numref !=
"") {
3694 $this->error = $obj->error;
3699 $langs->load(
"errors");
3700 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3713 global $conf, $langs, $user;
3715 $langs->load(
'propal');
3717 $nofetch = !empty($params[
'nofetch']);
3720 return [
'optimize' => $langs->trans(
"Proposal")];
3722 if ($user->hasRight(
'propal',
'lire')) {
3723 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3724 if (isset($this->
statut)) {
3725 $datas[
'status'] =
' '.$this->getLibStatut(5);
3727 if (!empty($this->
ref)) {
3728 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3731 $langs->load(
'companies');
3732 if (empty($this->thirdparty)) {
3735 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3737 if (!empty($this->ref_client)) {
3738 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_client;
3741 $langs->load(
'project');
3742 if (empty($this->project)) {
3745 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3749 if (!empty($this->total_ht)) {
3750 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3752 if (!empty($this->total_tva)) {
3753 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3755 if (!empty($this->total_ttc)) {
3756 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3758 if (!empty($this->date)) {
3759 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3761 if (!empty($this->delivery_date)) {
3762 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3780 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3782 global $langs, $conf, $user, $hookmanager;
3784 if (!empty($conf->dol_no_mouse_hover)) {
3791 'objecttype' => $this->element,
3792 'option' => $option,
3795 $classfortooltip =
'classfortooltip';
3798 $classfortooltip =
'classforajaxtooltip';
3799 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3806 if ($user->hasRight(
'propal',
'lire')) {
3807 if ($option ==
'') {
3808 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3809 } elseif ($option ==
'compta') {
3810 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3811 } elseif ($option ==
'expedition') {
3812 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3813 } elseif ($option ==
'document') {
3814 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3817 if ($option !=
'nolink') {
3819 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3820 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3821 $add_save_lastsearch_values = 1;
3823 if ($add_save_lastsearch_values) {
3824 $url .=
'&save_lastsearch_values=1';
3830 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3832 $label = $langs->trans(
"Proposal");
3833 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3835 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3836 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3839 $linkstart =
'<a href="'.$url.
'"';
3840 $linkstart .= $linkclose.
'>';
3843 $result .= $linkstart;
3845 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3847 if ($withpicto != 2) {
3848 $result .= $this->ref;
3850 $result .= $linkend;
3852 if ($addlinktonotes >= 0) {
3855 if ($addlinktonotes == 0) {
3856 if (!empty($this->note_private) || !empty($this->note_public)) {
3857 $txttoshow = $langs->trans(
'ViewPrivateNote');
3859 } elseif ($addlinktonotes == 1) {
3860 if (!empty($this->note_private)) {
3863 } elseif ($addlinktonotes == 2) {
3864 if (!empty($this->note_public)) {
3867 } elseif ($addlinktonotes == 3) {
3868 if ($user->socid > 0) {
3869 if (!empty($this->note_public)) {
3873 if (!empty($this->note_public)) {
3876 if (!empty($this->note_private)) {
3877 if (!empty($txttoshow)) {
3878 $txttoshow .=
'<br><br>';
3886 $result .=
' <span class="note inline-block">';
3887 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3890 $result .=
'</span>';
3895 $hookmanager->initHooks(array($this->element .
'dao'));
3896 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
3897 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3899 $result = $hookmanager->resPrint;
3901 $result .= $hookmanager->resPrint;
3914 return $this->
fetch_lines(0, 0, $sqlforgedfilters);
3928 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3930 global $conf, $langs;
3932 $langs->load(
"propale");
3933 $outputlangs->load(
"products");
3938 if ($this->model_pdf) {
3939 $modele = $this->model_pdf;
3941 $modele = $conf->global->PROPALE_ADDON_PDF;
3945 $modelpath =
"core/modules/propale/doc/";
3947 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3995 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
3997 $return =
'<div class="box-flex-item box-flex-grow-zero">';
3998 $return .=
'<div class="info-box info-box-sm">';
3999 $return .=
'<span class="info-box-icon bg-infobox-action">';
4001 $return .=
'</span>';
4002 $return .=
'<div class="info-box-content">';
4003 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
4004 if ($selected >= 0) {
4005 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
4007 if (!empty($arraydata[
'projectlink'])) {
4008 $return .=
'<span class="info-box-ref"> | '.$arraydata[
'projectlink'].
'</span>';
4010 if (!empty($arraydata[
'authorlink'])) {
4011 $return .=
'<br><span class="info-box-label">'.$arraydata[
'authorlink'].
'</span>';
4013 if (property_exists($this,
'total_ht')) {
4014 $return .=
'<br><span class="info-box-label amount" title="'.$langs->trans(
"AmountHT").
'">'.
price($this->total_ht).
'</span>';
4016 if (method_exists($this,
'getLibStatut')) {
4017 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
4019 $return .=
'</div>';
4020 $return .=
'</div>';
4021 $return .=
'</div>';
4034 public $element =
'propaldet';
4039 public $table_element =
'propaldet';
4045 public $fk_parent_line;
4063 public $vat_src_code;
4066 public $remise_percent;
4067 public $fk_remise_except;
4071 public $fk_fournprice;
4076 public $special_code;
4081 public $info_bits = 0;
4110 public $product_ref;
4125 public $product_label;
4130 public $product_desc;
4136 public $product_tobatch;
4142 public $product_barcode;
4144 public $localtax1_tx;
4145 public $localtax2_tx;
4146 public $localtax1_type;
4147 public $localtax2_type;
4148 public $total_localtax1;
4149 public $total_localtax2;
4154 public $skip_update_total;
4157 public $fk_multicurrency;
4158 public $multicurrency_code;
4159 public $multicurrency_subprice;
4160 public $multicurrency_total_ht;
4161 public $multicurrency_total_tva;
4162 public $multicurrency_total_ttc;
4183 $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,';
4184 $sql .=
' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
4185 $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,';
4186 $sql .=
' pd.fk_unit,';
4187 $sql .=
' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,';
4188 $sql .=
' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,';
4189 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
4190 $sql .=
' pd.date_start, pd.date_end, pd.product_type';
4191 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as pd';
4192 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON pd.fk_product = p.rowid';
4193 $sql .=
' WHERE pd.rowid = '.((int) $rowid);
4195 $result = $this->db->query($sql);
4197 $objp = $this->db->fetch_object($result);
4200 $this->
id = $objp->rowid;
4201 $this->
rowid = $objp->rowid;
4202 $this->fk_propal = $objp->fk_propal;
4203 $this->fk_parent_line = $objp->fk_parent_line;
4204 $this->label = $objp->custom_label;
4205 $this->desc = $objp->description;
4206 $this->qty = $objp->qty;
4207 $this->
price = $objp->price;
4208 $this->subprice = $objp->subprice;
4209 $this->vat_src_code = $objp->vat_src_code;
4210 $this->tva_tx = $objp->tva_tx;
4211 $this->remise = $objp->remise;
4212 $this->remise_percent = $objp->remise_percent;
4213 $this->fk_remise_except = $objp->fk_remise_except;
4214 $this->fk_product = $objp->fk_product;
4215 $this->info_bits = $objp->info_bits;
4217 $this->total_ht = $objp->total_ht;
4218 $this->total_tva = $objp->total_tva;
4219 $this->total_ttc = $objp->total_ttc;
4221 $this->fk_fournprice = $objp->fk_fournprice;
4223 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
4224 $this->pa_ht = $marginInfos[0];
4225 $this->marge_tx = $marginInfos[1];
4226 $this->marque_tx = $marginInfos[2];
4228 $this->special_code = $objp->special_code;
4229 $this->product_type = $objp->product_type;
4230 $this->rang = $objp->rang;
4232 $this->
ref = $objp->product_ref;
4233 $this->product_ref = $objp->product_ref;
4234 $this->libelle = $objp->product_label;
4235 $this->product_label = $objp->product_label;
4236 $this->product_desc = $objp->product_desc;
4237 $this->fk_unit = $objp->fk_unit;
4239 $this->date_start = $this->db->jdate($objp->date_start);
4240 $this->date_end = $this->db->jdate($objp->date_end);
4243 $this->fk_multicurrency = $objp->fk_multicurrency;
4244 $this->multicurrency_code = $objp->multicurrency_code;
4245 $this->multicurrency_subprice = $objp->multicurrency_subprice;
4246 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
4247 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
4248 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
4252 $this->db->free($result);
4271 global $conf, $user;
4275 dol_syslog(get_class($this).
"::insert rang=".$this->rang);
4277 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4280 if (empty($this->tva_tx)) {
4283 if (empty($this->localtax1_tx)) {
4284 $this->localtax1_tx = 0;
4286 if (empty($this->localtax2_tx)) {
4287 $this->localtax2_tx = 0;
4289 if (empty($this->localtax1_type)) {
4290 $this->localtax1_type = 0;
4292 if (empty($this->localtax2_type)) {
4293 $this->localtax2_type = 0;
4295 if (empty($this->total_localtax1)) {
4296 $this->total_localtax1 = 0;
4298 if (empty($this->total_localtax2)) {
4299 $this->total_localtax2 = 0;
4301 if (empty($this->rang)) {
4304 if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) {
4305 $this->remise_percent = 0;
4307 if (empty($this->info_bits)) {
4308 $this->info_bits = 0;
4310 if (empty($this->special_code)) {
4311 $this->special_code = 0;
4313 if (empty($this->fk_parent_line)) {
4314 $this->fk_parent_line = 0;
4316 if (empty($this->fk_fournprice)) {
4317 $this->fk_fournprice = 0;
4319 if (!is_numeric($this->qty)) {
4322 if (empty($this->pa_ht)) {
4325 if (empty($this->multicurrency_subprice)) {
4326 $this->multicurrency_subprice = 0;
4328 if (empty($this->multicurrency_total_ht)) {
4329 $this->multicurrency_total_ht = 0;
4331 if (empty($this->multicurrency_total_tva)) {
4332 $this->multicurrency_total_tva = 0;
4334 if (empty($this->multicurrency_total_ttc)) {
4335 $this->multicurrency_total_ttc = 0;
4339 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4340 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4343 $this->pa_ht = $result;
4348 if ($this->product_type < 0) {
4355 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'propaldet';
4356 $sql .=
' (fk_propal, fk_parent_line, label, description, fk_product, product_type,';
4357 $sql .=
' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
4358 $sql .=
' subprice, remise_percent, ';
4359 $sql .=
' info_bits, ';
4360 $sql .=
' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,';
4361 $sql .=
' fk_unit,';
4362 $sql .=
' date_start, date_end';
4363 $sql .=
', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)';
4364 $sql .=
" VALUES (".$this->fk_propal.
",";
4365 $sql .=
" ".($this->fk_parent_line > 0 ?
"'".$this->db->escape($this->fk_parent_line).
"'" :
"null").
",";
4366 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
4367 $sql .=
" '".$this->db->escape($this->desc).
"',";
4368 $sql .=
" ".($this->fk_product ?
"'".$this->db->escape($this->fk_product).
"'" :
"null").
",";
4369 $sql .=
" '".$this->db->escape($this->product_type).
"',";
4370 $sql .=
" ".($this->fk_remise_except ?
"'".$this->db->escape($this->fk_remise_except).
"'" :
"null").
",";
4371 $sql .=
" ".price2num($this->qty,
'MS').
",";
4372 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
4373 $sql .=
" ".price2num($this->tva_tx).
",";
4374 $sql .=
" ".price2num($this->localtax1_tx).
",";
4375 $sql .=
" ".price2num($this->localtax2_tx).
",";
4376 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
4377 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
4378 $sql .=
" ".(price2num($this->subprice) !==
'' ?
price2num($this->subprice,
'MU') :
"null").
",";
4379 $sql .=
" ".price2num($this->remise_percent, 3).
",";
4380 $sql .=
" ".(isset($this->info_bits) ? ((int) $this->info_bits) :
"null").
",";
4381 $sql .=
" ".price2num($this->total_ht,
'MT').
",";
4382 $sql .=
" ".price2num($this->total_tva,
'MT').
",";
4383 $sql .=
" ".price2num($this->total_localtax1,
'MT').
",";
4384 $sql .=
" ".price2num($this->total_localtax2,
'MT').
",";
4385 $sql .=
" ".price2num($this->total_ttc,
'MT').
",";
4386 $sql .=
" ".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null").
",";
4387 $sql .=
" ".(isset($this->pa_ht) ?
"'".price2num($this->pa_ht).
"'" :
"null").
",";
4388 $sql .=
' '.((int) $this->special_code).
',';
4389 $sql .=
' '.((int) $this->rang).
',';
4390 $sql .=
' '.(empty($this->fk_unit) ?
'NULL' : ((int) $this->fk_unit)).
',';
4391 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
',';
4392 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4393 $sql .=
", ".($this->fk_multicurrency > 0 ? ((int) $this->fk_multicurrency) :
'null');
4394 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
4395 $sql .=
", ".price2num($this->multicurrency_subprice,
'CU');
4396 $sql .=
", ".price2num($this->multicurrency_total_ht,
'CT');
4397 $sql .=
", ".price2num($this->multicurrency_total_tva,
'CT');
4398 $sql .=
", ".price2num($this->multicurrency_total_ttc,
'CT');
4401 dol_syslog(get_class($this).
'::insert', LOG_DEBUG);
4402 $resql = $this->db->query($sql);
4404 $this->
rowid = $this->db->last_insert_id(MAIN_DB_PREFIX.
'propaldet');
4407 $this->
id = $this->rowid;
4414 if (!$error && !$notrigger) {
4416 $result = $this->
call_trigger(
'LINEPROPAL_INSERT', $user);
4418 $this->db->rollback();
4424 $this->db->commit();
4427 $this->error = $this->db->error().
" sql=".$sql;
4428 $this->db->rollback();
4440 public function delete(
User $user, $notrigger = 0)
4449 $result = $this->
call_trigger(
'LINEPROPAL_DELETE', $user);
4457 $sql =
"DELETE FROM " . MAIN_DB_PREFIX .
"propaldet WHERE rowid = " . ((int) $this->
rowid);
4458 dol_syslog(
"PropaleLigne::delete", LOG_DEBUG);
4459 if ($this->db->query($sql)) {
4462 $this->
id = $this->rowid;
4466 dol_syslog(get_class($this) .
"::delete error -4 " . $this->error, LOG_ERR);
4470 $this->error = $this->db->error() .
" sql=" . $sql;
4476 $this->db->rollback();
4479 $this->db->commit();
4492 global $conf, $user;
4496 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4498 if (empty($this->
id) && !empty($this->
rowid)) {
4499 $this->
id = $this->rowid;
4503 if (empty($this->tva_tx)) {
4506 if (empty($this->localtax1_tx)) {
4507 $this->localtax1_tx = 0;
4509 if (empty($this->localtax2_tx)) {
4510 $this->localtax2_tx = 0;
4512 if (empty($this->total_localtax1)) {
4513 $this->total_localtax1 = 0;
4515 if (empty($this->total_localtax2)) {
4516 $this->total_localtax2 = 0;
4518 if (empty($this->localtax1_type)) {
4519 $this->localtax1_type = 0;
4521 if (empty($this->localtax2_type)) {
4522 $this->localtax2_type = 0;
4524 if (empty($this->marque_tx)) {
4525 $this->marque_tx = 0;
4527 if (empty($this->marge_tx)) {
4528 $this->marge_tx = 0;
4530 if (empty($this->
price)) {
4533 if (empty($this->remise_percent)) {
4534 $this->remise_percent = 0;
4536 if (empty($this->info_bits)) {
4537 $this->info_bits = 0;
4539 if (empty($this->special_code)) {
4540 $this->special_code = 0;
4542 if (empty($this->fk_parent_line)) {
4543 $this->fk_parent_line = 0;
4545 if (empty($this->fk_fournprice)) {
4546 $this->fk_fournprice = 0;
4548 if (empty($this->subprice)) {
4549 $this->subprice = 0;
4551 if (empty($this->pa_ht)) {
4556 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4557 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4560 $this->pa_ht = $result;
4567 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4568 $sql .=
" description='".$this->db->escape($this->desc).
"'";
4569 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
4570 $sql .=
", product_type=".$this->product_type;
4571 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"'";
4572 $sql .=
", tva_tx='".price2num($this->tva_tx).
"'";
4573 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
4574 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
4575 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
4576 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
4577 $sql .=
", qty='".price2num($this->qty).
"'";
4578 $sql .=
", subprice=".price2num($this->subprice);
4579 $sql .=
", remise_percent=".price2num($this->remise_percent);
4581 $sql .=
", remise=".(float)
price2num($this->remise);
4582 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
4583 if (empty($this->skip_update_total)) {
4584 $sql .=
", total_ht=".price2num($this->total_ht);
4585 $sql .=
", total_tva=".price2num($this->total_tva);
4586 $sql .=
", total_ttc=".price2num($this->total_ttc);
4587 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
4588 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
4590 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
4591 $sql .=
", buy_price_ht=".price2num($this->pa_ht);
4592 if (strlen($this->special_code)) {
4593 $sql .=
", special_code=".$this->special_code;
4595 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
4596 if (!empty($this->rang)) {
4597 $sql .=
", rang=".((int) $this->rang);
4599 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
4600 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4601 $sql .=
", fk_unit=".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
4604 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
4605 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
4606 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
4607 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
4609 $sql .=
" WHERE rowid = ".((int) $this->
id);
4611 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
4612 $resql = $this->db->query($sql);
4621 if (!$error && !$notrigger) {
4623 $result = $this->
call_trigger(
'LINEPROPAL_MODIFY', $user);
4625 $this->db->rollback();
4631 $this->db->commit();
4634 $this->error = $this->db->error();
4635 $this->db->rollback();
4653 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4654 $sql .=
" total_ht=".price2num($this->total_ht,
'MT');
4655 $sql .=
",total_tva=".price2num($this->total_tva,
'MT');
4656 $sql .=
",total_ttc=".price2num($this->total_ttc,
'MT');
4657 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
4659 dol_syslog(
"PropaleLigne::update_total", LOG_DEBUG);
4661 $resql = $this->db->query($sql);
4663 $this->db->commit();
4666 $this->error = $this->db->error();
4667 $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.