41 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
42 require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobjectline.class.php";
43 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
44 require_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
45 require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
46 require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
47 require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
64 public $element =
'propal';
69 public $table_element =
'propal';
74 public $table_element_line =
'propaldet';
79 public $fk_element =
'fk_propal';
84 public $picto =
'propal';
90 public $ismultientitymanaged = 1;
96 public $restrictiononfksoc = 1;
146 public $date_creation;
157 public $date_validation;
162 public $date_signature;
167 public $user_signature;
184 public $date_livraison;
189 public $delivery_date;
192 public $fin_validite;
194 public $user_author_id;
195 public $user_valid_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 =
'';
1418 $object->ref_client =
'';
1422 $objsoc->fetch($object->socid);
1426 if ($update_prices ===
true || $update_desc ===
true) {
1427 if ($objsoc->id > 0 && !empty($object->lines)) {
1428 if ($update_prices ===
true && !empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1430 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1433 foreach ($object->lines as $line) {
1436 if ($line->fk_product > 0) {
1437 $prod =
new Product($this->db);
1438 $res = $prod->fetch($line->fk_product);
1440 if ($update_prices ===
true) {
1441 $pu_ht = $prod->price;
1445 if (!empty($conf->global->PRODUIT_MULTIPRICES) && $objsoc->price_level > 0) {
1446 $pu_ht = $prod->multiprices[$objsoc->price_level];
1447 if (!empty($conf->global->PRODUIT_MULTIPRICES_USE_VAT_PER_LEVEL)) {
1448 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1449 $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
1452 } elseif (!empty($conf->global->PRODUIT_CUSTOMER_PRICES)) {
1454 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1455 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1458 if (count($prodcustprice->lines) > 0) {
1459 $pu_ht =
price($prodcustprice->lines[0]->price);
1460 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1461 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1462 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1468 $line->subprice = $pu_ht;
1469 $line->tva_tx = $tva_tx;
1472 if ($update_desc ===
true) {
1473 $line->desc = $prod->description;
1483 $object->entity = (!empty($forceentity) ? $forceentity : $object->entity);
1487 $object->user_author = $user->id;
1488 $object->user_valid = 0;
1489 $object->date = $now;
1490 $object->datep = $now;
1491 $object->fin_validite = $object->date + ($object->duree_validite * 24 * 3600);
1492 if (empty($conf->global->MAIN_KEEP_REF_CUSTOMER_ON_CLONING)) {
1493 $object->ref_client =
'';
1496 $object->note_private =
'';
1497 $object->note_public =
'';
1500 $object->context[
'createfromclone'] =
'createfromclone';
1501 $result = $object->create($user);
1503 $this->error = $object->error;
1504 $this->errors = array_merge($this->errors, $object->errors);
1510 if ($object->copy_linked_contact($this,
'internal') < 0) {
1517 if ($this->socid == $object->socid) {
1518 if ($object->copy_linked_contact($this,
'external') < 0) {
1526 if (is_object($hookmanager)) {
1527 $parameters = array(
'objFrom'=>$this,
'clonedObj'=>$object);
1529 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters, $object, $action);
1537 unset($object->context[
'createfromclone']);
1541 $this->db->commit();
1544 $this->db->rollback();
1558 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1560 $sql =
"SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc";
1561 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1562 $sql .=
", p.datec";
1563 $sql .=
", p.date_signature as dates";
1564 $sql .=
", p.date_valid as datev";
1565 $sql .=
", p.datep as dp";
1566 $sql .=
", p.fin_validite as dfv";
1567 $sql .=
", p.date_livraison as delivery_date";
1568 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1569 $sql .=
", p.note_private, p.note_public";
1570 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1571 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1572 $sql .=
", p.fk_delivery_address";
1573 $sql .=
", p.fk_availability";
1574 $sql .=
", p.fk_input_reason";
1575 $sql .=
", p.fk_cond_reglement";
1576 $sql .=
", p.fk_mode_reglement";
1577 $sql .=
', p.fk_account';
1578 $sql .=
", p.fk_shipping_method";
1579 $sql .=
", p.fk_warehouse";
1580 $sql .=
", p.fk_incoterms, p.location_incoterms";
1581 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1582 $sql .=
", p.tms as date_modification";
1583 $sql .=
", i.libelle as label_incoterms";
1584 $sql .=
", c.label as statut_label";
1585 $sql .=
", ca.code as availability_code, ca.label as availability";
1586 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1587 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1588 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1589 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1590 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1591 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1592 $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').
')';
1593 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1594 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1595 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1598 if (!empty($forceentity)) {
1599 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1601 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1603 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1606 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1609 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1610 $resql = $this->db->query(
$sql);
1612 if ($this->db->num_rows($resql)) {
1613 $obj = $this->db->fetch_object($resql);
1615 $this->
id = $obj->rowid;
1616 $this->entity = $obj->entity;
1618 $this->
ref = $obj->ref;
1619 $this->ref_client = $obj->ref_client;
1620 $this->ref_customer = $obj->ref_client;
1621 $this->ref_ext = $obj->ref_ext;
1623 $this->remise = $obj->remise;
1624 $this->remise_percent = $obj->remise_percent;
1625 $this->remise_absolue = $obj->remise_absolue;
1626 $this->total = $obj->total_ttc;
1627 $this->total_ttc = $obj->total_ttc;
1628 $this->total_ht = $obj->total_ht;
1629 $this->total_tva = $obj->total_tva;
1630 $this->total_localtax1 = $obj->localtax1;
1631 $this->total_localtax2 = $obj->localtax2;
1633 $this->socid = $obj->fk_soc;
1634 $this->thirdparty =
null;
1636 $this->fk_project = $obj->fk_project;
1637 $this->project =
null;
1639 $this->model_pdf = $obj->model_pdf;
1640 $this->modelpdf = $obj->model_pdf;
1641 $this->last_main_doc = $obj->last_main_doc;
1642 $this->note = $obj->note_private;
1643 $this->note_private = $obj->note_private;
1644 $this->note_public = $obj->note_public;
1646 $this->status = (int) $obj->fk_statut;
1647 $this->statut = $this->status;
1649 $this->datec = $this->db->jdate($obj->datec);
1650 $this->datev = $this->db->jdate($obj->datev);
1651 $this->date_creation = $this->db->jdate($obj->datec);
1652 $this->date_validation = $this->db->jdate($obj->datev);
1653 $this->date_modification = $this->db->jdate($obj->date_modification);
1654 $this->date_signature = $this->db->jdate($obj->dates);
1655 $this->date = $this->db->jdate($obj->dp);
1656 $this->datep = $this->db->jdate($obj->dp);
1657 $this->fin_validite = $this->db->jdate($obj->dfv);
1658 $this->date_livraison = $this->db->jdate($obj->delivery_date);
1659 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1660 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1661 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1662 $this->availability_id = $obj->fk_availability;
1663 $this->availability_code = $obj->availability_code;
1665 $this->demand_reason_id = $obj->fk_input_reason;
1666 $this->demand_reason_code = $obj->demand_reason_code;
1668 $this->fk_address = $obj->fk_delivery_address;
1670 $this->mode_reglement_id = $obj->fk_mode_reglement;
1671 $this->mode_reglement_code = $obj->mode_reglement_code;
1672 $this->mode_reglement = $obj->mode_reglement;
1673 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1674 $this->cond_reglement_id = $obj->fk_cond_reglement;
1675 $this->cond_reglement_code = $obj->cond_reglement_code;
1676 $this->cond_reglement = $obj->cond_reglement;
1677 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1678 $this->deposit_percent = $obj->deposit_percent;
1680 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1682 $this->user_author_id = $obj->fk_user_author;
1683 $this->user_valid_id = $obj->fk_user_valid;
1684 $this->user_close_id = $obj->fk_user_cloture;
1687 $this->fk_incoterms = $obj->fk_incoterms;
1688 $this->location_incoterms = $obj->location_incoterms;
1689 $this->label_incoterms = $obj->label_incoterms;
1692 $this->fk_multicurrency = $obj->fk_multicurrency;
1693 $this->multicurrency_code = $obj->multicurrency_code;
1694 $this->multicurrency_tx = $obj->multicurrency_tx;
1695 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1696 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1697 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1699 if ($obj->fk_statut == self::STATUS_DRAFT) {
1700 $this->brouillon = 1;
1707 $this->db->free($resql);
1709 $this->lines = array();
1720 $this->error =
"Record Not Found";
1723 $this->error = $this->db->lasterror();
1742 if (isset($this->
ref)) {
1743 $this->
ref = trim($this->
ref);
1745 if (isset($this->ref_client)) {
1746 $this->ref_client = trim($this->ref_client);
1748 if (isset($this->note) || isset($this->note_private)) {
1749 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1751 if (isset($this->note_public)) {
1752 $this->note_public = trim($this->note_public);
1754 if (isset($this->model_pdf)) {
1755 $this->model_pdf = trim($this->model_pdf);
1757 if (isset($this->import_key)) {
1758 $this->import_key = trim($this->import_key);
1760 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1761 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1768 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1769 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1770 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1771 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1772 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1773 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1774 if (!empty($this->fin_validite)) {
1775 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1777 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1778 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1779 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1780 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1781 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1782 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1783 $sql .=
" fk_statut=".(isset($this->statut) ? $this->statut :
"null").
",";
1784 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1785 $sql .=
" fk_user_valid=".(isset($this->user_valid) ? $this->user_valid :
"null").
",";
1786 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1787 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1788 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1789 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1790 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1791 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1792 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1793 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1794 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1795 $sql .=
" WHERE rowid=".((int) $this->
id);
1799 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1800 $resql = $this->db->query(
$sql);
1803 $this->errors[] =
"Error ".$this->db->lasterror();
1813 if (!$error && !$notrigger) {
1824 foreach ($this->errors as $errmsg) {
1825 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1826 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1828 $this->db->rollback();
1831 $this->db->commit();
1847 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $filters =
'')
1850 global $langs, $conf;
1852 $this->lines = array();
1854 $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,';
1855 $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,';
1856 $sql .=
' d.fk_unit,';
1857 $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,';
1858 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1859 $sql .=
' d.date_start, d.date_end,';
1860 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1861 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1862 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1863 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1864 if ($only_product) {
1865 $sql .=
' AND p.fk_product_type = 0';
1870 $sql .=
' ORDER by d.rang';
1872 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1873 $result = $this->db->query(
$sql);
1875 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1877 $num = $this->db->num_rows($result);
1881 $objp = $this->db->fetch_object($result);
1885 $line->rowid = $objp->rowid;
1886 $line->id = $objp->rowid;
1887 $line->fk_propal = $objp->fk_propal;
1888 $line->fk_parent_line = $objp->fk_parent_line;
1889 $line->product_type = $objp->product_type;
1890 $line->label = $objp->custom_label;
1891 $line->desc = $objp->description;
1892 $line->description = $objp->description;
1893 $line->qty = $objp->qty;
1894 $line->vat_src_code = $objp->vat_src_code;
1895 $line->tva_tx = $objp->tva_tx;
1896 $line->localtax1_tx = $objp->localtax1_tx;
1897 $line->localtax2_tx = $objp->localtax2_tx;
1898 $line->localtax1_type = $objp->localtax1_type;
1899 $line->localtax2_type = $objp->localtax2_type;
1900 $line->subprice = $objp->subprice;
1901 $line->fk_remise_except = $objp->fk_remise_except;
1902 $line->remise_percent = $objp->remise_percent;
1903 $line->price = $objp->price;
1905 $line->info_bits = $objp->info_bits;
1906 $line->total_ht = $objp->total_ht;
1907 $line->total_tva = $objp->total_tva;
1908 $line->total_localtax1 = $objp->total_localtax1;
1909 $line->total_localtax2 = $objp->total_localtax2;
1910 $line->total_ttc = $objp->total_ttc;
1911 $line->fk_fournprice = $objp->fk_fournprice;
1912 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1913 $line->pa_ht = $marginInfos[0];
1914 $line->marge_tx = $marginInfos[1];
1915 $line->marque_tx = $marginInfos[2];
1916 $line->special_code = $objp->special_code;
1917 $line->rang = $objp->rang;
1919 $line->fk_product = $objp->fk_product;
1921 $line->ref = $objp->product_ref;
1922 $line->libelle = $objp->product_label;
1924 $line->product_ref = $objp->product_ref;
1925 $line->product_label = $objp->product_label;
1926 $line->product_desc = $objp->product_desc;
1927 $line->product_tobatch = $objp->product_tobatch;
1928 $line->product_barcode = $objp->product_barcode;
1930 $line->fk_product_type = $objp->fk_product_type;
1931 $line->fk_unit = $objp->fk_unit;
1932 $line->weight = $objp->weight;
1933 $line->weight_units = $objp->weight_units;
1934 $line->volume = $objp->volume;
1935 $line->volume_units = $objp->volume_units;
1937 $line->date_start = $this->db->jdate($objp->date_start);
1938 $line->date_end = $this->db->jdate($objp->date_end);
1941 $line->fk_multicurrency = $objp->fk_multicurrency;
1942 $line->multicurrency_code = $objp->multicurrency_code;
1943 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1944 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1945 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1946 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1948 $line->fetch_optionals();
1951 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1952 $tmpproduct =
new Product($this->db);
1953 $tmpproduct->fetch($objp->fk_product);
1954 $tmpproduct->getMultiLangs();
1956 $line->multilangs = $tmpproduct->multilangs;
1959 $this->lines[$i] = $line;
1964 $this->db->free($result);
1968 $this->error = $this->db->lasterror();
1980 public function valid($user, $notrigger = 0)
1984 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1989 if ($this->statut == self::STATUS_VALIDATED) {
1990 dol_syslog(get_class($this).
"::valid action abandonned: already validated", LOG_WARNING);
1994 if (!((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->creer))
1995 || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->propal->propal_advance->validate)))) {
1996 $this->error =
'ErrorPermissionDenied';
1997 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
2006 $soc =
new Societe($this->db);
2007 $soc->fetch($this->socid);
2010 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2017 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2018 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2019 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2022 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2023 $resql = $this->db->query(
$sql);
2030 if (!$error && !$notrigger) {
2032 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2040 $this->oldref = $this->ref;
2043 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2045 $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).
"'";
2046 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2047 $resql = $this->db->query(
$sql);
2050 $this->error = $this->db->lasterror();
2052 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2053 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2054 $resql = $this->db->query(
$sql);
2056 $error++; $this->error = $this->db->lasterror();
2062 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2063 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2064 if (!$error && file_exists($dirsource)) {
2065 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2066 if (@rename($dirsource, $dirdest)) {
2069 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2070 foreach ($listoffiles as $fileentry) {
2071 $dirsource = $fileentry[
'name'];
2072 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2073 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2074 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2075 @rename($dirsource, $dirdest);
2082 $this->brouillon = 0;
2084 $this->user_valid_id = $user->id;
2085 $this->datev = $now;
2087 $this->db->commit();
2090 $this->db->rollback();
2109 $this->error =
'ErrorBadParameter';
2110 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2114 if (!empty($user->rights->propal->creer)) {
2119 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2120 $sql .=
" WHERE rowid = ".((int) $this->
id);
2123 $resql = $this->db->query(
$sql);
2125 $this->errors[] = $this->db->error();
2130 $this->oldcopy = clone $this;
2131 $this->date = $date;
2132 $this->datep = $date;
2135 if (!$notrigger && empty($error)) {
2145 $this->db->commit();
2148 foreach ($this->errors as $errmsg) {
2149 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2150 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2152 $this->db->rollback();
2172 if (!empty($user->rights->propal->creer)) {
2177 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2178 $sql .=
" WHERE rowid = ".((int) $this->
id);
2182 $resql = $this->db->query(
$sql);
2184 $this->errors[] = $this->db->error();
2190 $this->oldcopy = clone $this;
2191 $this->fin_validite = $date_end_validity;
2194 if (!$notrigger && empty($error)) {
2204 $this->db->commit();
2207 foreach ($this->errors as $errmsg) {
2208 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2209 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2211 $this->db->rollback();
2245 if (!empty($user->rights->propal->creer)) {
2250 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2251 $sql .=
" SET date_livraison = ".($delivery_date !=
'' ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2252 $sql .=
" WHERE rowid = ".((int) $this->
id);
2255 $resql = $this->db->query(
$sql);
2257 $this->errors[] = $this->db->error();
2262 $this->oldcopy = clone $this;
2263 $this->date_livraison = $delivery_date;
2264 $this->delivery_date = $delivery_date;
2267 if (!$notrigger && empty($error)) {
2277 $this->db->commit();
2280 foreach ($this->errors as $errmsg) {
2281 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2282 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2284 $this->db->rollback();
2304 if (!empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) {
2309 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2310 $sql .=
" SET fk_availability = ".((int) $id);
2311 $sql .=
" WHERE rowid = ".((int) $this->
id);
2313 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2314 $resql = $this->db->query(
$sql);
2316 $this->errors[] = $this->db->error();
2321 $this->oldcopy = clone $this;
2322 $this->fk_availability = $id;
2323 $this->availability_id = $id;
2326 if (!$notrigger && empty($error)) {
2336 $this->db->commit();
2339 foreach ($this->errors as $errmsg) {
2340 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2341 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2343 $this->db->rollback();
2347 $error_str =
'Propal status do not meet requirement '.$this->statut;
2349 $this->error = $error_str;
2350 $this->errors[] = $this->error;
2367 if (!empty($user->rights->propal->creer) && $this->statut >= self::STATUS_DRAFT) {
2372 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2373 $sql .=
" SET fk_input_reason = ".((int) $id);
2374 $sql .=
" WHERE rowid = ".((int) $this->
id);
2377 $resql = $this->db->query(
$sql);
2379 $this->errors[] = $this->db->error();
2385 $this->oldcopy = clone $this;
2386 $this->fk_input_reason = $id;
2387 $this->demand_reason_id = $id;
2391 if (!$notrigger && empty($error)) {
2401 $this->db->commit();
2404 foreach ($this->errors as $errmsg) {
2405 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2406 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2408 $this->db->rollback();
2412 $error_str =
'Propal status do not meet requirement '.$this->statut;
2414 $this->error = $error_str;
2415 $this->errors[] = $this->error;
2432 if (!empty($user->rights->propal->creer)) {
2437 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2438 $sql .=
" WHERE rowid = ".((int) $this->
id);
2440 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2441 $resql = $this->db->query(
$sql);
2443 $this->errors[] = $this->db->error();
2448 $this->oldcopy = clone $this;
2449 $this->ref_client = $ref_client;
2452 if (!$notrigger && empty($error)) {
2462 $this->db->commit();
2465 foreach ($this->errors as $errmsg) {
2466 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2467 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2469 $this->db->rollback();
2492 if (!empty($user->rights->propal->creer)) {
2499 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET remise_percent = ".((
float)
$remise);
2503 $resql = $this->db->query(
$sql);
2505 $this->errors[] = $this->db->error();
2510 $this->oldcopy = clone $this;
2511 $this->remise_percent =
$remise;
2515 if (!$notrigger && empty($error)) {
2525 $this->db->commit();
2528 foreach ($this->errors as $errmsg) {
2529 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2530 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2532 $this->db->rollback();
2558 if (!empty($user->rights->propal->creer)) {
2563 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2564 $sql .=
" SET remise_absolue = ".((float)
$remise);
2568 $resql = $this->db->query(
$sql);
2570 $this->errors[] = $this->db->error();
2575 $this->oldcopy = clone $this;
2579 if (!$notrigger && empty($error)) {
2589 $this->db->commit();
2592 foreach ($this->errors as $errmsg) {
2593 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2594 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2596 $this->db->rollback();
2619 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2620 $sql .=
" SET fk_statut = ".((int) $status).
",";
2621 if (!empty(
$note)) {
2622 $sql .=
" note_private = '".$this->db->escape(
$note).
"',";
2624 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2625 $sql .=
" WHERE rowid = ".((int) $this->
id);
2629 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2630 $resql = $this->db->query(
$sql);
2633 $this->errors[] =
"Error ".$this->db->lasterror();
2648 if (!empty($this->errors)) {
2649 foreach ($this->errors as $errmsg) {
2650 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2651 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2654 $this->db->rollback();
2657 $this->statut = $status;
2658 $this->status = $status;
2660 $this->db->commit();
2676 global $langs,$conf;
2685 if (empty($conf->global->PROPALE_KEEP_OLD_SIGNATURE_INFO)) {
2686 $date_signature = $now;
2687 $fk_user_signature = $user->id;
2689 $this->
info($this->
id);
2690 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2691 $date_signature = $now;
2692 $fk_user_signature = $user->id;
2694 $date_signature = $this->date_signature;
2695 $fk_user_signature = $this->user_signature->id;
2699 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2700 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"'";
2701 if ($status == self::STATUS_SIGNED) {
2702 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2704 $sql .=
" WHERE rowid = ".((int) $this->
id);
2706 $resql = $this->db->query(
$sql);
2709 $modelpdf = !empty($conf->global->PROPALE_ADDON_PDF_ODT_CLOSED) ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2710 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2712 if ($status == self::STATUS_SIGNED) {
2713 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2714 $modelpdf = !empty($conf->global->PROPALE_ADDON_PDF_ODT_TOBILL) ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2718 $soc->id = $this->socid;
2719 $result = $soc->set_as_client();
2722 $this->error=$this->db->lasterror();
2723 $this->db->rollback();
2728 if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
2730 $outputlangs = $langs;
2732 $outputlangs =
new Translate(
"", $conf);
2733 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2734 $outputlangs->setDefaultLang($newlang);
2738 $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0);
2739 $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0);
2740 $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0);
2743 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2747 $this->oldcopy= clone $this;
2748 $this->statut = $status;
2749 $this->status = $status;
2750 $this->date_signature = $date_signature;
2751 $this->note_private = $newprivatenote;
2754 if (!$notrigger && empty($error)) {
2764 $this->db->commit();
2767 $this->statut = $this->oldcopy->statut;
2768 $this->status = $this->oldcopy->statut;
2769 $this->date_signature = $this->oldcopy->date_signature;
2770 $this->note_private = $this->oldcopy->note_private;
2772 $this->db->rollback();
2776 $this->error = $this->db->lasterror();
2777 $this->db->rollback();
2792 global $conf, $langs;
2799 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2805 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2806 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2807 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2810 $resql = $this->db->query(
$sql);
2812 $this->errors[] = $this->db->error();
2815 $num = $this->db->affected_rows($resql);
2819 $modelpdf = $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED ? $conf->global->PROPALE_ADDON_PDF_ODT_CLOSED : $this->model_pdf;
2821 if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
2823 $outputlangs = $langs;
2825 $outputlangs =
new Translate(
"", $conf);
2826 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2827 $outputlangs->setDefaultLang($newlang);
2831 $hidedetails = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DETAILS) ? 1 : 0);
2832 $hidedesc = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0);
2833 $hideref = (!empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0);
2836 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2839 $this->oldcopy = clone $this;
2841 $this->date_cloture = $now;
2842 $this->note_private = $newprivatenote;
2845 if (!$notrigger && empty($error)) {
2855 $this->db->commit();
2858 foreach ($this->errors as $errmsg) {
2859 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2860 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2862 $this->db->rollback();
2881 if ($this->statut <= self::STATUS_DRAFT) {
2885 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2889 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2890 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2891 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2892 $sql .=
" WHERE rowid = ".((int) $this->
id);
2894 $resql = $this->db->query(
$sql);
2896 $this->errors[] = $this->db->error();
2901 $this->oldcopy = clone $this;
2904 if (!$notrigger && empty($error)) {
2915 $this->brouillon = 1;
2917 $this->db->commit();
2920 foreach ($this->errors as $errmsg) {
2921 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2922 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2924 $this->db->rollback();
2944 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2951 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2952 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2953 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2954 if (empty($user->rights->societe->client->voir) && !$socid) {
2955 $sql .=
", sc.fk_soc, sc.fk_user";
2957 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2958 if (empty($user->rights->societe->client->voir) && !$socid) {
2959 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
2961 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2962 $sql .=
" AND p.fk_soc = s.rowid";
2963 $sql .=
" AND p.fk_statut = c.id";
2964 if (empty($user->rights->societe->client->voir) && !$socid) {
2965 $sql .=
" AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
2968 $sql .=
" AND s.rowid = ".((int) $socid);
2971 $sql .=
" AND p.fk_statut = ".self::STATUS_DRAFT;
2973 if ($notcurrentuser > 0) {
2974 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2976 $sql .= $this->db->order($sortfield, $sortorder);
2977 $sql .= $this->db->plimit($limit, $offset);
2979 $result = $this->db->query(
$sql);
2981 $num = $this->db->num_rows($result);
2985 $obj = $this->db->fetch_object($result);
2987 if ($shortlist == 1) {
2988 $ga[$obj->propalid] = $obj->ref;
2989 } elseif ($shortlist == 2) {
2990 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2992 $ga[$i][
'id'] = $obj->propalid;
2993 $ga[$i][
'ref'] = $obj->ref;
2994 $ga[$i][
'name'] = $obj->name;
3028 $linkedInvoices = array();
3031 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
3034 foreach ($objectid as $key => $object) {
3036 if ($objecttype ==
'facture') {
3037 $linkedInvoices[] = $object;
3041 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
3042 foreach ($subobjectid as $subkey => $subobject) {
3043 if ($subobjecttype ==
'facture') {
3044 $linkedInvoices[] = $subobject;
3052 if (count($linkedInvoices) > 0) {
3053 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
3054 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
3055 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
3057 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
3058 $resql = $this->db->query(
$sql);
3061 $tab_sqlobj = array();
3062 $nump = $this->db->num_rows($resql);
3063 for ($i = 0; $i < $nump; $i++) {
3064 $sqlobj = $this->db->fetch_object($resql);
3065 $tab_sqlobj[] = $sqlobj;
3067 $this->db->free($resql);
3069 $nump = count($tab_sqlobj);
3073 while ($i < $nump) {
3074 $obj = array_shift($tab_sqlobj);
3097 public function delete($user, $notrigger = 0)
3100 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3116 if (!$error && !empty($this->table_element_line)) {
3117 $tabletodelete = $this->table_element_line;
3118 $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).
")";
3119 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3120 if (!$this->db->query($sqlef) || !$this->db->query(
$sql)) {
3122 $this->error = $this->db->lasterror();
3123 $this->errors[] = $this->error;
3124 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3149 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3155 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3156 $res = $this->db->query(
$sql);
3159 $this->error = $this->db->lasterror();
3160 $this->errors[] = $this->error;
3161 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3176 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3177 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3178 $file = $dir.
"/".$ref.
".pdf";
3179 if (file_exists($file)) {
3183 $this->error =
'ErrorFailToDeleteFile';
3184 $this->errors[] = $this->error;
3185 $this->db->rollback();
3189 if (file_exists($dir)) {
3192 $this->error =
'ErrorFailToDeleteDir';
3193 $this->errors[] = $this->error;
3194 $this->db->rollback();
3202 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3203 $this->db->commit();
3206 $this->db->rollback();
3223 if ($this->statut >= self::STATUS_DRAFT) {
3228 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3229 $sql .=
' SET fk_availability = '.((int) $availability_id);
3230 $sql .=
' WHERE rowid='.((int) $this->
id);
3232 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3233 $resql = $this->db->query(
$sql);
3235 $this->errors[] = $this->db->error();
3240 $this->oldcopy = clone $this;
3241 $this->availability_id = $availability_id;
3244 if (!$notrigger && empty($error)) {
3254 $this->db->commit();
3257 foreach ($this->errors as $errmsg) {
3258 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3259 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3261 $this->db->rollback();
3265 $error_str =
'Propal status do not meet requirement '.$this->statut;
3267 $this->error = $error_str;
3268 $this->errors[] = $this->error;
3287 if ($this->statut >= self::STATUS_DRAFT) {
3292 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3293 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3294 $sql .=
' WHERE rowid='.((int) $this->
id);
3296 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3297 $resql = $this->db->query(
$sql);
3299 $this->errors[] = $this->db->error();
3304 $this->oldcopy = clone $this;
3305 $this->demand_reason_id = $demand_reason_id;
3308 if (!$notrigger && empty($error)) {
3318 $this->db->commit();
3321 foreach ($this->errors as $errmsg) {
3322 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3323 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3325 $this->db->rollback();
3329 $error_str =
'Propal status do not meet requirement '.$this->statut;
3331 $this->error = $error_str;
3332 $this->errors[] = $this->error;
3346 $sql =
"SELECT c.rowid, ";
3347 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3348 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3349 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3350 $sql .=
" WHERE c.rowid = ".((int) $id);
3352 $result = $this->db->query(
$sql);
3355 if ($this->db->num_rows($result)) {
3356 $obj = $this->db->fetch_object($result);
3358 $this->
id = $obj->rowid;
3360 $this->date_creation = $this->db->jdate($obj->datec);
3361 $this->date_validation = $this->db->jdate($obj->datev);
3362 $this->date_signature = $this->db->jdate($obj->date_signature);
3363 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3365 $cuser =
new User($this->db);
3366 $cuser->fetch($obj->fk_user_author);
3367 $this->user_creation = $cuser;
3369 if ($obj->fk_user_valid) {
3370 $vuser =
new User($this->db);
3371 $vuser->fetch($obj->fk_user_valid);
3372 $this->user_validation = $vuser;
3375 if ($obj->fk_user_signature) {
3376 $user_signature =
new User($this->db);
3377 $user_signature->fetch($obj->fk_user_signature);
3378 $this->user_signature = $user_signature;
3381 if ($obj->fk_user_cloture) {
3382 $cluser =
new User($this->db);
3383 $cluser->fetch($obj->fk_user_cloture);
3384 $this->user_cloture = $cluser;
3387 $this->db->free($result);
3402 return $this->
LibStatut($this->statut, $mode);
3416 global $conf, $hookmanager;
3419 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3421 $langs->load(
"propal");
3422 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3423 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3424 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3425 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3426 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3427 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3428 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3429 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3430 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3431 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3435 if ($status == self::STATUS_DRAFT) {
3436 $statusType =
'status0';
3437 } elseif ($status == self::STATUS_VALIDATED) {
3438 $statusType =
'status1';
3439 } elseif ($status == self::STATUS_SIGNED) {
3440 $statusType =
'status4';
3441 } elseif ($status == self::STATUS_NOTSIGNED) {
3442 $statusType =
'status9';
3443 } elseif ($status == self::STATUS_BILLED) {
3444 $statusType =
'status6';
3448 $parameters = array(
'status' => $status,
'mode' => $mode);
3449 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3452 return $hookmanager->resPrint;
3455 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3470 global $conf, $langs;
3474 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3475 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3476 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3477 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
3478 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3482 if ($mode ==
'opened') {
3483 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3485 if ($mode ==
'signed') {
3486 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3489 $sql .=
" AND p.fk_soc = ".((int) $user->socid);
3492 $resql = $this->db->query(
$sql);
3494 $langs->load(
"propal");
3499 $label = $labelShort =
'';
3500 if ($mode ==
'opened') {
3501 $delay_warning = $conf->propal->cloture->warning_delay;
3503 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3504 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3506 if ($mode ==
'signed') {
3507 $delay_warning = $conf->propal->facturation->warning_delay;
3509 $label = $langs->trans(
"PropalsToBill");
3510 $labelShort = $langs->trans(
"ToBill");
3514 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3515 $response->label = $label;
3516 $response->labelShort = $labelShort;
3517 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3518 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3522 while ($obj = $this->db->fetch_object($resql)) {
3523 $response->nbtodo++;
3524 $response->total += $obj->total_ht;
3526 if ($mode ==
'opened') {
3527 $datelimit = $this->db->jdate($obj->datefin);
3528 if ($datelimit < ($now - $delay_warning)) {
3529 $response->nbtodolate++;
3538 $this->error = $this->db->error();
3553 global $conf, $langs;
3558 $sql =
"SELECT rowid";
3559 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3560 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3561 $sql .= $this->db->plimit(100);
3563 $resql = $this->db->query(
$sql);
3565 $num_prods = $this->db->num_rows($resql);
3567 while ($i < $num_prods) {
3569 $row = $this->db->fetch_row($resql);
3570 $prodids[$i] = $row[0];
3576 $this->
ref =
'SPECIMEN';
3577 $this->ref_client =
'NEMICEPS';
3578 $this->specimen = 1;
3580 $this->date = time();
3581 $this->fin_validite = $this->date + 3600 * 24 * 30;
3582 $this->cond_reglement_id = 1;
3583 $this->cond_reglement_code =
'RECEP';
3584 $this->mode_reglement_id = 7;
3585 $this->mode_reglement_code =
'CHQ';
3586 $this->availability_id = 1;
3587 $this->availability_code =
'AV_NOW';
3588 $this->demand_reason_id = 1;
3589 $this->demand_reason_code =
'SRC_00';
3590 $this->note_public =
'This is a comment (public)';
3591 $this->note_private =
'This is a comment (private)';
3593 $this->multicurrency_tx = 1;
3594 $this->multicurrency_code = $conf->currency;
3599 while ($xnbp < $nbp) {
3601 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3603 $line->subprice = 100;
3606 $line->localtax1_tx = 0;
3607 $line->localtax2_tx = 0;
3609 $line->total_ht = 50;
3610 $line->total_ttc = 60;
3611 $line->total_tva = 10;
3612 $line->remise_percent = 50;
3614 $line->total_ht = 100;
3615 $line->total_ttc = 120;
3616 $line->total_tva = 20;
3617 $line->remise_percent = 00;
3620 if ($num_prods > 0) {
3621 $prodid = mt_rand(1, $num_prods);
3622 $line->fk_product = $prodids[$prodid];
3623 $line->product_ref =
'SPECIMEN';
3626 $this->lines[$xnbp] = $line;
3628 $this->total_ht += $line->total_ht;
3629 $this->total_tva += $line->total_tva;
3630 $this->total_ttc += $line->total_ttc;
3647 $this->nb = array();
3650 $sql =
"SELECT count(p.rowid) as nb";
3651 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3652 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3653 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3654 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3655 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3658 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3660 $resql = $this->db->query(
$sql);
3663 while ($obj = $this->db->fetch_object($resql)) {
3664 $this->nb[
"proposals"] = $obj->nb;
3666 $this->db->free($resql);
3670 $this->error = $this->db->error();
3685 global $conf, $langs;
3686 $langs->load(
"propal");
3688 $classname = $conf->global->PROPALE_ADDON;
3690 if (!empty($classname)) {
3693 $file = $classname.
".php";
3696 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3697 foreach ($dirmodels as $reldir) {
3701 $mybool |= @include_once $dir.$file;
3709 $obj =
new $classname();
3711 $numref = $obj->getNextValue($soc, $this);
3713 if ($numref !=
"") {
3716 $this->error = $obj->error;
3721 $langs->load(
"errors");
3722 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3735 global $conf, $langs, $user;
3737 $langs->load(
'propal');
3739 $nofetch = !empty($params[
'nofetch']);
3741 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
3742 return [
'optimize' => $langs->trans(
"Proposal")];
3744 if ($user->hasRight(
'propal',
'lire')) {
3745 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3746 if (isset($this->statut)) {
3747 $datas[
'status'] =
' '.$this->getLibStatut(5);
3749 if (!empty($this->
ref)) {
3750 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3753 $langs->load(
'companies');
3754 if (empty($this->thirdparty)) {
3757 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3759 if (!empty($this->ref_client)) {
3760 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_client;
3763 $langs->load(
'project');
3764 if (empty($this->project)) {
3767 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3771 if (!empty($this->total_ht)) {
3772 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3774 if (!empty($this->total_tva)) {
3775 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3777 if (!empty($this->total_ttc)) {
3778 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3780 if (!empty($this->date)) {
3781 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3783 if (!empty($this->delivery_date)) {
3784 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3802 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3804 global $langs, $conf, $user, $hookmanager;
3806 if (!empty($conf->dol_no_mouse_hover)) {
3813 'objecttype' => $this->element,
3814 'option' => $option,
3817 $classfortooltip =
'classfortooltip';
3820 $classfortooltip =
'classforajaxtooltip';
3821 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3828 if ($user->hasRight(
'propal',
'lire')) {
3829 if ($option ==
'') {
3830 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3831 } elseif ($option ==
'compta') {
3832 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3833 } elseif ($option ==
'expedition') {
3834 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3835 } elseif ($option ==
'document') {
3836 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3839 if ($option !=
'nolink') {
3841 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3842 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3843 $add_save_lastsearch_values = 1;
3845 if ($add_save_lastsearch_values) {
3846 $url .=
'&save_lastsearch_values=1';
3852 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3853 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
3854 $label = $langs->trans(
"Proposal");
3855 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3857 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3858 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3861 $linkstart =
'<a href="'.$url.
'"';
3862 $linkstart .= $linkclose.
'>';
3865 $result .= $linkstart;
3867 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3869 if ($withpicto != 2) {
3870 $result .= $this->ref;
3872 $result .= $linkend;
3874 if ($addlinktonotes >= 0) {
3877 if ($addlinktonotes == 0) {
3878 if (!empty($this->note_private) || !empty($this->note_public)) {
3879 $txttoshow = $langs->trans(
'ViewPrivateNote');
3881 } elseif ($addlinktonotes == 1) {
3882 if (!empty($this->note_private)) {
3885 } elseif ($addlinktonotes == 2) {
3886 if (!empty($this->note_public)) {
3889 } elseif ($addlinktonotes == 3) {
3890 if ($user->socid > 0) {
3891 if (!empty($this->note_public)) {
3895 if (!empty($this->note_public)) {
3898 if (!empty($this->note_private)) {
3899 if (!empty($txttoshow)) {
3900 $txttoshow .=
'<br><br>';
3908 $result .=
' <span class="note inline-block">';
3909 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3912 $result .=
'</span>';
3917 $hookmanager->initHooks(array($this->element .
'dao'));
3918 $parameters = array(
'id'=>$this->
id,
'getnomurl' => &$result);
3919 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3921 $result = $hookmanager->resPrint;
3923 $result .= $hookmanager->resPrint;
3950 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3952 global $conf, $langs;
3954 $langs->load(
"propale");
3955 $outputlangs->load(
"products");
3960 if ($this->model_pdf) {
3961 $modele = $this->model_pdf;
3962 } elseif (!empty($conf->global->PROPALE_ADDON_PDF)) {
3963 $modele = $conf->global->PROPALE_ADDON_PDF;
3967 $modelpath =
"core/modules/propale/doc/";
3969 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4017 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
4019 $return =
'<div class="box-flex-item box-flex-grow-zero">';
4020 $return .=
'<div class="info-box info-box-sm">';
4021 $return .=
'<span class="info-box-icon bg-infobox-action">';
4023 $return .=
'</span>';
4024 $return .=
'<div class="info-box-content">';
4025 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
4026 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
4027 if (property_exists($this,
'fk_project')) {
4028 $return .=
'<span class="info-box-ref"> | '.$this->fk_project.
'</span>';
4030 if (property_exists($this,
'author')) {
4031 $return .=
'<br><span class="info-box-label">'.$this->author.
'</span>';
4033 if (property_exists($this,
'total_ht')) {
4034 $return .=
'<br><span class="" >'.$langs->trans(
"AmountHT").
' : </span><span class="info-box-label amount">'.
price($this->total_ht).
'</span>';
4036 if (method_exists($this,
'getLibStatut')) {
4037 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
4039 $return .=
'</div>';
4040 $return .=
'</div>';
4041 $return .=
'</div>';
4054 public $element =
'propaldet';
4059 public $table_element =
'propaldet';
4065 public $fk_parent_line;
4083 public $vat_src_code;
4086 public $remise_percent;
4087 public $fk_remise_except;
4091 public $fk_fournprice;
4096 public $special_code;
4101 public $info_bits = 0;
4130 public $product_ref;
4145 public $product_label;
4150 public $product_desc;
4156 public $product_tobatch;
4162 public $product_barcode;
4164 public $localtax1_tx;
4165 public $localtax2_tx;
4166 public $localtax1_type;
4167 public $localtax2_type;
4168 public $total_localtax1;
4169 public $total_localtax2;
4174 public $skip_update_total;
4177 public $fk_multicurrency;
4178 public $multicurrency_code;
4179 public $multicurrency_subprice;
4180 public $multicurrency_total_ht;
4181 public $multicurrency_total_tva;
4182 public $multicurrency_total_ttc;
4203 $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,';
4204 $sql .=
' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
4205 $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,';
4206 $sql .=
' pd.fk_unit,';
4207 $sql .=
' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,';
4208 $sql .=
' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,';
4209 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
4210 $sql .=
' pd.date_start, pd.date_end, pd.product_type';
4211 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as pd';
4212 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON pd.fk_product = p.rowid';
4213 $sql .=
' WHERE pd.rowid = '.((int) $rowid);
4215 $result = $this->db->query(
$sql);
4217 $objp = $this->db->fetch_object($result);
4220 $this->
id = $objp->rowid;
4221 $this->
rowid = $objp->rowid;
4222 $this->fk_propal = $objp->fk_propal;
4223 $this->fk_parent_line = $objp->fk_parent_line;
4224 $this->label = $objp->custom_label;
4225 $this->desc = $objp->description;
4226 $this->qty = $objp->qty;
4227 $this->
price = $objp->price;
4228 $this->subprice = $objp->subprice;
4229 $this->vat_src_code = $objp->vat_src_code;
4230 $this->tva_tx = $objp->tva_tx;
4231 $this->remise = $objp->remise;
4232 $this->remise_percent = $objp->remise_percent;
4233 $this->fk_remise_except = $objp->fk_remise_except;
4234 $this->fk_product = $objp->fk_product;
4235 $this->info_bits = $objp->info_bits;
4237 $this->total_ht = $objp->total_ht;
4238 $this->total_tva = $objp->total_tva;
4239 $this->total_ttc = $objp->total_ttc;
4241 $this->fk_fournprice = $objp->fk_fournprice;
4243 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
4244 $this->pa_ht = $marginInfos[0];
4245 $this->marge_tx = $marginInfos[1];
4246 $this->marque_tx = $marginInfos[2];
4248 $this->special_code = $objp->special_code;
4249 $this->product_type = $objp->product_type;
4250 $this->rang = $objp->rang;
4252 $this->
ref = $objp->product_ref;
4253 $this->product_ref = $objp->product_ref;
4254 $this->libelle = $objp->product_label;
4255 $this->product_label = $objp->product_label;
4256 $this->product_desc = $objp->product_desc;
4257 $this->fk_unit = $objp->fk_unit;
4259 $this->date_start = $this->db->jdate($objp->date_start);
4260 $this->date_end = $this->db->jdate($objp->date_end);
4263 $this->fk_multicurrency = $objp->fk_multicurrency;
4264 $this->multicurrency_code = $objp->multicurrency_code;
4265 $this->multicurrency_subprice = $objp->multicurrency_subprice;
4266 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
4267 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
4268 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
4272 $this->db->free($result);
4291 global $conf, $user;
4295 dol_syslog(get_class($this).
"::insert rang=".$this->rang);
4297 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4300 if (empty($this->tva_tx)) {
4303 if (empty($this->localtax1_tx)) {
4304 $this->localtax1_tx = 0;
4306 if (empty($this->localtax2_tx)) {
4307 $this->localtax2_tx = 0;
4309 if (empty($this->localtax1_type)) {
4310 $this->localtax1_type = 0;
4312 if (empty($this->localtax2_type)) {
4313 $this->localtax2_type = 0;
4315 if (empty($this->total_localtax1)) {
4316 $this->total_localtax1 = 0;
4318 if (empty($this->total_localtax2)) {
4319 $this->total_localtax2 = 0;
4321 if (empty($this->rang)) {
4324 if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) {
4325 $this->remise_percent = 0;
4327 if (empty($this->info_bits)) {
4328 $this->info_bits = 0;
4330 if (empty($this->special_code)) {
4331 $this->special_code = 0;
4333 if (empty($this->fk_parent_line)) {
4334 $this->fk_parent_line = 0;
4336 if (empty($this->fk_fournprice)) {
4337 $this->fk_fournprice = 0;
4339 if (!is_numeric($this->qty)) {
4342 if (empty($this->pa_ht)) {
4345 if (empty($this->multicurrency_subprice)) {
4346 $this->multicurrency_subprice = 0;
4348 if (empty($this->multicurrency_total_ht)) {
4349 $this->multicurrency_total_ht = 0;
4351 if (empty($this->multicurrency_total_tva)) {
4352 $this->multicurrency_total_tva = 0;
4354 if (empty($this->multicurrency_total_ttc)) {
4355 $this->multicurrency_total_ttc = 0;
4359 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4360 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4363 $this->pa_ht = $result;
4368 if ($this->product_type < 0) {
4375 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'propaldet';
4376 $sql .=
' (fk_propal, fk_parent_line, label, description, fk_product, product_type,';
4377 $sql .=
' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
4378 $sql .=
' subprice, remise_percent, ';
4379 $sql .=
' info_bits, ';
4380 $sql .=
' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,';
4381 $sql .=
' fk_unit,';
4382 $sql .=
' date_start, date_end';
4383 $sql .=
', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)';
4384 $sql .=
" VALUES (".$this->fk_propal.
",";
4385 $sql .=
" ".($this->fk_parent_line > 0 ?
"'".$this->db->escape($this->fk_parent_line).
"'" :
"null").
",";
4386 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
4387 $sql .=
" '".$this->db->escape($this->desc).
"',";
4388 $sql .=
" ".($this->fk_product ?
"'".$this->db->escape($this->fk_product).
"'" :
"null").
",";
4389 $sql .=
" '".$this->db->escape($this->product_type).
"',";
4390 $sql .=
" ".($this->fk_remise_except ?
"'".$this->db->escape($this->fk_remise_except).
"'" :
"null").
",";
4391 $sql .=
" ".price2num($this->qty,
'MS').
",";
4392 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
4393 $sql .=
" ".price2num($this->tva_tx).
",";
4394 $sql .=
" ".price2num($this->localtax1_tx).
",";
4395 $sql .=
" ".price2num($this->localtax2_tx).
",";
4396 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
4397 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
4398 $sql .=
" ".(price2num($this->subprice) !==
'' ?
price2num($this->subprice,
'MU') :
"null").
",";
4399 $sql .=
" ".price2num($this->remise_percent, 3).
",";
4400 $sql .=
" ".(isset($this->info_bits) ? ((int) $this->info_bits) :
"null").
",";
4401 $sql .=
" ".price2num($this->total_ht,
'MT').
",";
4402 $sql .=
" ".price2num($this->total_tva,
'MT').
",";
4403 $sql .=
" ".price2num($this->total_localtax1,
'MT').
",";
4404 $sql .=
" ".price2num($this->total_localtax2,
'MT').
",";
4405 $sql .=
" ".price2num($this->total_ttc,
'MT').
",";
4406 $sql .=
" ".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null").
",";
4407 $sql .=
" ".(isset($this->pa_ht) ?
"'".price2num($this->pa_ht).
"'" :
"null").
",";
4408 $sql .=
' '.((int) $this->special_code).
',';
4409 $sql .=
' '.((int) $this->rang).
',';
4410 $sql .=
' '.(empty($this->fk_unit) ?
'NULL' : ((int) $this->fk_unit)).
',';
4411 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
',';
4412 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4413 $sql .=
", ".($this->fk_multicurrency > 0 ? ((int) $this->fk_multicurrency) :
'null');
4414 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
4415 $sql .=
", ".price2num($this->multicurrency_subprice,
'CU');
4416 $sql .=
", ".price2num($this->multicurrency_total_ht,
'CT');
4417 $sql .=
", ".price2num($this->multicurrency_total_tva,
'CT');
4418 $sql .=
", ".price2num($this->multicurrency_total_ttc,
'CT');
4421 dol_syslog(get_class($this).
'::insert', LOG_DEBUG);
4422 $resql = $this->db->query(
$sql);
4424 $this->
rowid = $this->db->last_insert_id(MAIN_DB_PREFIX.
'propaldet');
4427 $this->
id = $this->rowid;
4434 if (!$error && !$notrigger) {
4436 $result = $this->
call_trigger(
'LINEPROPAL_INSERT', $user);
4438 $this->db->rollback();
4444 $this->db->commit();
4447 $this->error = $this->db->error().
" sql=".
$sql;
4448 $this->db->rollback();
4460 public function delete(
User $user, $notrigger = 0)
4469 $result = $this->
call_trigger(
'LINEPROPAL_DELETE', $user);
4477 $sql =
"DELETE FROM " . MAIN_DB_PREFIX .
"propaldet WHERE rowid = " . ((int) $this->
rowid);
4478 dol_syslog(
"PropaleLigne::delete", LOG_DEBUG);
4479 if ($this->db->query(
$sql)) {
4482 $this->
id = $this->rowid;
4486 dol_syslog(get_class($this) .
"::delete error -4 " . $this->error, LOG_ERR);
4490 $this->error = $this->db->error() .
" sql=" .
$sql;
4496 $this->db->rollback();
4499 $this->db->commit();
4512 global $conf, $user;
4516 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4518 if (empty($this->
id) && !empty($this->
rowid)) {
4519 $this->
id = $this->rowid;
4523 if (empty($this->tva_tx)) {
4526 if (empty($this->localtax1_tx)) {
4527 $this->localtax1_tx = 0;
4529 if (empty($this->localtax2_tx)) {
4530 $this->localtax2_tx = 0;
4532 if (empty($this->total_localtax1)) {
4533 $this->total_localtax1 = 0;
4535 if (empty($this->total_localtax2)) {
4536 $this->total_localtax2 = 0;
4538 if (empty($this->localtax1_type)) {
4539 $this->localtax1_type = 0;
4541 if (empty($this->localtax2_type)) {
4542 $this->localtax2_type = 0;
4544 if (empty($this->marque_tx)) {
4545 $this->marque_tx = 0;
4547 if (empty($this->marge_tx)) {
4548 $this->marge_tx = 0;
4550 if (empty($this->
price)) {
4553 if (empty($this->remise_percent)) {
4554 $this->remise_percent = 0;
4556 if (empty($this->info_bits)) {
4557 $this->info_bits = 0;
4559 if (empty($this->special_code)) {
4560 $this->special_code = 0;
4562 if (empty($this->fk_parent_line)) {
4563 $this->fk_parent_line = 0;
4565 if (empty($this->fk_fournprice)) {
4566 $this->fk_fournprice = 0;
4568 if (empty($this->subprice)) {
4569 $this->subprice = 0;
4571 if (empty($this->pa_ht)) {
4576 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4577 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4580 $this->pa_ht = $result;
4587 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4588 $sql .=
" description='".$this->db->escape($this->desc).
"'";
4589 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
4590 $sql .=
", product_type=".$this->product_type;
4591 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"'";
4592 $sql .=
", tva_tx='".price2num($this->tva_tx).
"'";
4593 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
4594 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
4595 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
4596 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
4597 $sql .=
", qty='".price2num($this->qty).
"'";
4598 $sql .=
", subprice=".price2num($this->subprice);
4599 $sql .=
", remise_percent=".price2num($this->remise_percent);
4602 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
4603 if (empty($this->skip_update_total)) {
4604 $sql .=
", total_ht=".price2num($this->total_ht);
4605 $sql .=
", total_tva=".price2num($this->total_tva);
4606 $sql .=
", total_ttc=".price2num($this->total_ttc);
4607 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
4608 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
4610 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
4611 $sql .=
", buy_price_ht=".price2num($this->pa_ht);
4612 if (strlen($this->special_code)) {
4613 $sql .=
", special_code=".$this->special_code;
4615 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line :
"null");
4616 if (!empty($this->rang)) {
4617 $sql .=
", rang=".((int) $this->rang);
4619 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
4620 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4621 $sql .=
", fk_unit=".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
4624 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
4625 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
4626 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
4627 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
4629 $sql .=
" WHERE rowid = ".((int) $this->
id);
4631 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
4632 $resql = $this->db->query(
$sql);
4641 if (!$error && !$notrigger) {
4643 $result = $this->
call_trigger(
'LINEPROPAL_MODIFY', $user);
4645 $this->db->rollback();
4651 $this->db->commit();
4654 $this->error = $this->db->error();
4655 $this->db->rollback();
4673 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4674 $sql .=
" total_ht=".price2num($this->total_ht,
'MT');
4675 $sql .=
",total_tva=".price2num($this->total_tva,
'MT');
4676 $sql .=
",total_ttc=".price2num($this->total_ttc,
'MT');
4677 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
4679 dol_syslog(
"PropaleLigne::update_total", LOG_DEBUG);
4681 $resql = $this->db->query(
$sql);
4683 $this->db->commit();
4686 $this->error = $this->db->error();
4687 $this->db->rollback();
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.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
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 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.
trait CommonIncoterm
Superclass for incoterm classes.
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
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).
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
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.
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.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
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.
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...
getMarginInfos($pvht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $paht)
Return an array with margins information of a line.
div float
Buy price without taxes.
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.