42require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
43require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobjectline.class.php";
44require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
45require_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
46require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
47require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
48require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
65 public $element =
'propal';
70 public $table_element =
'propal';
75 public $table_element_line =
'propaldet';
80 public $fk_element =
'fk_propal';
85 public $picto =
'propal';
91 public $ismultientitymanaged = 1;
97 public $restrictiononfksoc = 1;
147 public $date_creation;
158 public $date_validation;
163 public $date_signature;
168 public $user_signature;
185 public $date_livraison;
190 public $delivery_date;
193 public $fin_validite;
195 public $user_author_id;
196 public $user_close_id;
214 public $cond_reglement_code;
215 public $cond_reglement_doc;
216 public $mode_reglement_code;
218 public $deposit_percent;
240 public $address_type;
243 public $availability_id;
244 public $availability_code;
246 public $duree_validite;
248 public $demand_reason_id;
249 public $demand_reason_code;
251 public $warehouse_id;
253 public $extraparams = array();
258 public $lines = array();
261 public $labelStatus = array();
262 public $labelStatusShort = array();
268 public $fk_multicurrency;
270 public $multicurrency_code;
271 public $multicurrency_tx;
272 public $multicurrency_total_ht;
273 public $multicurrency_total_tva;
274 public $multicurrency_total_ttc;
275 public $multicurrency_total_localtax1;
276 public $multicurrency_total_localtax2;
307 public $fields = array(
308 'rowid' =>array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>10),
309 'entity' =>array(
'type'=>
'integer',
'label'=>
'Entity',
'default'=>1,
'enabled'=>1,
'visible'=>-2,
'notnull'=>1,
'position'=>15,
'index'=>1),
310 'ref' =>array(
'type'=>
'varchar(30)',
'label'=>
'Ref',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'showoncombobox'=>1,
'position'=>20),
311 'ref_client' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefCustomer',
'enabled'=>1,
'visible'=>-1,
'position'=>22),
312 'ref_ext' =>array(
'type'=>
'varchar(255)',
'label'=>
'RefExt',
'enabled'=>1,
'visible'=>0,
'position'=>40),
313 'fk_soc' =>array(
'type'=>
'integer:Societe:societe/class/societe.class.php',
'label'=>
'ThirdParty',
'enabled'=>
'isModEnabled("societe")',
'visible'=>-1,
'position'=>23),
314 '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),
315 'tms' =>array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>25),
316 'datec' =>array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'enabled'=>1,
'visible'=>-1,
'position'=>55),
317 'datep' =>array(
'type'=>
'date',
'label'=>
'Date',
'enabled'=>1,
'visible'=>-1,
'position'=>60),
318 'fin_validite' =>array(
'type'=>
'datetime',
'label'=>
'DateEnd',
'enabled'=>1,
'visible'=>-1,
'position'=>65),
319 'date_valid' =>array(
'type'=>
'datetime',
'label'=>
'DateValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>70),
320 'date_cloture' =>array(
'type'=>
'datetime',
'label'=>
'DateClosing',
'enabled'=>1,
'visible'=>-1,
'position'=>75),
321 'fk_user_author' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Fk user author',
'enabled'=>1,
'visible'=>-1,
'position'=>80),
322 'fk_user_modif' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserModif',
'enabled'=>1,
'visible'=>-2,
'notnull'=>-1,
'position'=>85),
323 'fk_user_valid' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'UserValidation',
'enabled'=>1,
'visible'=>-1,
'position'=>90),
324 'fk_user_cloture' =>array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Fk user cloture',
'enabled'=>1,
'visible'=>-1,
'position'=>95),
325 'price' =>array(
'type'=>
'double',
'label'=>
'Price',
'enabled'=>1,
'visible'=>-1,
'position'=>105),
329 'total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalHT',
'enabled'=>1,
'visible'=>-1,
'position'=>125,
'isameasure'=>1),
330 'total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'VAT',
'enabled'=>1,
'visible'=>-1,
'position'=>130,
'isameasure'=>1),
331 'localtax1' =>array(
'type'=>
'double(24,8)',
'label'=>
'LocalTax1',
'enabled'=>1,
'visible'=>-1,
'position'=>135,
'isameasure'=>1),
332 'localtax2' =>array(
'type'=>
'double(24,8)',
'label'=>
'LocalTax2',
'enabled'=>1,
'visible'=>-1,
'position'=>140,
'isameasure'=>1),
333 'total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'TotalTTC',
'enabled'=>1,
'visible'=>-1,
'position'=>145,
'isameasure'=>1),
334 'fk_account' =>array(
'type'=>
'integer',
'label'=>
'BankAccount',
'enabled'=>
'isModEnabled("banque")',
'visible'=>-1,
'position'=>150),
335 'fk_currency' =>array(
'type'=>
'varchar(3)',
'label'=>
'Currency',
'enabled'=>1,
'visible'=>-1,
'position'=>155),
336 'fk_cond_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentTerm',
'enabled'=>1,
'visible'=>-1,
'position'=>160),
337 'deposit_percent' =>array(
'type'=>
'varchar(63)',
'label'=>
'DepositPercent',
'enabled'=>1,
'visible'=>-1,
'position'=>161),
338 'fk_mode_reglement' =>array(
'type'=>
'integer',
'label'=>
'PaymentMode',
'enabled'=>1,
'visible'=>-1,
'position'=>165),
339 'note_private' =>array(
'type'=>
'html',
'label'=>
'NotePrivate',
'enabled'=>1,
'visible'=>0,
'position'=>170),
340 'note_public' =>array(
'type'=>
'html',
'label'=>
'NotePublic',
'enabled'=>1,
'visible'=>0,
'position'=>175),
341 'model_pdf' =>array(
'type'=>
'varchar(255)',
'label'=>
'PDFTemplate',
'enabled'=>1,
'visible'=>0,
'position'=>180),
342 'date_livraison' =>array(
'type'=>
'date',
'label'=>
'DateDeliveryPlanned',
'enabled'=>1,
'visible'=>-1,
'position'=>185),
343 'fk_shipping_method' =>array(
'type'=>
'integer',
'label'=>
'ShippingMethod',
'enabled'=>1,
'visible'=>-1,
'position'=>190),
344 'fk_warehouse' =>array(
'type'=>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label'=>
'Fk warehouse',
'enabled'=>
'isModEnabled("stock")',
'visible'=>-1,
'position'=>191),
345 'fk_availability' =>array(
'type'=>
'integer',
'label'=>
'Availability',
'enabled'=>1,
'visible'=>-1,
'position'=>195),
346 'fk_delivery_address' =>array(
'type'=>
'integer',
'label'=>
'DeliveryAddress',
'enabled'=>1,
'visible'=>0,
'position'=>200),
347 'fk_input_reason' =>array(
'type'=>
'integer',
'label'=>
'InputReason',
'enabled'=>1,
'visible'=>-1,
'position'=>205),
348 'extraparams' =>array(
'type'=>
'varchar(255)',
'label'=>
'Extraparams',
'enabled'=>1,
'visible'=>-1,
'position'=>215),
349 'fk_incoterms' =>array(
'type'=>
'integer',
'label'=>
'IncotermCode',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>220),
350 'location_incoterms' =>array(
'type'=>
'varchar(255)',
'label'=>
'IncotermLabel',
'enabled'=>
'$conf->incoterm->enabled',
'visible'=>-1,
'position'=>225),
351 'fk_multicurrency' =>array(
'type'=>
'integer',
'label'=>
'MulticurrencyID',
'enabled'=>1,
'visible'=>-1,
'position'=>230),
352 'multicurrency_code' =>array(
'type'=>
'varchar(255)',
'label'=>
'MulticurrencyCurrency',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>235),
353 'multicurrency_tx' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyRate',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>240,
'isameasure'=>1),
354 'multicurrency_total_ht' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountHT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>245,
'isameasure'=>1),
355 'multicurrency_total_tva' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountVAT',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>250,
'isameasure'=>1),
356 'multicurrency_total_ttc' =>array(
'type'=>
'double(24,8)',
'label'=>
'MulticurrencyAmountTTC',
'enabled'=>
'isModEnabled("multicurrency")',
'visible'=>-1,
'position'=>255,
'isameasure'=>1),
357 'last_main_doc' =>array(
'type'=>
'varchar(255)',
'label'=>
'LastMainDoc',
'enabled'=>1,
'visible'=>-1,
'position'=>260),
358 'fk_statut' =>array(
'type'=>
'smallint(6)',
'label'=>
'Status',
'enabled'=>1,
'visible'=>-1,
'notnull'=>1,
'position'=>500),
359 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>900),
394 global $conf, $langs;
398 $this->socid = $socid;
399 $this->
id = $propalid;
401 $this->duree_validite =
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
420 global $conf, $mysoc;
426 dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
427 if ($idproduct > 0) {
428 $prod =
new Product($this->db);
429 $prod->fetch($idproduct);
431 $productdesc = $prod->description;
435 if (empty($tva_tx)) {
440 $localtax1_tx =
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
441 $localtax2_tx =
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
444 if ($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
445 $price = $prod->multiprices[$this->thirdparty->price_level];
452 $line->fk_product = $idproduct;
453 $line->desc = $productdesc;
457 $line->vat_src_code = $vat_src_code;
458 $line->tva_tx = $tva_tx;
459 $line->fk_unit = $prod->fk_unit;
461 $line->info_bits = 1;
464 $this->lines[] = $line;
482 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
483 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
488 $result =
$remise->fetch($idremise);
492 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
493 $this->db->rollback();
499 $this->line->context = $this->context;
501 $line->fk_propal = $this->id;
502 $line->fk_remise_except =
$remise->id;
503 $line->desc =
$remise->description;
504 $line->vat_src_code =
$remise->vat_src_code;
505 $line->tva_tx =
$remise->tva_tx;
506 $line->subprice = -
$remise->amount_ht;
507 $line->fk_product = 0;
509 $line->remise_percent = 0;
511 $line->info_bits = 2;
514 $line->price = -
$remise->amount_ht;
516 $line->total_ht = -
$remise->amount_ht;
517 $line->total_tva = -
$remise->amount_tva;
518 $line->total_ttc = -
$remise->amount_ttc;
520 $result = $line->insert();
527 $this->db->rollback();
531 $this->error = $line->error;
532 $this->errors = $line->errors;
533 $this->db->rollback();
537 $this->db->rollback();
579 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 = 0, $fk_unit =
null, $origin =
'', $origin_id = 0, $pu_ht_devise = 0, $fk_remise_except = 0, $noupdateafterinsertline = 0)
581 global $mysoc, $conf, $langs;
583 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);
585 if ($this->
statut == self::STATUS_DRAFT) {
586 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
595 if (empty($info_bits)) {
601 if (empty($fk_parent_line) || $fk_parent_line < 0) {
608 $pu_ht_devise =
price2num($pu_ht_devise);
610 if (!preg_match(
'/\((.*)\)/', $txtva)) {
616 if ($price_base_type ==
'HT') {
627 if ($date_start && $date_end && $date_start > $date_end) {
628 $langs->load(
"errors");
629 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
635 $product_type = $type;
636 if (!empty($fk_product) && $fk_product > 0) {
637 $product =
new Product($this->db);
638 $result = $product->fetch($fk_product);
639 $product_type = $product->type;
641 if (!empty($conf->global->STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL) && $product_type == 0 && $product->stock_reel < $qty) {
642 $langs->load(
"errors");
643 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
644 $this->db->rollback();
660 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
661 $vat_src_code = $reg[1];
662 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
665 $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);
667 $total_ht = $tabprice[0];
668 $total_tva = $tabprice[1];
669 $total_ttc = $tabprice[2];
670 $total_localtax1 = $tabprice[9];
671 $total_localtax2 = $tabprice[10];
672 $pu_ht = $tabprice[3];
673 $pu_tva = $tabprice[4];
674 $pu_ttc = $tabprice[5];
677 $multicurrency_total_ht = $tabprice[16];
678 $multicurrency_total_tva = $tabprice[17];
679 $multicurrency_total_ttc = $tabprice[18];
680 $pu_ht_devise = $tabprice[19];
684 if ($ranktouse == -1) {
685 $rangmax = $this->
line_max($fk_parent_line);
686 $ranktouse = $rangmax + 1;
701 $this->line->context = $this->context;
703 $this->line->fk_propal = $this->id;
704 $this->line->label = $label;
705 $this->line->desc = $desc;
706 $this->line->qty = $qty;
708 $this->line->vat_src_code = $vat_src_code;
709 $this->line->tva_tx = $txtva;
710 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
711 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
712 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
713 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
714 $this->line->fk_product = $fk_product;
715 $this->line->product_type = $type;
716 $this->line->fk_remise_except = $fk_remise_except;
718 $this->line->subprice = $pu_ht;
719 $this->line->rang = $ranktouse;
720 $this->line->info_bits = $info_bits;
721 $this->line->total_ht = $total_ht;
722 $this->line->total_tva = $total_tva;
723 $this->line->total_localtax1 = $total_localtax1;
724 $this->line->total_localtax2 = $total_localtax2;
725 $this->line->total_ttc = $total_ttc;
726 $this->line->special_code = $special_code;
727 $this->line->fk_parent_line = $fk_parent_line;
728 $this->line->fk_unit = $fk_unit;
730 $this->line->date_start = $date_start;
731 $this->line->date_end = $date_end;
733 $this->line->fk_fournprice = $fk_fournprice;
734 $this->line->pa_ht = $pa_ht;
736 $this->line->origin_id = $origin_id;
737 $this->line->origin = $origin;
740 $this->line->fk_multicurrency = $this->fk_multicurrency;
741 $this->line->multicurrency_code = $this->multicurrency_code;
742 $this->line->multicurrency_subprice = $pu_ht_devise;
743 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
744 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
745 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
748 if (empty($qty) && empty($special_code)) {
749 $this->line->special_code = 3;
753 $this->line->price =
$price;
755 if (is_array($array_options) && count($array_options) > 0) {
756 $this->line->array_options = $array_options;
759 $result = $this->line->insert();
762 if (!empty($fk_parent_line)) {
764 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
765 $linecount = count($this->lines);
766 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
772 if (empty($noupdateafterinsertline)) {
778 return $this->line->id;
780 $this->error = $this->db->error();
781 $this->db->rollback();
785 $this->error = $this->line->error;
786 $this->errors = $this->line->errors;
787 $this->db->rollback();
791 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
826 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 = 0, $fk_unit =
null, $pu_ht_devise = 0, $notrigger = 0, $rang = 0)
828 global $mysoc, $langs;
830 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
831 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");
832 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
838 $pu_ht_devise =
price2num($pu_ht_devise);
839 if (!preg_match(
'/\((.*)\)/', $txtva)) {
845 if (empty($qty) && empty($special_code)) {
848 if (!empty($qty) && $special_code == 3) {
855 if ($date_start && $date_end && $date_start > $date_end) {
856 $langs->load(
"errors");
857 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
861 if ($this->
statut == self::STATUS_DRAFT) {
874 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
875 $vat_src_code = $reg[1];
876 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
881 $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);
882 $total_ht = $tabprice[0];
883 $total_tva = $tabprice[1];
884 $total_ttc = $tabprice[2];
885 $total_localtax1 = $tabprice[9];
886 $total_localtax2 = $tabprice[10];
887 $pu_ht = $tabprice[3];
888 $pu_tva = $tabprice[4];
889 $pu_ttc = $tabprice[5];
892 $multicurrency_total_ht = $tabprice[16];
893 $multicurrency_total_tva = $tabprice[17];
894 $multicurrency_total_ttc = $tabprice[18];
895 $pu_ht_devise = $tabprice[19];
907 $line->fetch($rowid);
909 $staticline = clone $line;
911 $line->oldline = $staticline;
913 $this->line->context = $this->context;
914 $this->line->rang = $rang;
917 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
918 $rangmax = $this->
line_max($fk_parent_line);
919 $this->line->rang = $rangmax + 1;
922 $this->line->id = $rowid;
923 $this->line->label = $label;
924 $this->line->desc = $desc;
925 $this->line->qty = $qty;
926 $this->line->product_type = $type;
927 $this->line->vat_src_code = $vat_src_code;
928 $this->line->tva_tx = $txtva;
929 $this->line->localtax1_tx = $txlocaltax1;
930 $this->line->localtax2_tx = $txlocaltax2;
931 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
932 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
934 $this->line->subprice = $pu_ht;
935 $this->line->info_bits = $info_bits;
937 $this->line->total_ht = $total_ht;
938 $this->line->total_tva = $total_tva;
939 $this->line->total_localtax1 = $total_localtax1;
940 $this->line->total_localtax2 = $total_localtax2;
941 $this->line->total_ttc = $total_ttc;
942 $this->line->special_code = $special_code;
943 $this->line->fk_parent_line = $fk_parent_line;
944 $this->line->skip_update_total = $skip_update_total;
945 $this->line->fk_unit = $fk_unit;
947 $this->line->fk_fournprice = $fk_fournprice;
948 $this->line->pa_ht = $pa_ht;
950 $this->line->date_start = $date_start;
951 $this->line->date_end = $date_end;
953 if (is_array($array_options) && count($array_options) > 0) {
955 foreach ($array_options as $key => $value) {
956 $this->line->array_options[$key] = $array_options[$key];
961 $this->line->multicurrency_subprice = $pu_ht_devise;
962 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
963 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
964 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
966 $result = $this->line->update($notrigger);
969 if (!empty($fk_parent_line)) {
975 $this->fk_propal = $this->id;
976 $this->
rowid = $rowid;
981 $this->error = $this->line->error;
982 $this->errors = $this->line->errors;
983 $this->db->rollback();
987 dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
1004 if ($this->
statut == self::STATUS_DRAFT) {
1009 $line->context = $this->context;
1012 $line->fetch($lineid);
1014 if ($id > 0 && $line->fk_propal != $id) {
1015 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
1020 $staticline = clone $line;
1021 $line->oldline = $staticline;
1023 if ($line->delete($user) > 0) {
1026 $this->db->commit();
1029 $this->error = $line->error;
1030 $this->errors = $line->errors;
1031 $this->db->rollback();
1035 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1049 public function create($user, $notrigger = 0)
1051 global $conf, $hookmanager, $mysoc;
1057 if (empty($this->date)) {
1060 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1061 if (empty($this->availability_id)) {
1062 $this->availability_id = 0;
1064 if (empty($this->demand_reason_id)) {
1065 $this->demand_reason_id = 0;
1069 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1074 if (empty($this->fk_multicurrency)) {
1075 $this->multicurrency_code = $conf->currency;
1076 $this->fk_multicurrency = 0;
1077 $this->multicurrency_tx = 1;
1081 $delivery_date = empty($this->delivery_date) ? $this->date_livraison : $this->delivery_date;
1088 $this->error =
"Failed to fetch company";
1089 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1094 if (!empty($this->
ref)) {
1097 $this->error =
'ErrorRefAlreadyExists';
1098 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1099 $this->db->rollback();
1104 if (empty($this->date)) {
1105 $this->error =
"Date of proposal is required";
1106 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1114 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
1118 $sql .=
", remise_percent";
1119 $sql .=
", remise_absolue";
1120 $sql .=
", total_tva";
1121 $sql .=
", total_ttc";
1125 $sql .=
", fk_user_author";
1126 $sql .=
", note_private";
1127 $sql .=
", note_public";
1128 $sql .=
", model_pdf";
1129 $sql .=
", fin_validite";
1130 $sql .=
", fk_cond_reglement";
1131 $sql .=
", deposit_percent";
1132 $sql .=
", fk_mode_reglement";
1133 $sql .=
", fk_account";
1134 $sql .=
", ref_client";
1135 $sql .=
", ref_ext";
1136 $sql .=
", date_livraison";
1137 $sql .=
", fk_shipping_method";
1138 $sql .=
", fk_warehouse";
1139 $sql .=
", fk_availability";
1140 $sql .=
", fk_input_reason";
1141 $sql .=
", fk_projet";
1142 $sql .=
", fk_incoterms";
1143 $sql .=
", location_incoterms";
1145 $sql .=
", fk_multicurrency";
1146 $sql .=
", multicurrency_code";
1147 $sql .=
", multicurrency_tx";
1149 $sql .=
" VALUES (";
1150 $sql .= $this->socid;
1152 $sql .=
", ".((float) $this->remise);
1153 $sql .=
", ".($this->remise_percent ? ((float) $this->remise_percent) :
'NULL');
1154 $sql .=
", ".($this->remise_absolue ? ((float) $this->remise_absolue) :
'NULL');
1157 $sql .=
", '".$this->db->idate($this->date).
"'";
1158 $sql .=
", '".$this->db->idate($now).
"'";
1159 $sql .=
", '(PROV)'";
1160 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1161 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1162 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1163 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1164 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1165 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1166 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1167 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1168 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1169 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1170 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1171 $sql .=
", ".(empty($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1172 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1173 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1174 $sql .=
", ".$this->availability_id;
1175 $sql .=
", ".$this->demand_reason_id;
1176 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1177 $sql .=
", ".(int) $this->fk_incoterms;
1178 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1179 $sql .=
", ".setEntity($this);
1180 $sql .=
", ".(int) $this->fk_multicurrency;
1181 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1182 $sql .=
", ".(double) $this->multicurrency_tx;
1185 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1186 $resql = $this->db->query($sql);
1188 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1191 $this->
ref =
'(PROV'.$this->id.
')';
1192 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1194 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1195 $resql = $this->db->query($sql);
1200 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1201 $this->linked_objects = $this->linkedObjectsIds;
1205 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1206 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1207 if (is_array($tmp_origin_id)) {
1208 foreach ($tmp_origin_id as $origin_id) {
1211 $this->error = $this->db->lasterror();
1217 $origin_id = $tmp_origin_id;
1220 $this->error = $this->db->lasterror();
1232 $fk_parent_line = 0;
1233 $num = count($this->lines);
1235 for ($i = 0; $i < $num; $i++) {
1236 if (!is_object($this->lines[$i])) {
1238 $line = (object) $this->lines[$i];
1240 $line = $this->lines[$i];
1243 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1244 $fk_parent_line = 0;
1247 $vatrate = $line->tva_tx;
1248 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1249 $vatrate .=
' ('.$line->vat_src_code.
')';
1252 if (!empty($conf->global->MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION)) {
1253 $originid = $line->origin_id;
1254 $origintype = $line->origin;
1256 $originid = $line->id;
1257 $origintype = $this->element;
1265 $line->localtax1_tx,
1266 $line->localtax2_tx,
1268 $line->remise_percent,
1272 $line->product_type,
1274 $line->special_code,
1276 $line->fk_fournprice,
1281 $line->array_options,
1292 $this->error = $this->db->error;
1298 $line->id = $result;
1301 if ($result > 0 && $line->product_type == 9) {
1302 $fk_parent_line = $result;
1332 if (!$error && !$notrigger) {
1341 $this->error = $this->db->lasterror();
1346 $this->error = $this->db->lasterror();
1351 $this->db->commit();
1352 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1355 $this->db->rollback();
1359 $this->error = $this->db->lasterror();
1360 $this->db->rollback();
1375 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1377 global $conf, $hookmanager, $mysoc;
1386 $object =
new self($this->db);
1391 $object->fetch($this->
id);
1393 $objsoc =
new Societe($this->db);
1396 if (!empty($socid) && $socid != $object->socid) {
1397 if ($objsoc->fetch($socid) > 0) {
1398 $object->socid = $objsoc->id;
1399 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1400 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1401 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1402 $object->fk_delivery_address =
'';
1414 $object->fk_project =
'';
1419 $object->ref_client =
'';
1424 $objsoc->fetch($object->socid);
1428 if ($update_prices ===
true || $update_desc ===
true) {
1429 if ($objsoc->id > 0 && !empty($object->lines)) {
1430 if ($update_prices ===
true && !empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1432 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1435 foreach ($object->lines as $line) {
1438 if ($line->fk_product > 0) {
1439 $prod =
new Product($this->db);
1440 $res = $prod->fetch($line->fk_product);
1442 if ($update_prices ===
true) {
1443 $pu_ht = $prod->price;
1447 if (!empty($conf->global->PRODUIT_MULTIPRICES) && $objsoc->price_level > 0) {
1448 $pu_ht = $prod->multiprices[$objsoc->price_level];
1449 if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) {
1450 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1451 $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
1454 } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1456 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1457 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1460 if (count($prodcustprice->lines) > 0) {
1461 $pu_ht =
price($prodcustprice->lines[0]->price);
1462 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1463 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1464 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1470 $line->subprice = $pu_ht;
1471 $line->tva_tx = $tva_tx;
1474 if ($update_desc ===
true) {
1475 $line->desc = $prod->description;
1485 $object->entity = (!empty($forceentity) ? $forceentity : $object->entity);
1489 $object->user_author = $user->id;
1491 $object->user_validation_id = 0;
1493 $object->date = $now;
1494 $object->datep = $now;
1495 $object->fin_validite = $object->date + ($object->duree_validite * 24 * 3600);
1496 if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) {
1497 $object->ref_client =
'';
1500 $object->note_private =
'';
1501 $object->note_public =
'';
1504 $object->context[
'createfromclone'] =
'createfromclone';
1505 $result = $object->create($user);
1507 $this->error = $object->error;
1508 $this->errors = array_merge($this->errors, $object->errors);
1514 if ($object->copy_linked_contact($this,
'internal') < 0) {
1521 if ($this->socid == $object->socid) {
1522 if ($object->copy_linked_contact($this,
'external') < 0) {
1530 if (is_object($hookmanager)) {
1531 $parameters = array(
'objFrom'=>$this,
'clonedObj'=>$object);
1533 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1541 unset($object->context[
'createfromclone']);
1545 $this->db->commit();
1548 $this->db->rollback();
1562 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1564 $sql =
"SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc";
1565 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1566 $sql .=
", p.datec";
1567 $sql .=
", p.date_signature as dates";
1568 $sql .=
", p.date_valid as datev";
1569 $sql .=
", p.datep as dp";
1570 $sql .=
", p.fin_validite as dfv";
1571 $sql .=
", p.date_livraison as delivery_date";
1572 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1573 $sql .=
", p.note_private, p.note_public";
1574 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1575 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1576 $sql .=
", p.fk_delivery_address";
1577 $sql .=
", p.fk_availability";
1578 $sql .=
", p.fk_input_reason";
1579 $sql .=
", p.fk_cond_reglement";
1580 $sql .=
", p.fk_mode_reglement";
1581 $sql .=
', p.fk_account';
1582 $sql .=
", p.fk_shipping_method";
1583 $sql .=
", p.fk_warehouse";
1584 $sql .=
", p.fk_incoterms, p.location_incoterms";
1585 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1586 $sql .=
", p.tms as date_modification";
1587 $sql .=
", i.libelle as label_incoterms";
1588 $sql .=
", c.label as statut_label";
1589 $sql .=
", ca.code as availability_code, ca.label as availability";
1590 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1591 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1592 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1593 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1594 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1595 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1596 $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').
')';
1597 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1598 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1599 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1602 if (!empty($forceentity)) {
1603 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1605 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1607 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1610 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1613 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1614 $resql = $this->db->query($sql);
1616 if ($this->db->num_rows($resql)) {
1617 $obj = $this->db->fetch_object($resql);
1619 $this->
id = $obj->rowid;
1620 $this->entity = $obj->entity;
1622 $this->
ref = $obj->ref;
1623 $this->ref_client = $obj->ref_client;
1624 $this->ref_customer = $obj->ref_client;
1625 $this->ref_ext = $obj->ref_ext;
1627 $this->remise = $obj->remise;
1628 $this->remise_percent = $obj->remise_percent;
1629 $this->remise_absolue = $obj->remise_absolue;
1630 $this->total = $obj->total_ttc;
1631 $this->total_ttc = $obj->total_ttc;
1632 $this->total_ht = $obj->total_ht;
1633 $this->total_tva = $obj->total_tva;
1634 $this->total_localtax1 = $obj->localtax1;
1635 $this->total_localtax2 = $obj->localtax2;
1637 $this->socid = $obj->fk_soc;
1638 $this->thirdparty =
null;
1640 $this->fk_project = $obj->fk_project;
1641 $this->project =
null;
1643 $this->model_pdf = $obj->model_pdf;
1644 $this->modelpdf = $obj->model_pdf;
1645 $this->last_main_doc = $obj->last_main_doc;
1646 $this->note = $obj->note_private;
1647 $this->note_private = $obj->note_private;
1648 $this->note_public = $obj->note_public;
1650 $this->status = (int) $obj->fk_statut;
1651 $this->
statut = $this->status;
1653 $this->datec = $this->db->jdate($obj->datec);
1654 $this->datev = $this->db->jdate($obj->datev);
1655 $this->date_creation = $this->db->jdate($obj->datec);
1656 $this->date_validation = $this->db->jdate($obj->datev);
1657 $this->date_modification = $this->db->jdate($obj->date_modification);
1658 $this->date_signature = $this->db->jdate($obj->dates);
1659 $this->date = $this->db->jdate($obj->dp);
1660 $this->datep = $this->db->jdate($obj->dp);
1661 $this->fin_validite = $this->db->jdate($obj->dfv);
1662 $this->date_livraison = $this->db->jdate($obj->delivery_date);
1663 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1664 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1665 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1666 $this->availability_id = $obj->fk_availability;
1667 $this->availability_code = $obj->availability_code;
1669 $this->demand_reason_id = $obj->fk_input_reason;
1670 $this->demand_reason_code = $obj->demand_reason_code;
1672 $this->fk_address = $obj->fk_delivery_address;
1674 $this->mode_reglement_id = $obj->fk_mode_reglement;
1675 $this->mode_reglement_code = $obj->mode_reglement_code;
1676 $this->mode_reglement = $obj->mode_reglement;
1677 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1678 $this->cond_reglement_id = $obj->fk_cond_reglement;
1679 $this->cond_reglement_code = $obj->cond_reglement_code;
1680 $this->cond_reglement = $obj->cond_reglement;
1681 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1682 $this->deposit_percent = $obj->deposit_percent;
1684 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1686 $this->user_author_id = $obj->fk_user_author;
1687 $this->user_validation_id = $obj->fk_user_valid;
1688 $this->user_close_id = $obj->fk_user_cloture;
1691 $this->fk_incoterms = $obj->fk_incoterms;
1692 $this->location_incoterms = $obj->location_incoterms;
1693 $this->label_incoterms = $obj->label_incoterms;
1696 $this->fk_multicurrency = $obj->fk_multicurrency;
1697 $this->multicurrency_code = $obj->multicurrency_code;
1698 $this->multicurrency_tx = $obj->multicurrency_tx;
1699 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1700 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1701 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1703 if ($obj->fk_statut == self::STATUS_DRAFT) {
1704 $this->brouillon = 1;
1711 $this->db->free($resql);
1713 $this->lines = array();
1724 $this->error =
"Record Not Found";
1727 $this->error = $this->db->lasterror();
1746 if (isset($this->
ref)) {
1747 $this->
ref = trim($this->
ref);
1749 if (isset($this->ref_client)) {
1750 $this->ref_client = trim($this->ref_client);
1752 if (isset($this->note) || isset($this->note_private)) {
1753 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1755 if (isset($this->note_public)) {
1756 $this->note_public = trim($this->note_public);
1758 if (isset($this->model_pdf)) {
1759 $this->model_pdf = trim($this->model_pdf);
1761 if (isset($this->import_key)) {
1762 $this->import_key = trim($this->import_key);
1764 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1765 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1772 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1773 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1774 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1775 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1776 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1777 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1778 if (!empty($this->fin_validite)) {
1779 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1781 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1782 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1783 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1784 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1785 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1786 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1787 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->
statut :
"null").
",";
1788 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1789 $sql .=
" fk_user_valid = ".(!empty($this->user_validation_id) ? (int) $this->user_validation_id :
"null").
",";
1790 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1791 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1792 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1793 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1794 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1795 $sql .=
" fk_shipping_method=".(isset($this->shipping_method_id) ? (int) $this->shipping_method_id :
"null").
",";
1796 $sql .=
" fk_availability=".(isset($this->availability_id) ? (int) $this->availability_id :
"null").
",";
1797 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1798 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1799 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1800 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1801 $sql .=
" WHERE rowid=".((int) $this->
id);
1805 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1806 $resql = $this->db->query($sql);
1809 $this->errors[] =
"Error ".$this->db->lasterror();
1819 if (!$error && !$notrigger) {
1830 foreach ($this->errors as $errmsg) {
1831 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1832 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1834 $this->db->rollback();
1837 $this->db->commit();
1853 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $filters =
'')
1856 global $langs, $conf;
1858 $this->lines = array();
1860 $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,';
1861 $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,';
1862 $sql .=
' d.fk_unit,';
1863 $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,';
1864 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1865 $sql .=
' d.date_start, d.date_end,';
1866 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1867 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1868 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1869 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1870 if ($only_product) {
1871 $sql .=
' AND p.fk_product_type = 0';
1876 $sql .=
' ORDER by d.rang';
1878 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1879 $result = $this->db->query($sql);
1881 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1883 $num = $this->db->num_rows($result);
1887 $objp = $this->db->fetch_object($result);
1891 $line->rowid = $objp->rowid;
1892 $line->id = $objp->rowid;
1893 $line->fk_propal = $objp->fk_propal;
1894 $line->fk_parent_line = $objp->fk_parent_line;
1895 $line->product_type = $objp->product_type;
1896 $line->label = $objp->custom_label;
1897 $line->desc = $objp->description;
1898 $line->description = $objp->description;
1899 $line->qty = $objp->qty;
1900 $line->vat_src_code = $objp->vat_src_code;
1901 $line->tva_tx = $objp->tva_tx;
1902 $line->localtax1_tx = $objp->localtax1_tx;
1903 $line->localtax2_tx = $objp->localtax2_tx;
1904 $line->localtax1_type = $objp->localtax1_type;
1905 $line->localtax2_type = $objp->localtax2_type;
1906 $line->subprice = $objp->subprice;
1907 $line->fk_remise_except = $objp->fk_remise_except;
1908 $line->remise_percent = $objp->remise_percent;
1909 $line->price = $objp->price;
1911 $line->info_bits = $objp->info_bits;
1912 $line->total_ht = $objp->total_ht;
1913 $line->total_tva = $objp->total_tva;
1914 $line->total_localtax1 = $objp->total_localtax1;
1915 $line->total_localtax2 = $objp->total_localtax2;
1916 $line->total_ttc = $objp->total_ttc;
1917 $line->fk_fournprice = $objp->fk_fournprice;
1918 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1919 $line->pa_ht = $marginInfos[0];
1920 $line->marge_tx = $marginInfos[1];
1921 $line->marque_tx = $marginInfos[2];
1922 $line->special_code = $objp->special_code;
1923 $line->rang = $objp->rang;
1925 $line->fk_product = $objp->fk_product;
1927 $line->ref = $objp->product_ref;
1928 $line->libelle = $objp->product_label;
1930 $line->product_ref = $objp->product_ref;
1931 $line->product_label = $objp->product_label;
1932 $line->product_desc = $objp->product_desc;
1933 $line->product_tobatch = $objp->product_tobatch;
1934 $line->product_barcode = $objp->product_barcode;
1936 $line->fk_product_type = $objp->fk_product_type;
1937 $line->fk_unit = $objp->fk_unit;
1938 $line->weight = $objp->weight;
1939 $line->weight_units = $objp->weight_units;
1940 $line->volume = $objp->volume;
1941 $line->volume_units = $objp->volume_units;
1943 $line->date_start = $this->db->jdate($objp->date_start);
1944 $line->date_end = $this->db->jdate($objp->date_end);
1947 $line->fk_multicurrency = $objp->fk_multicurrency;
1948 $line->multicurrency_code = $objp->multicurrency_code;
1949 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1950 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1951 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1952 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1954 $line->fetch_optionals();
1957 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1958 $tmpproduct =
new Product($this->db);
1959 $tmpproduct->fetch($objp->fk_product);
1960 $tmpproduct->getMultiLangs();
1962 $line->multilangs = $tmpproduct->multilangs;
1965 $this->lines[$i] = $line;
1970 $this->db->free($result);
1974 $this->error = $this->db->lasterror();
1986 public function valid($user, $notrigger = 0)
1990 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1995 if ($this->
statut == self::STATUS_VALIDATED) {
1996 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
2000 if (!((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->creer))
2001 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->validate)))) {
2002 $this->error =
'ErrorPermissionDenied';
2003 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
2012 $soc =
new Societe($this->db);
2013 $soc->fetch($this->socid);
2016 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2023 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2024 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2025 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2028 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2029 $resql = $this->db->query($sql);
2036 if (!$error && !$notrigger) {
2038 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2046 $this->oldref = $this->ref;
2049 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2051 $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).
"'";
2052 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2053 $resql = $this->db->query($sql);
2056 $this->error = $this->db->lasterror();
2058 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2059 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2060 $resql = $this->db->query($sql);
2062 $error++; $this->error = $this->db->lasterror();
2068 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2069 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2070 if (!$error && file_exists($dirsource)) {
2071 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2072 if (@rename($dirsource, $dirdest)) {
2075 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2076 foreach ($listoffiles as $fileentry) {
2077 $dirsource = $fileentry[
'name'];
2078 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2079 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2080 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2081 @rename($dirsource, $dirdest);
2088 $this->brouillon = 0;
2090 $this->user_validation_id = $user->id;
2091 $this->datev = $now;
2093 $this->db->commit();
2096 $this->db->rollback();
2115 $this->error =
'ErrorBadParameter';
2116 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2120 if (!empty($user->rights->propal->creer)) {
2125 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2126 $sql .=
" WHERE rowid = ".((int) $this->
id);
2129 $resql = $this->db->query($sql);
2131 $this->errors[] = $this->db->error();
2136 $this->oldcopy = clone $this;
2137 $this->date = $date;
2138 $this->datep = $date;
2141 if (!$notrigger && empty($error)) {
2151 $this->db->commit();
2154 foreach ($this->errors as $errmsg) {
2155 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2156 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2158 $this->db->rollback();
2178 if (!empty($user->rights->propal->creer)) {
2183 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2184 $sql .=
" WHERE rowid = ".((int) $this->
id);
2188 $resql = $this->db->query($sql);
2190 $this->errors[] = $this->db->error();
2196 $this->oldcopy = clone $this;
2197 $this->fin_validite = $date_end_validity;
2200 if (!$notrigger && empty($error)) {
2210 $this->db->commit();
2213 foreach ($this->errors as $errmsg) {
2214 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2215 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2217 $this->db->rollback();
2251 if (!empty($user->rights->propal->creer)) {
2256 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2257 $sql .=
" SET date_livraison = ".($delivery_date !=
'' ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2258 $sql .=
" WHERE rowid = ".((int) $this->
id);
2261 $resql = $this->db->query($sql);
2263 $this->errors[] = $this->db->error();
2268 $this->oldcopy = clone $this;
2269 $this->date_livraison = $delivery_date;
2270 $this->delivery_date = $delivery_date;
2273 if (!$notrigger && empty($error)) {
2283 $this->db->commit();
2286 foreach ($this->errors as $errmsg) {
2287 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2288 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2290 $this->db->rollback();
2310 if (!empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) {
2315 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2316 $sql .=
" SET fk_availability = ".((int) $id);
2317 $sql .=
" WHERE rowid = ".((int) $this->
id);
2319 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2320 $resql = $this->db->query($sql);
2322 $this->errors[] = $this->db->error();
2327 $this->oldcopy = clone $this;
2328 $this->fk_availability = $id;
2329 $this->availability_id = $id;
2332 if (!$notrigger && empty($error)) {
2342 $this->db->commit();
2345 foreach ($this->errors as $errmsg) {
2346 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2347 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2349 $this->db->rollback();
2353 $error_str =
'Propal status do not meet requirement '.$this->statut;
2355 $this->error = $error_str;
2356 $this->errors[] = $this->error;
2373 if (!empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) {
2378 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2379 $sql .=
" SET fk_input_reason = ".((int) $id);
2380 $sql .=
" WHERE rowid = ".((int) $this->
id);
2383 $resql = $this->db->query($sql);
2385 $this->errors[] = $this->db->error();
2391 $this->oldcopy = clone $this;
2392 $this->fk_input_reason = $id;
2393 $this->demand_reason_id = $id;
2397 if (!$notrigger && empty($error)) {
2407 $this->db->commit();
2410 foreach ($this->errors as $errmsg) {
2411 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2412 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2414 $this->db->rollback();
2418 $error_str =
'Propal status do not meet requirement '.$this->statut;
2420 $this->error = $error_str;
2421 $this->errors[] = $this->error;
2438 if (!empty($user->rights->propal->creer)) {
2443 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2444 $sql .=
" WHERE rowid = ".((int) $this->
id);
2446 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2447 $resql = $this->db->query($sql);
2449 $this->errors[] = $this->db->error();
2454 $this->oldcopy = clone $this;
2455 $this->ref_client = $ref_client;
2458 if (!$notrigger && empty($error)) {
2468 $this->db->commit();
2471 foreach ($this->errors as $errmsg) {
2472 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2473 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2475 $this->db->rollback();
2498 if (!empty($user->rights->propal->creer)) {
2505 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET remise_percent = ".((float)
$remise);
2509 $resql = $this->db->query($sql);
2511 $this->errors[] = $this->db->error();
2516 $this->oldcopy = clone $this;
2517 $this->remise_percent =
$remise;
2521 if (!$notrigger && empty($error)) {
2531 $this->db->commit();
2534 foreach ($this->errors as $errmsg) {
2535 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2536 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2538 $this->db->rollback();
2564 if (!empty($user->rights->propal->creer)) {
2569 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2570 $sql .=
" SET remise_absolue = ".((float)
$remise);
2574 $resql = $this->db->query($sql);
2576 $this->errors[] = $this->db->error();
2581 $this->oldcopy = clone $this;
2585 if (!$notrigger && empty($error)) {
2595 $this->db->commit();
2598 foreach ($this->errors as $errmsg) {
2599 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2600 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2602 $this->db->rollback();
2625 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2626 $sql .=
" SET fk_statut = ".((int) $status).
",";
2627 if (!empty(
$note)) {
2628 $sql .=
" note_private = '".$this->db->escape(
$note).
"',";
2630 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2631 $sql .=
" WHERE rowid = ".((int) $this->
id);
2635 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2636 $resql = $this->db->query($sql);
2639 $this->errors[] =
"Error ".$this->db->lasterror();
2654 if (!empty($this->errors)) {
2655 foreach ($this->errors as $errmsg) {
2656 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2657 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2660 $this->db->rollback();
2664 $this->status = $status;
2666 $this->db->commit();
2682 global $langs,$conf;
2691 if (empty($conf->global->PROPALE_KEEP_OLD_SIGNATURE_INFO)) {
2692 $date_signature = $now;
2693 $fk_user_signature = $user->id;
2695 $this->
info($this->
id);
2696 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2697 $date_signature = $now;
2698 $fk_user_signature = $user->id;
2700 $date_signature = $this->date_signature;
2701 $fk_user_signature = $this->user_signature->id;
2705 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2706 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"'";
2707 if ($status == self::STATUS_SIGNED) {
2708 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2710 $sql .=
" WHERE rowid = ".((int) $this->
id);
2712 $resql = $this->db->query($sql);
2715 $modelpdf = !empty($conf->global->PROPALE_ADDON_PDF_ODT_CLOSED) ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2716 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2718 if ($status == self::STATUS_SIGNED) {
2719 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2720 $modelpdf = !empty($conf->global->PROPALE_ADDON_PDF_ODT_TOBILL) ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2724 $soc->id = $this->socid;
2725 $result = $soc->set_as_client();
2728 $this->error=$this->db->lasterror();
2729 $this->db->rollback();
2734 if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
2736 $outputlangs = $langs;
2738 $outputlangs =
new Translate(
"", $conf);
2739 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2740 $outputlangs->setDefaultLang($newlang);
2744 $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0);
2745 $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0);
2746 $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0);
2749 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2753 $this->oldcopy= clone $this;
2755 $this->status = $status;
2756 $this->date_signature = $date_signature;
2757 $this->note_private = $newprivatenote;
2760 if (!$notrigger && empty($error)) {
2770 $this->db->commit();
2773 $this->
statut = $this->oldcopy->statut;
2774 $this->status = $this->oldcopy->statut;
2775 $this->date_signature = $this->oldcopy->date_signature;
2776 $this->note_private = $this->oldcopy->note_private;
2778 $this->db->rollback();
2782 $this->error = $this->db->lasterror();
2783 $this->db->rollback();
2798 global $conf, $langs;
2805 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2811 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2812 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2813 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2816 $resql = $this->db->query($sql);
2818 $this->errors[] = $this->db->error();
2821 $num = $this->db->affected_rows($resql);
2825 $modelpdf = $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2827 if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
2829 $outputlangs = $langs;
2831 $outputlangs =
new Translate(
"", $conf);
2832 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2833 $outputlangs->setDefaultLang($newlang);
2837 $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0);
2838 $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0);
2839 $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0);
2842 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2845 $this->oldcopy = clone $this;
2847 $this->date_cloture = $now;
2848 $this->note_private = $newprivatenote;
2851 if (!$notrigger && empty($error)) {
2861 $this->db->commit();
2864 foreach ($this->errors as $errmsg) {
2865 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2866 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2868 $this->db->rollback();
2887 if ($this->
statut <= self::STATUS_DRAFT) {
2891 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2895 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2896 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2897 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2898 $sql .=
" WHERE rowid = ".((int) $this->
id);
2900 $resql = $this->db->query($sql);
2902 $this->errors[] = $this->db->error();
2907 $this->oldcopy = clone $this;
2910 if (!$notrigger && empty($error)) {
2921 $this->brouillon = 1;
2923 $this->db->commit();
2926 foreach ($this->errors as $errmsg) {
2927 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2928 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2930 $this->db->rollback();
2950 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2957 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2958 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2959 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2960 if (empty($user->rights->societe->client->voir) && !$socid) {
2961 $sql .=
", sc.fk_soc, sc.fk_user";
2963 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2964 if (empty($user->rights->societe->client->voir) && !$socid) {
2965 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
2967 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2968 $sql .=
" AND p.fk_soc = s.rowid";
2969 $sql .=
" AND p.fk_statut = c.id";
2970 if (empty($user->rights->societe->client->voir) && !$socid) {
2971 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
2974 $sql .=
" AND s.rowid = ".((int) $socid);
2977 $sql .=
" AND p.fk_statut = ".self::STATUS_DRAFT;
2979 if ($notcurrentuser > 0) {
2980 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2982 $sql .= $this->db->order($sortfield, $sortorder);
2983 $sql .= $this->db->plimit($limit, $offset);
2985 $result = $this->db->query($sql);
2987 $num = $this->db->num_rows($result);
2991 $obj = $this->db->fetch_object($result);
2993 if ($shortlist == 1) {
2994 $ga[$obj->propalid] = $obj->ref;
2995 } elseif ($shortlist == 2) {
2996 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2998 $ga[$i][
'id'] = $obj->propalid;
2999 $ga[$i][
'ref'] = $obj->ref;
3000 $ga[$i][
'name'] = $obj->name;
3034 $linkedInvoices = array();
3037 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
3040 foreach ($objectid as $key => $object) {
3042 if ($objecttype ==
'facture') {
3043 $linkedInvoices[] = $object;
3047 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
3048 foreach ($subobjectid as $subkey => $subobject) {
3049 if ($subobjecttype ==
'facture') {
3050 $linkedInvoices[] = $subobject;
3058 if (count($linkedInvoices) > 0) {
3059 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
3060 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
3061 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
3063 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
3064 $resql = $this->db->query($sql);
3067 $tab_sqlobj = array();
3068 $nump = $this->db->num_rows($resql);
3069 for ($i = 0; $i < $nump; $i++) {
3070 $sqlobj = $this->db->fetch_object($resql);
3071 $tab_sqlobj[] = $sqlobj;
3073 $this->db->free($resql);
3075 $nump = count($tab_sqlobj);
3079 while ($i < $nump) {
3080 $obj = array_shift($tab_sqlobj);
3103 public function delete($user, $notrigger = 0)
3106 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3122 if (!$error && !empty($this->table_element_line)) {
3123 $tabletodelete = $this->table_element_line;
3124 $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).
")";
3125 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3126 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3128 $this->error = $this->db->lasterror();
3129 $this->errors[] = $this->error;
3130 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3155 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3161 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3162 $res = $this->db->query($sql);
3165 $this->error = $this->db->lasterror();
3166 $this->errors[] = $this->error;
3167 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3182 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3183 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3184 $file = $dir.
"/".$ref.
".pdf";
3185 if (file_exists($file)) {
3189 $this->error =
'ErrorFailToDeleteFile';
3190 $this->errors[] = $this->error;
3191 $this->db->rollback();
3195 if (file_exists($dir)) {
3198 $this->error =
'ErrorFailToDeleteDir';
3199 $this->errors[] = $this->error;
3200 $this->db->rollback();
3208 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3209 $this->db->commit();
3212 $this->db->rollback();
3229 if ($this->
statut >= self::STATUS_DRAFT) {
3234 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3235 $sql .=
' SET fk_availability = '.((int) $availability_id);
3236 $sql .=
' WHERE rowid='.((int) $this->
id);
3238 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3239 $resql = $this->db->query($sql);
3241 $this->errors[] = $this->db->error();
3246 $this->oldcopy = clone $this;
3247 $this->availability_id = $availability_id;
3250 if (!$notrigger && empty($error)) {
3260 $this->db->commit();
3263 foreach ($this->errors as $errmsg) {
3264 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3265 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3267 $this->db->rollback();
3271 $error_str =
'Propal status do not meet requirement '.$this->statut;
3273 $this->error = $error_str;
3274 $this->errors[] = $this->error;
3293 if ($this->
statut >= self::STATUS_DRAFT) {
3298 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3299 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3300 $sql .=
' WHERE rowid='.((int) $this->
id);
3302 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3303 $resql = $this->db->query($sql);
3305 $this->errors[] = $this->db->error();
3310 $this->oldcopy = clone $this;
3311 $this->demand_reason_id = $demand_reason_id;
3314 if (!$notrigger && empty($error)) {
3324 $this->db->commit();
3327 foreach ($this->errors as $errmsg) {
3328 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3329 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3331 $this->db->rollback();
3335 $error_str =
'Propal status do not meet requirement '.$this->statut;
3337 $this->error = $error_str;
3338 $this->errors[] = $this->error;
3352 $sql =
"SELECT c.rowid, ";
3353 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3354 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3355 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3356 $sql .=
" WHERE c.rowid = ".((int) $id);
3358 $result = $this->db->query($sql);
3361 if ($this->db->num_rows($result)) {
3362 $obj = $this->db->fetch_object($result);
3364 $this->
id = $obj->rowid;
3366 $this->date_creation = $this->db->jdate($obj->datec);
3367 $this->date_validation = $this->db->jdate($obj->datev);
3368 $this->date_signature = $this->db->jdate($obj->date_signature);
3369 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3371 $cuser =
new User($this->db);
3372 $cuser->fetch($obj->fk_user_author);
3373 $this->user_creation = $cuser;
3375 if ($obj->fk_user_valid) {
3376 $this->user_validation_id = $obj->fk_user_valid;
3379 if ($obj->fk_user_signature) {
3380 $user_signature =
new User($this->db);
3381 $user_signature->fetch($obj->fk_user_signature);
3382 $this->user_signature = $user_signature;
3385 if ($obj->fk_user_cloture) {
3386 $cluser =
new User($this->db);
3387 $cluser->fetch($obj->fk_user_cloture);
3388 $this->user_cloture = $cluser;
3391 $this->db->free($result);
3420 global $conf, $hookmanager;
3423 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3425 $langs->load(
"propal");
3426 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3427 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3428 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3429 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3430 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3431 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3432 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3433 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3434 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3435 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3439 if ($status == self::STATUS_DRAFT) {
3440 $statusType =
'status0';
3441 } elseif ($status == self::STATUS_VALIDATED) {
3442 $statusType =
'status1';
3443 } elseif ($status == self::STATUS_SIGNED) {
3444 $statusType =
'status4';
3445 } elseif ($status == self::STATUS_NOTSIGNED) {
3446 $statusType =
'status9';
3447 } elseif ($status == self::STATUS_BILLED) {
3448 $statusType =
'status6';
3452 $parameters = array(
'status' => $status,
'mode' => $mode);
3453 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3456 return $hookmanager->resPrint;
3459 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3474 global $conf, $langs;
3478 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3479 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3480 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3481 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
3482 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3485 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3486 if ($mode ==
'opened') {
3487 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3489 if ($mode ==
'signed') {
3490 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3493 $sql .=
" AND p.fk_soc = ".((int) $user->socid);
3496 $resql = $this->db->query($sql);
3498 $langs->load(
"propal");
3503 $label = $labelShort =
'';
3504 if ($mode ==
'opened') {
3505 $delay_warning = $conf->propal->cloture->warning_delay;
3507 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3508 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3510 if ($mode ==
'signed') {
3511 $delay_warning = $conf->propal->facturation->warning_delay;
3513 $label = $langs->trans(
"PropalsToBill");
3514 $labelShort = $langs->trans(
"ToBill");
3518 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3519 $response->label = $label;
3520 $response->labelShort = $labelShort;
3521 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3522 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3526 while ($obj = $this->db->fetch_object($resql)) {
3527 $response->nbtodo++;
3528 $response->total += $obj->total_ht;
3530 if ($mode ==
'opened') {
3531 $datelimit = $this->db->jdate($obj->datefin);
3532 if ($datelimit < ($now - $delay_warning)) {
3533 $response->nbtodolate++;
3542 $this->error = $this->db->error();
3557 global $conf, $langs;
3562 $sql =
"SELECT rowid";
3563 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3564 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3565 $sql .= $this->db->plimit(100);
3567 $resql = $this->db->query($sql);
3569 $num_prods = $this->db->num_rows($resql);
3571 while ($i < $num_prods) {
3573 $row = $this->db->fetch_row($resql);
3574 $prodids[$i] = $row[0];
3580 $this->
ref =
'SPECIMEN';
3581 $this->ref_client =
'NEMICEPS';
3582 $this->specimen = 1;
3584 $this->date = time();
3585 $this->fin_validite = $this->date + 3600 * 24 * 30;
3586 $this->cond_reglement_id = 1;
3587 $this->cond_reglement_code =
'RECEP';
3588 $this->mode_reglement_id = 7;
3589 $this->mode_reglement_code =
'CHQ';
3590 $this->availability_id = 1;
3591 $this->availability_code =
'AV_NOW';
3592 $this->demand_reason_id = 1;
3593 $this->demand_reason_code =
'SRC_00';
3594 $this->note_public =
'This is a comment (public)';
3595 $this->note_private =
'This is a comment (private)';
3597 $this->multicurrency_tx = 1;
3598 $this->multicurrency_code = $conf->currency;
3603 while ($xnbp < $nbp) {
3605 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3607 $line->subprice = 100;
3610 $line->localtax1_tx = 0;
3611 $line->localtax2_tx = 0;
3613 $line->total_ht = 50;
3614 $line->total_ttc = 60;
3615 $line->total_tva = 10;
3616 $line->remise_percent = 50;
3618 $line->total_ht = 100;
3619 $line->total_ttc = 120;
3620 $line->total_tva = 20;
3621 $line->remise_percent = 00;
3624 if ($num_prods > 0) {
3625 $prodid = mt_rand(1, $num_prods);
3626 $line->fk_product = $prodids[$prodid];
3627 $line->product_ref =
'SPECIMEN';
3630 $this->lines[$xnbp] = $line;
3632 $this->total_ht += $line->total_ht;
3633 $this->total_tva += $line->total_tva;
3634 $this->total_ttc += $line->total_ttc;
3651 $this->nb = array();
3654 $sql =
"SELECT count(p.rowid) as nb";
3655 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3656 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3657 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3658 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3659 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3662 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3664 $resql = $this->db->query($sql);
3667 while ($obj = $this->db->fetch_object($resql)) {
3668 $this->nb[
"proposals"] = $obj->nb;
3670 $this->db->free($resql);
3674 $this->error = $this->db->error();
3689 global $conf, $langs;
3690 $langs->load(
"propal");
3692 $classname = $conf->global->PROPALE_ADDON;
3694 if (!empty($classname)) {
3697 $file = $classname.
".php";
3700 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3701 foreach ($dirmodels as $reldir) {
3705 $mybool |= @include_once $dir.$file;
3713 $obj =
new $classname();
3715 $numref = $obj->getNextValue($soc, $this);
3717 if ($numref !=
"") {
3720 $this->error = $obj->error;
3725 $langs->load(
"errors");
3726 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3739 global $conf, $langs, $user;
3741 $langs->load(
'propal');
3743 $nofetch = !empty($params[
'nofetch']);
3745 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
3746 return [
'optimize' => $langs->trans(
"Proposal")];
3748 if ($user->hasRight(
'propal',
'lire')) {
3749 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3750 if (isset($this->
statut)) {
3751 $datas[
'status'] =
' '.$this->getLibStatut(5);
3753 if (!empty($this->
ref)) {
3754 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3757 $langs->load(
'companies');
3758 if (empty($this->thirdparty)) {
3761 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3763 if (!empty($this->ref_client)) {
3764 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_client;
3767 $langs->load(
'project');
3768 if (empty($this->project)) {
3771 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3775 if (!empty($this->total_ht)) {
3776 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3778 if (!empty($this->total_tva)) {
3779 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3781 if (!empty($this->total_ttc)) {
3782 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3784 if (!empty($this->date)) {
3785 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3787 if (!empty($this->delivery_date)) {
3788 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3806 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3808 global $langs, $conf, $user, $hookmanager;
3810 if (!empty($conf->dol_no_mouse_hover)) {
3817 'objecttype' => $this->element,
3818 'option' => $option,
3821 $classfortooltip =
'classfortooltip';
3824 $classfortooltip =
'classforajaxtooltip';
3825 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3832 if ($user->hasRight(
'propal',
'lire')) {
3833 if ($option ==
'') {
3834 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3835 } elseif ($option ==
'compta') {
3836 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3837 } elseif ($option ==
'expedition') {
3838 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3839 } elseif ($option ==
'document') {
3840 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3843 if ($option !=
'nolink') {
3845 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3846 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3847 $add_save_lastsearch_values = 1;
3849 if ($add_save_lastsearch_values) {
3850 $url .=
'&save_lastsearch_values=1';
3856 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3857 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
3858 $label = $langs->trans(
"Proposal");
3859 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3861 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3862 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3865 $linkstart =
'<a href="'.$url.
'"';
3866 $linkstart .= $linkclose.
'>';
3869 $result .= $linkstart;
3871 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3873 if ($withpicto != 2) {
3874 $result .= $this->ref;
3876 $result .= $linkend;
3878 if ($addlinktonotes >= 0) {
3881 if ($addlinktonotes == 0) {
3882 if (!empty($this->note_private) || !empty($this->note_public)) {
3883 $txttoshow = $langs->trans(
'ViewPrivateNote');
3885 } elseif ($addlinktonotes == 1) {
3886 if (!empty($this->note_private)) {
3889 } elseif ($addlinktonotes == 2) {
3890 if (!empty($this->note_public)) {
3893 } elseif ($addlinktonotes == 3) {
3894 if ($user->socid > 0) {
3895 if (!empty($this->note_public)) {
3899 if (!empty($this->note_public)) {
3902 if (!empty($this->note_private)) {
3903 if (!empty($txttoshow)) {
3904 $txttoshow .=
'<br><br>';
3912 $result .=
' <span class="note inline-block">';
3913 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3916 $result .=
'</span>';
3921 $hookmanager->initHooks(array($this->element .
'dao'));
3922 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
3923 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3925 $result = $hookmanager->resPrint;
3927 $result .= $hookmanager->resPrint;
3954 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3956 global $conf, $langs;
3958 $langs->load(
"propale");
3959 $outputlangs->load(
"products");
3964 if ($this->model_pdf) {
3965 $modele = $this->model_pdf;
3966 } elseif (!empty($conf->global->PROPALE_ADDON_PDF)) {
3967 $modele = $conf->global->PROPALE_ADDON_PDF;
3971 $modelpath =
"core/modules/propale/doc/";
3973 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4021 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
4023 $return =
'<div class="box-flex-item box-flex-grow-zero">';
4024 $return .=
'<div class="info-box info-box-sm">';
4025 $return .=
'<span class="info-box-icon bg-infobox-action">';
4027 $return .=
'</span>';
4028 $return .=
'<div class="info-box-content">';
4029 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
4030 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
4031 if (property_exists($this,
'fk_project')) {
4032 $return .=
'<span class="info-box-ref"> | '.$this->fk_project.
'</span>';
4034 if (property_exists($this,
'author')) {
4035 $return .=
'<br><span class="info-box-label">'.$this->author.
'</span>';
4037 if (property_exists($this,
'total_ht')) {
4038 $return .=
'<br><span class="" >'.$langs->trans(
"AmountHT").
' : </span><span class="info-box-label amount">'.
price($this->total_ht).
'</span>';
4040 if (method_exists($this,
'getLibStatut')) {
4041 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
4043 $return .=
'</div>';
4044 $return .=
'</div>';
4045 $return .=
'</div>';
4058 public $element =
'propaldet';
4063 public $table_element =
'propaldet';
4069 public $fk_parent_line;
4087 public $vat_src_code;
4090 public $remise_percent;
4091 public $fk_remise_except;
4095 public $fk_fournprice;
4100 public $special_code;
4105 public $info_bits = 0;
4134 public $product_ref;
4149 public $product_label;
4154 public $product_desc;
4160 public $product_tobatch;
4166 public $product_barcode;
4168 public $localtax1_tx;
4169 public $localtax2_tx;
4170 public $localtax1_type;
4171 public $localtax2_type;
4172 public $total_localtax1;
4173 public $total_localtax2;
4178 public $skip_update_total;
4181 public $fk_multicurrency;
4182 public $multicurrency_code;
4183 public $multicurrency_subprice;
4184 public $multicurrency_total_ht;
4185 public $multicurrency_total_tva;
4186 public $multicurrency_total_ttc;
4207 $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,';
4208 $sql .=
' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
4209 $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,';
4210 $sql .=
' pd.fk_unit,';
4211 $sql .=
' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,';
4212 $sql .=
' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,';
4213 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
4214 $sql .=
' pd.date_start, pd.date_end, pd.product_type';
4215 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as pd';
4216 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON pd.fk_product = p.rowid';
4217 $sql .=
' WHERE pd.rowid = '.((int) $rowid);
4219 $result = $this->db->query($sql);
4221 $objp = $this->db->fetch_object($result);
4224 $this->
id = $objp->rowid;
4225 $this->
rowid = $objp->rowid;
4226 $this->fk_propal = $objp->fk_propal;
4227 $this->fk_parent_line = $objp->fk_parent_line;
4228 $this->label = $objp->custom_label;
4229 $this->desc = $objp->description;
4230 $this->qty = $objp->qty;
4231 $this->
price = $objp->price;
4232 $this->subprice = $objp->subprice;
4233 $this->vat_src_code = $objp->vat_src_code;
4234 $this->tva_tx = $objp->tva_tx;
4235 $this->remise = $objp->remise;
4236 $this->remise_percent = $objp->remise_percent;
4237 $this->fk_remise_except = $objp->fk_remise_except;
4238 $this->fk_product = $objp->fk_product;
4239 $this->info_bits = $objp->info_bits;
4241 $this->total_ht = $objp->total_ht;
4242 $this->total_tva = $objp->total_tva;
4243 $this->total_ttc = $objp->total_ttc;
4245 $this->fk_fournprice = $objp->fk_fournprice;
4247 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
4248 $this->pa_ht = $marginInfos[0];
4249 $this->marge_tx = $marginInfos[1];
4250 $this->marque_tx = $marginInfos[2];
4252 $this->special_code = $objp->special_code;
4253 $this->product_type = $objp->product_type;
4254 $this->rang = $objp->rang;
4256 $this->
ref = $objp->product_ref;
4257 $this->product_ref = $objp->product_ref;
4258 $this->libelle = $objp->product_label;
4259 $this->product_label = $objp->product_label;
4260 $this->product_desc = $objp->product_desc;
4261 $this->fk_unit = $objp->fk_unit;
4263 $this->date_start = $this->db->jdate($objp->date_start);
4264 $this->date_end = $this->db->jdate($objp->date_end);
4267 $this->fk_multicurrency = $objp->fk_multicurrency;
4268 $this->multicurrency_code = $objp->multicurrency_code;
4269 $this->multicurrency_subprice = $objp->multicurrency_subprice;
4270 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
4271 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
4272 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
4276 $this->db->free($result);
4295 global $conf, $user;
4299 dol_syslog(get_class($this).
"::insert rang=".$this->rang);
4301 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4304 if (empty($this->tva_tx)) {
4307 if (empty($this->localtax1_tx)) {
4308 $this->localtax1_tx = 0;
4310 if (empty($this->localtax2_tx)) {
4311 $this->localtax2_tx = 0;
4313 if (empty($this->localtax1_type)) {
4314 $this->localtax1_type = 0;
4316 if (empty($this->localtax2_type)) {
4317 $this->localtax2_type = 0;
4319 if (empty($this->total_localtax1)) {
4320 $this->total_localtax1 = 0;
4322 if (empty($this->total_localtax2)) {
4323 $this->total_localtax2 = 0;
4325 if (empty($this->rang)) {
4328 if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) {
4329 $this->remise_percent = 0;
4331 if (empty($this->info_bits)) {
4332 $this->info_bits = 0;
4334 if (empty($this->special_code)) {
4335 $this->special_code = 0;
4337 if (empty($this->fk_parent_line)) {
4338 $this->fk_parent_line = 0;
4340 if (empty($this->fk_fournprice)) {
4341 $this->fk_fournprice = 0;
4343 if (!is_numeric($this->qty)) {
4346 if (empty($this->pa_ht)) {
4349 if (empty($this->multicurrency_subprice)) {
4350 $this->multicurrency_subprice = 0;
4352 if (empty($this->multicurrency_total_ht)) {
4353 $this->multicurrency_total_ht = 0;
4355 if (empty($this->multicurrency_total_tva)) {
4356 $this->multicurrency_total_tva = 0;
4358 if (empty($this->multicurrency_total_ttc)) {
4359 $this->multicurrency_total_ttc = 0;
4363 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4364 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4367 $this->pa_ht = $result;
4372 if ($this->product_type < 0) {
4379 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'propaldet';
4380 $sql .=
' (fk_propal, fk_parent_line, label, description, fk_product, product_type,';
4381 $sql .=
' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
4382 $sql .=
' subprice, remise_percent, ';
4383 $sql .=
' info_bits, ';
4384 $sql .=
' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,';
4385 $sql .=
' fk_unit,';
4386 $sql .=
' date_start, date_end';
4387 $sql .=
', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)';
4388 $sql .=
" VALUES (".$this->fk_propal.
",";
4389 $sql .=
" ".($this->fk_parent_line > 0 ?
"'".$this->db->escape($this->fk_parent_line).
"'" :
"null").
",";
4390 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
4391 $sql .=
" '".$this->db->escape($this->desc).
"',";
4392 $sql .=
" ".($this->fk_product ?
"'".$this->db->escape($this->fk_product).
"'" :
"null").
",";
4393 $sql .=
" '".$this->db->escape($this->product_type).
"',";
4394 $sql .=
" ".($this->fk_remise_except ?
"'".$this->db->escape($this->fk_remise_except).
"'" :
"null").
",";
4395 $sql .=
" ".price2num($this->qty,
'MS').
",";
4396 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
4397 $sql .=
" ".price2num($this->tva_tx).
",";
4398 $sql .=
" ".price2num($this->localtax1_tx).
",";
4399 $sql .=
" ".price2num($this->localtax2_tx).
",";
4400 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
4401 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
4402 $sql .=
" ".(price2num($this->subprice) !==
'' ?
price2num($this->subprice,
'MU') :
"null").
",";
4403 $sql .=
" ".price2num($this->remise_percent, 3).
",";
4404 $sql .=
" ".(isset($this->info_bits) ? ((int) $this->info_bits) :
"null").
",";
4405 $sql .=
" ".price2num($this->total_ht,
'MT').
",";
4406 $sql .=
" ".price2num($this->total_tva,
'MT').
",";
4407 $sql .=
" ".price2num($this->total_localtax1,
'MT').
",";
4408 $sql .=
" ".price2num($this->total_localtax2,
'MT').
",";
4409 $sql .=
" ".price2num($this->total_ttc,
'MT').
",";
4410 $sql .=
" ".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null").
",";
4411 $sql .=
" ".(isset($this->pa_ht) ?
"'".price2num($this->pa_ht).
"'" :
"null").
",";
4412 $sql .=
' '.((int) $this->special_code).
',';
4413 $sql .=
' '.((int) $this->rang).
',';
4414 $sql .=
' '.(empty($this->fk_unit) ?
'NULL' : ((int) $this->fk_unit)).
',';
4415 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
',';
4416 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4417 $sql .=
", ".($this->fk_multicurrency > 0 ? ((int) $this->fk_multicurrency) :
'null');
4418 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
4419 $sql .=
", ".price2num($this->multicurrency_subprice,
'CU');
4420 $sql .=
", ".price2num($this->multicurrency_total_ht,
'CT');
4421 $sql .=
", ".price2num($this->multicurrency_total_tva,
'CT');
4422 $sql .=
", ".price2num($this->multicurrency_total_ttc,
'CT');
4425 dol_syslog(get_class($this).
'::insert', LOG_DEBUG);
4426 $resql = $this->db->query($sql);
4428 $this->
rowid = $this->db->last_insert_id(MAIN_DB_PREFIX.
'propaldet');
4431 $this->
id = $this->rowid;
4438 if (!$error && !$notrigger) {
4440 $result = $this->
call_trigger(
'LINEPROPAL_INSERT', $user);
4442 $this->db->rollback();
4449 $this->db->commit();
4453 foreach ($this->errors as $errmsg) {
4454 dol_syslog(get_class($this).
"::insert ".$errmsg, LOG_ERR);
4455 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4457 $this->db->rollback();
4460 $this->error = $this->db->error().
" sql=".$sql;
4461 $this->db->rollback();
4473 public function delete(
User $user, $notrigger = 0)
4482 $result = $this->
call_trigger(
'LINEPROPAL_DELETE', $user);
4490 $sql =
"DELETE FROM " . MAIN_DB_PREFIX .
"propaldet WHERE rowid = " . ((int) $this->
rowid);
4491 dol_syslog(
"PropaleLigne::delete", LOG_DEBUG);
4492 if ($this->db->query($sql)) {
4495 $this->
id = $this->rowid;
4499 dol_syslog(get_class($this) .
"::delete error -4 " . $this->error, LOG_ERR);
4503 $this->error = $this->db->error() .
" sql=" . $sql;
4509 $this->db->rollback();
4512 $this->db->commit();
4525 global $conf, $user;
4529 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4531 if (empty($this->
id) && !empty($this->
rowid)) {
4532 $this->
id = $this->rowid;
4536 if (empty($this->tva_tx)) {
4539 if (empty($this->localtax1_tx)) {
4540 $this->localtax1_tx = 0;
4542 if (empty($this->localtax2_tx)) {
4543 $this->localtax2_tx = 0;
4545 if (empty($this->total_localtax1)) {
4546 $this->total_localtax1 = 0;
4548 if (empty($this->total_localtax2)) {
4549 $this->total_localtax2 = 0;
4551 if (empty($this->localtax1_type)) {
4552 $this->localtax1_type = 0;
4554 if (empty($this->localtax2_type)) {
4555 $this->localtax2_type = 0;
4557 if (empty($this->marque_tx)) {
4558 $this->marque_tx = 0;
4560 if (empty($this->marge_tx)) {
4561 $this->marge_tx = 0;
4563 if (empty($this->
price)) {
4566 if (empty($this->remise_percent)) {
4567 $this->remise_percent = 0;
4569 if (empty($this->info_bits)) {
4570 $this->info_bits = 0;
4572 if (empty($this->special_code)) {
4573 $this->special_code = 0;
4575 if (empty($this->fk_parent_line)) {
4576 $this->fk_parent_line = 0;
4578 if (empty($this->fk_fournprice)) {
4579 $this->fk_fournprice = 0;
4581 if (empty($this->subprice)) {
4582 $this->subprice = 0;
4584 if (empty($this->pa_ht)) {
4589 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4590 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4593 $this->pa_ht = $result;
4600 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4601 $sql .=
" description='".$this->db->escape($this->desc).
"'";
4602 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
4603 $sql .=
", product_type=".$this->product_type;
4604 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"'";
4605 $sql .=
", tva_tx='".price2num($this->tva_tx).
"'";
4606 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
4607 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
4608 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
4609 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
4610 $sql .=
", qty='".price2num($this->qty).
"'";
4611 $sql .=
", subprice=".price2num($this->subprice);
4612 $sql .=
", remise_percent=".price2num($this->remise_percent);
4614 $sql .=
", remise=".(float)
price2num($this->remise);
4615 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
4616 if (empty($this->skip_update_total)) {
4617 $sql .=
", total_ht=".price2num($this->total_ht);
4618 $sql .=
", total_tva=".price2num($this->total_tva);
4619 $sql .=
", total_ttc=".price2num($this->total_ttc);
4620 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
4621 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
4623 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
4624 $sql .=
", buy_price_ht=".price2num($this->pa_ht);
4625 if (strlen($this->special_code)) {
4626 $sql .=
", special_code=".$this->special_code;
4628 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
4629 if (!empty($this->rang)) {
4630 $sql .=
", rang=".((int) $this->rang);
4632 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
4633 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4634 $sql .=
", fk_unit=".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
4637 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
4638 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
4639 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
4640 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
4642 $sql .=
" WHERE rowid = ".((int) $this->
id);
4644 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
4645 $resql = $this->db->query($sql);
4654 if (!$error && !$notrigger) {
4656 $result = $this->
call_trigger(
'LINEPROPAL_MODIFY', $user);
4658 $this->db->rollback();
4665 $this->db->commit();
4669 foreach ($this->errors as $errmsg) {
4670 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
4671 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4673 $this->db->rollback();
4676 $this->error = $this->db->error();
4677 $this->db->rollback();
4695 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4696 $sql .=
" total_ht=".price2num($this->total_ht,
'MT');
4697 $sql .=
",total_tva=".price2num($this->total_tva,
'MT');
4698 $sql .=
",total_ttc=".price2num($this->total_ttc,
'MT');
4699 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
4701 dol_syslog(
"PropaleLigne::update_total", LOG_DEBUG);
4703 $resql = $this->db->query($sql);
4705 $this->db->commit();
4708 $this->error = $this->db->error();
4709 $this->db->rollback();
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.
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)
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid='', $f_user=null, $notrigger=0)
Delete all links between an object $this.
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.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
File of class to manage predefined price products or services by customer.
Class to manage proposals.
getTooltipContentArray($params)
getTooltipContentArray
const STATUS_DRAFT
Draft status.
fetch_lines($only_product=0, $loadalsotranslation=0, $filters='')
Load array lines.
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.
set_remise_percent($user, $remise, $notrigger=0)
Set an overall discount on the proposal.
classifyBilled(User $user, $notrigger=0, $note='')
Classify the proposal to status Billed.
fetch($rowid, $ref='', $ref_ext='', $forceentity=0)
Load a proposal from database.
set_availability($user, $id, $notrigger=0)
Set delivery.
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, ...)
getLinesArray($filters='')
Retrieve an array of proposal lines.
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.
set_remise_absolue($user, $remise, $notrigger=0)
Set an absolute overall discount on the proposal.
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.
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=0, $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...
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)
Reopen the commercial proposal.
__construct($db, $socid=0, $propalid=0)
Constructor.
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
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=0, $fk_unit=null, $pu_ht_devise=0, $notrigger=0, $rang=0)
Update a proposal line.
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.
print $langs trans("Ref").' m m m statut
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 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
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.