43require_once DOL_DOCUMENT_ROOT.
'/core/class/commonobject.class.php';
44require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobjectline.class.php";
45require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
46require_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
47require_once DOL_DOCUMENT_ROOT.
'/margin/lib/margins.lib.php';
48require_once DOL_DOCUMENT_ROOT.
'/multicurrency/class/multicurrency.class.php';
49require_once DOL_DOCUMENT_ROOT.
'/core/class/commonincoterm.class.php';
66 public $element =
'propal';
71 public $table_element =
'propal';
76 public $table_element_line =
'propaldet';
81 public $fk_element =
'fk_propal';
86 public $picto =
'propal';
92 public $restrictiononfksoc = 1;
124 public $ref_customer;
155 public $date_creation;
166 public $date_validation;
171 public $date_signature;
176 public $user_signature;
192 public $delivery_date;
195 public $fin_validite;
197 public $user_author_id;
215 public $cond_reglement_code;
216 public $cond_reglement;
217 public $cond_reglement_doc;
219 public $mode_reglement_code;
220 public $mode_reglement;
222 public $deposit_percent;
230 public $address_type;
236 public $availability_id;
243 public $fk_availability;
248 public $availability_code;
253 public $availability;
255 public $duree_validite;
257 public $demand_reason_id;
258 public $demand_reason_code;
259 public $demand_reason;
261 public $warehouse_id;
263 public $extraparams = array();
268 public $lines = array();
275 public $labelStatus = array();
276 public $labelStatusShort = array();
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),
326 'total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalHT',
'enabled' => 1,
'visible' => -1,
'position' => 125,
'isameasure' => 1),
327 'total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'VAT',
'enabled' => 1,
'visible' => -1,
'position' => 130,
'isameasure' => 1),
328 'localtax1' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax1',
'enabled' => 1,
'visible' => -1,
'position' => 135,
'isameasure' => 1),
329 'localtax2' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax2',
'enabled' => 1,
'visible' => -1,
'position' => 140,
'isameasure' => 1),
330 'total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalTTC',
'enabled' => 1,
'visible' => -1,
'position' => 145,
'isameasure' => 1),
331 'fk_account' => array(
'type' =>
'integer',
'label' =>
'BankAccount',
'enabled' =>
'isModEnabled("bank")',
'visible' => -1,
'position' => 150),
332 'fk_currency' => array(
'type' =>
'varchar(3)',
'label' =>
'Currency',
'enabled' => 1,
'visible' => -1,
'position' => 155),
333 'fk_cond_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentTerm',
'enabled' => 1,
'visible' => -1,
'position' => 160),
334 'deposit_percent' => array(
'type' =>
'varchar(63)',
'label' =>
'DepositPercent',
'enabled' => 1,
'visible' => -1,
'position' => 161),
335 'fk_mode_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentMode',
'enabled' => 1,
'visible' => -1,
'position' => 165),
336 'note_private' => array(
'type' =>
'html',
'label' =>
'NotePrivate',
'enabled' => 1,
'visible' => 0,
'position' => 170),
337 'note_public' => array(
'type' =>
'html',
'label' =>
'NotePublic',
'enabled' => 1,
'visible' => 0,
'position' => 175),
338 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'PDFTemplate',
'enabled' => 1,
'visible' => 0,
'position' => 180),
339 'date_livraison' => array(
'type' =>
'date',
'label' =>
'DateDeliveryPlanned',
'enabled' => 1,
'visible' => -1,
'position' => 185),
340 'fk_shipping_method' => array(
'type' =>
'integer',
'label' =>
'ShippingMethod',
'enabled' => 1,
'visible' => -1,
'position' => 190),
341 'fk_warehouse' => array(
'type' =>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label' =>
'Fk warehouse',
'enabled' =>
'isModEnabled("stock")',
'visible' => -1,
'position' => 191),
342 'fk_availability' => array(
'type' =>
'integer',
'label' =>
'Availability',
'enabled' => 1,
'visible' => -1,
'position' => 195),
343 'fk_delivery_address' => array(
'type' =>
'integer',
'label' =>
'DeliveryAddress',
'enabled' => 1,
'visible' => 0,
'position' => 200),
344 'fk_input_reason' => array(
'type' =>
'integer',
'label' =>
'InputReason',
'enabled' => 1,
'visible' => -1,
'position' => 205),
345 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => -1,
'position' => 215),
346 'fk_incoterms' => array(
'type' =>
'integer',
'label' =>
'IncotermCode',
'enabled' =>
'isModEnabled("incoterm")',
'visible' => -1,
'position' => 220),
347 'location_incoterms' => array(
'type' =>
'varchar(255)',
'label' =>
'IncotermLabel',
'enabled' =>
'isModEnabled("incoterm")',
'visible' => -1,
'position' => 225),
348 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'MulticurrencyID',
'enabled' => 1,
'visible' => -1,
'position' => 230),
349 'multicurrency_code' => array(
'type' =>
'varchar(255)',
'label' =>
'MulticurrencyCurrency',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 235),
350 'multicurrency_tx' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyRate',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 240,
'isameasure' => 1),
351 'multicurrency_total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountHT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 245,
'isameasure' => 1),
352 'multicurrency_total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountVAT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 250,
'isameasure' => 1),
353 'multicurrency_total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountTTC',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 255,
'isameasure' => 1),
354 'last_main_doc' => array(
'type' =>
'varchar(255)',
'label' =>
'LastMainDoc',
'enabled' => 1,
'visible' => -1,
'position' => 260),
355 'fk_statut' => array(
'type' =>
'smallint(6)',
'label' =>
'Status',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 500),
356 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -2,
'position' => 900),
397 $this->ismultientitymanaged = 1;
398 $this->socid = $socid;
399 $this->
id = $propalid;
401 $this->duree_validite =
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
417 public function add_product($idproduct, $qty, $remise_percent = 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;
456 $line->remise_percent = $remise_percent;
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);
491 if ($remise->fk_facture) {
492 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
493 $this->db->rollback();
499 $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 = array(), $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';
589 if (empty($remise_percent)) {
595 if (empty($info_bits)) {
601 if (empty($fk_parent_line) || $fk_parent_line < 0) {
605 $remise_percent =
price2num($remise_percent);
608 $pu_ht_devise =
price2num($pu_ht_devise);
610 if (!preg_match(
'/\((.*)\)/', (
string) $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 (
getDolGlobalString(
'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();
659 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
660 $vat_src_code = $reg[1];
661 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
664 $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);
666 $total_ht = $tabprice[0];
667 $total_tva = $tabprice[1];
668 $total_ttc = $tabprice[2];
669 $total_localtax1 = $tabprice[9];
670 $total_localtax2 = $tabprice[10];
671 $pu_ht = $tabprice[3];
672 $pu_tva = $tabprice[4];
673 $pu_ttc = $tabprice[5];
676 $multicurrency_total_ht = $tabprice[16];
677 $multicurrency_total_tva = $tabprice[17];
678 $multicurrency_total_ttc = $tabprice[18];
679 $pu_ht_devise = $tabprice[19];
683 if ($ranktouse == -1) {
684 $rangmax = $this->
line_max($fk_parent_line);
685 $ranktouse = $rangmax + 1;
692 if ((
float) $remise_percent > 0) {
693 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
694 $price = (float) $pu - $remise;
700 $this->line->context = $this->context;
702 $this->line->fk_propal = $this->id;
703 $this->line->label = $label;
704 $this->line->desc = $desc;
705 $this->line->qty = $qty;
707 $this->line->vat_src_code = $vat_src_code;
708 $this->line->tva_tx = $txtva;
709 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
710 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
711 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
712 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
713 $this->line->fk_product = $fk_product;
714 $this->line->product_type = $type;
715 $this->line->fk_remise_except = $fk_remise_except;
716 $this->line->remise_percent = $remise_percent;
717 $this->line->subprice = $pu_ht;
718 $this->line->rang = $ranktouse;
719 $this->line->info_bits = $info_bits;
720 $this->line->total_ht = $total_ht;
721 $this->line->total_tva = $total_tva;
722 $this->line->total_localtax1 = $total_localtax1;
723 $this->line->total_localtax2 = $total_localtax2;
724 $this->line->total_ttc = $total_ttc;
725 $this->line->special_code = $special_code;
726 $this->line->fk_parent_line = $fk_parent_line;
727 $this->line->fk_unit = $fk_unit;
729 $this->line->date_start = $date_start;
730 $this->line->date_end = $date_end;
732 $this->line->fk_fournprice = $fk_fournprice;
733 $this->line->pa_ht = $pa_ht;
735 $this->line->origin_id = $origin_id;
736 $this->line->origin = $origin;
739 $this->line->fk_multicurrency = $this->fk_multicurrency;
740 $this->line->multicurrency_code = $this->multicurrency_code;
741 $this->line->multicurrency_subprice = $pu_ht_devise;
742 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
743 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
744 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
747 if (empty($qty) && empty($special_code)) {
748 $this->line->special_code = 3;
752 $this->line->price =
$price;
754 if (is_array($array_options) && count($array_options) > 0) {
755 $this->line->array_options = $array_options;
758 $result = $this->line->insert();
761 if (!empty($fk_parent_line)) {
763 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
764 $linecount = count($this->lines);
765 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
771 if (empty($noupdateafterinsertline)) {
777 return $this->line->id;
779 $this->error = $this->db->error();
780 $this->db->rollback();
784 $this->error = $this->line->error;
785 $this->errors = $this->line->errors;
786 $this->db->rollback();
790 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
825 public function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $desc =
'', $price_base_type =
'HT', $info_bits = 0, $special_code = 0, $fk_parent_line = 0, $skip_update_total = 0, $fk_fournprice = 0, $pa_ht = 0, $label =
'', $type = 0, $date_start =
'', $date_end =
'', $array_options = array(), $fk_unit =
null, $pu_ht_devise = 0, $notrigger = 0, $rang = 0)
827 global $mysoc, $langs;
829 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
830 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");
831 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
834 $remise_percent =
price2num($remise_percent);
837 $pu_ht_devise =
price2num($pu_ht_devise);
838 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
844 if (empty($qty) && empty($special_code)) {
847 if (!empty($qty) && $special_code == 3) {
854 if ($date_start && $date_end && $date_start > $date_end) {
855 $langs->load(
"errors");
856 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
860 if ($this->
status == self::STATUS_DRAFT) {
873 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
874 $vat_src_code = $reg[1];
875 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
880 $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);
881 $total_ht = $tabprice[0];
882 $total_tva = $tabprice[1];
883 $total_ttc = $tabprice[2];
884 $total_localtax1 = $tabprice[9];
885 $total_localtax2 = $tabprice[10];
886 $pu_ht = $tabprice[3];
887 $pu_tva = $tabprice[4];
888 $pu_ttc = $tabprice[5];
891 $multicurrency_total_ht = $tabprice[16];
892 $multicurrency_total_tva = $tabprice[17];
893 $multicurrency_total_ttc = $tabprice[18];
894 $pu_ht_devise = $tabprice[19];
899 if ((
float) $remise_percent > 0) {
900 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
901 $price = (float) $pu - $remise;
906 $line->fetch($rowid);
908 $staticline = clone $line;
910 $line->oldline = $staticline;
912 $this->line->context = $this->context;
913 $this->line->rang = $rang;
916 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
917 $rangmax = $this->
line_max($fk_parent_line);
918 $this->line->rang = $rangmax + 1;
921 $this->line->id = $rowid;
922 $this->line->label = $label;
923 $this->line->desc = $desc;
924 $this->line->qty = $qty;
925 $this->line->product_type = $type;
926 $this->line->vat_src_code = $vat_src_code;
927 $this->line->tva_tx = $txtva;
928 $this->line->localtax1_tx = $txlocaltax1;
929 $this->line->localtax2_tx = $txlocaltax2;
930 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
931 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
932 $this->line->remise_percent = $remise_percent;
933 $this->line->subprice = $pu_ht;
934 $this->line->info_bits = $info_bits;
936 $this->line->total_ht = $total_ht;
937 $this->line->total_tva = $total_tva;
938 $this->line->total_localtax1 = $total_localtax1;
939 $this->line->total_localtax2 = $total_localtax2;
940 $this->line->total_ttc = $total_ttc;
941 $this->line->special_code = $special_code;
942 $this->line->fk_parent_line = $fk_parent_line;
943 $this->line->skip_update_total = $skip_update_total;
944 $this->line->fk_unit = $fk_unit;
946 $this->line->fk_fournprice = $fk_fournprice;
947 $this->line->pa_ht = $pa_ht;
949 $this->line->date_start = $date_start;
950 $this->line->date_end = $date_end;
952 if (is_array($array_options) && count($array_options) > 0) {
954 foreach ($array_options as $key => $value) {
955 $this->line->array_options[$key] = $array_options[$key];
960 $this->line->multicurrency_subprice = $pu_ht_devise;
961 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
962 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
963 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
965 $result = $this->line->update($notrigger);
968 if (!empty($fk_parent_line)) {
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 = $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 (";
1117 $sql .=
", total_tva";
1118 $sql .=
", total_ttc";
1122 $sql .=
", fk_user_author";
1123 $sql .=
", note_private";
1124 $sql .=
", note_public";
1125 $sql .=
", model_pdf";
1126 $sql .=
", fin_validite";
1127 $sql .=
", fk_cond_reglement";
1128 $sql .=
", deposit_percent";
1129 $sql .=
", fk_mode_reglement";
1130 $sql .=
", fk_account";
1131 $sql .=
", ref_client";
1132 $sql .=
", ref_ext";
1133 $sql .=
", date_livraison";
1134 $sql .=
", fk_shipping_method";
1135 $sql .=
", fk_warehouse";
1136 $sql .=
", fk_availability";
1137 $sql .=
", fk_input_reason";
1138 $sql .=
", fk_projet";
1139 $sql .=
", fk_incoterms";
1140 $sql .=
", location_incoterms";
1142 $sql .=
", fk_multicurrency";
1143 $sql .=
", multicurrency_code";
1144 $sql .=
", multicurrency_tx";
1146 $sql .=
" VALUES (";
1147 $sql .= $this->socid;
1151 $sql .=
", '".$this->db->idate($this->date).
"'";
1152 $sql .=
", '".$this->db->idate($now).
"'";
1153 $sql .=
", '(PROV)'";
1154 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1155 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1156 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1157 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1158 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1159 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1160 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1161 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1162 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1163 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1164 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1165 $sql .=
", ".(empty($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1166 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1167 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1168 $sql .=
", ".$this->availability_id;
1169 $sql .=
", ".$this->demand_reason_id;
1170 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1171 $sql .=
", ".(int) $this->fk_incoterms;
1172 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1173 $sql .=
", ".setEntity($this);
1174 $sql .=
", ".(int) $this->fk_multicurrency;
1175 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1176 $sql .=
", ".(float) $this->multicurrency_tx;
1179 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1180 $resql = $this->db->query($sql);
1182 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1185 $this->
ref =
'(PROV'.$this->id.
')';
1186 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1188 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1189 $resql = $this->db->query($sql);
1194 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1195 $this->linked_objects = $this->linkedObjectsIds;
1199 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1200 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1201 if (is_array($tmp_origin_id)) {
1202 foreach ($tmp_origin_id as $origin_id) {
1205 $this->error = $this->db->lasterror();
1210 $origin_id = $tmp_origin_id;
1213 $this->error = $this->db->lasterror();
1225 $fk_parent_line = 0;
1226 $num = count($this->lines);
1228 for ($i = 0; $i < $num; $i++) {
1229 if (!is_object($this->lines[$i])) {
1231 $line = (object) $this->lines[$i];
1233 $line = $this->lines[$i];
1236 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1237 $fk_parent_line = 0;
1240 $vatrate = $line->tva_tx;
1241 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1242 $vatrate .=
' ('.$line->vat_src_code.
')';
1246 $originid = $line->origin_id;
1247 $origintype = $line->origin;
1249 $originid = $line->id;
1250 $origintype = $this->element;
1258 $line->localtax1_tx,
1259 $line->localtax2_tx,
1261 $line->remise_percent,
1265 $line->product_type,
1267 $line->special_code,
1269 $line->fk_fournprice,
1274 $line->array_options,
1285 $this->error = $this->db->error;
1291 $line->id = $result;
1294 if ($result > 0 && $line->product_type == 9) {
1295 $fk_parent_line = $result;
1325 if (!$error && !$notrigger) {
1334 $this->error = $this->db->lasterror();
1339 $this->error = $this->db->lasterror();
1344 $this->db->commit();
1345 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1348 $this->db->rollback();
1352 $this->error = $this->db->lasterror();
1353 $this->db->rollback();
1368 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1370 global $conf, $hookmanager, $mysoc;
1379 $object =
new self($this->db);
1386 $objsoc =
new Societe($this->db);
1389 if (!empty($socid) && $socid !=
$object->socid) {
1390 if ($objsoc->fetch($socid) > 0) {
1392 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1393 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1394 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1395 $object->fk_delivery_address = 0;
1417 $objsoc->fetch(
$object->socid);
1421 if ($update_prices ===
true || $update_desc ===
true) {
1422 if ($objsoc->id > 0 && !empty(
$object->lines)) {
1425 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1428 foreach (
$object->lines as $line) {
1431 if ($line->fk_product > 0) {
1432 $prod =
new Product($this->db);
1433 $res = $prod->fetch($line->fk_product);
1435 if ($update_prices ===
true) {
1436 $pu_ht = $prod->price;
1438 $remise_percent = $objsoc->remise_percent;
1441 $pu_ht = $prod->multiprices[$objsoc->price_level];
1443 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1444 $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
1449 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1450 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1453 if (count($prodcustprice->lines) > 0) {
1454 $pu_ht =
price($prodcustprice->lines[0]->price);
1455 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1456 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1457 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1463 $line->subprice = $pu_ht;
1464 $line->tva_tx = $tva_tx;
1465 $line->remise_percent = $remise_percent;
1467 if ($update_desc ===
true) {
1468 $line->desc = $prod->description;
1478 $object->entity = (!empty($forceentity) ? $forceentity :
$object->entity);
1482 $object->user_creation_id = $user->id;
1483 $object->user_validation_id = 0;
1495 $object->context[
'createfromclone'] =
'createfromclone';
1496 $result =
$object->create($user);
1498 $this->error =
$object->error;
1499 $this->errors = array_merge($this->errors,
$object->errors);
1505 if (
$object->copy_linked_contact($this,
'internal') < 0) {
1512 if ($this->socid ==
$object->socid) {
1513 if (
$object->copy_linked_contact($this,
'external') < 0) {
1521 if (is_object($hookmanager)) {
1522 $parameters = array(
'objFrom' => $this,
'clonedObj' =>
$object);
1524 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters,
$object, $action);
1532 unset(
$object->context[
'createfromclone']);
1536 $this->db->commit();
1539 $this->db->rollback();
1553 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1555 $sql =
"SELECT p.rowid, p.ref, p.entity, p.fk_soc";
1556 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1557 $sql .=
", p.datec";
1558 $sql .=
", p.date_signature as dates";
1559 $sql .=
", p.date_valid as datev";
1560 $sql .=
", p.datep as dp";
1561 $sql .=
", p.fin_validite as dfv";
1562 $sql .=
", p.date_livraison as delivery_date";
1563 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1564 $sql .=
", p.note_private, p.note_public";
1565 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1566 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1567 $sql .=
", p.fk_delivery_address";
1568 $sql .=
", p.fk_availability";
1569 $sql .=
", p.fk_input_reason";
1570 $sql .=
", p.fk_cond_reglement";
1571 $sql .=
", p.fk_mode_reglement";
1572 $sql .=
', p.fk_account';
1573 $sql .=
", p.fk_shipping_method";
1574 $sql .=
", p.fk_warehouse";
1575 $sql .=
", p.fk_incoterms, p.location_incoterms";
1576 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1577 $sql .=
", p.tms as date_modification";
1578 $sql .=
", i.libelle as label_incoterms";
1579 $sql .=
", c.label as statut_label";
1580 $sql .=
", ca.code as availability_code, ca.label as availability";
1581 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1582 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1583 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1584 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1585 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1586 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1587 $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').
')';
1588 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1589 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1590 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1593 if (!empty($forceentity)) {
1594 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1596 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1598 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1601 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1604 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1605 $resql = $this->db->query($sql);
1607 if ($this->db->num_rows($resql)) {
1608 $obj = $this->db->fetch_object($resql);
1610 $this->
id = $obj->rowid;
1611 $this->entity = $obj->entity;
1613 $this->
ref = $obj->ref;
1614 $this->ref_client = $obj->ref_client;
1615 $this->ref_customer = $obj->ref_client;
1616 $this->ref_ext = $obj->ref_ext;
1618 $this->total = $obj->total_ttc;
1619 $this->total_ttc = $obj->total_ttc;
1620 $this->total_ht = $obj->total_ht;
1621 $this->total_tva = $obj->total_tva;
1622 $this->total_localtax1 = $obj->localtax1;
1623 $this->total_localtax2 = $obj->localtax2;
1625 $this->socid = $obj->fk_soc;
1626 $this->thirdparty =
null;
1628 $this->fk_project = $obj->fk_project;
1629 $this->project =
null;
1631 $this->model_pdf = $obj->model_pdf;
1632 $this->last_main_doc = $obj->last_main_doc;
1633 $this->note = $obj->note_private;
1634 $this->note_private = $obj->note_private;
1635 $this->note_public = $obj->note_public;
1637 $this->
status = (int) $obj->fk_statut;
1638 $this->
statut = $this->status;
1640 $this->datec = $this->db->jdate($obj->datec);
1641 $this->datev = $this->db->jdate($obj->datev);
1642 $this->date_creation = $this->db->jdate($obj->datec);
1643 $this->date_validation = $this->db->jdate($obj->datev);
1644 $this->date_modification = $this->db->jdate($obj->date_modification);
1645 $this->date_signature = $this->db->jdate($obj->dates);
1646 $this->date = $this->db->jdate($obj->dp);
1647 $this->datep = $this->db->jdate($obj->dp);
1648 $this->fin_validite = $this->db->jdate($obj->dfv);
1649 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1650 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1651 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1652 $this->availability_id = $obj->fk_availability;
1653 $this->availability_code = $obj->availability_code;
1655 $this->demand_reason_id = $obj->fk_input_reason;
1656 $this->demand_reason_code = $obj->demand_reason_code;
1658 $this->fk_address = $obj->fk_delivery_address;
1660 $this->mode_reglement_id = $obj->fk_mode_reglement;
1661 $this->mode_reglement_code = $obj->mode_reglement_code;
1662 $this->mode_reglement = $obj->mode_reglement;
1663 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1664 $this->cond_reglement_id = $obj->fk_cond_reglement;
1665 $this->cond_reglement_code = $obj->cond_reglement_code;
1666 $this->cond_reglement = $obj->cond_reglement;
1667 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1668 $this->deposit_percent = $obj->deposit_percent;
1670 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1672 $this->user_author_id = $obj->fk_user_author;
1673 $this->user_validation_id = $obj->fk_user_valid;
1674 $this->user_closing_id = $obj->fk_user_cloture;
1677 $this->fk_incoterms = $obj->fk_incoterms;
1678 $this->location_incoterms = $obj->location_incoterms;
1679 $this->label_incoterms = $obj->label_incoterms;
1682 $this->fk_multicurrency = $obj->fk_multicurrency;
1683 $this->multicurrency_code = $obj->multicurrency_code;
1684 $this->multicurrency_tx = $obj->multicurrency_tx;
1685 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1686 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1687 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1693 $this->db->free($resql);
1695 $this->lines = array();
1706 $this->error =
"Record Not Found";
1709 $this->error = $this->db->lasterror();
1728 if (isset($this->
ref)) {
1729 $this->
ref = trim($this->
ref);
1731 if (isset($this->ref_client)) {
1732 $this->ref_client = trim($this->ref_client);
1734 if (isset($this->note) || isset($this->note_private)) {
1735 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1737 if (isset($this->note_public)) {
1738 $this->note_public = trim($this->note_public);
1740 if (isset($this->model_pdf)) {
1741 $this->model_pdf = trim($this->model_pdf);
1743 if (isset($this->import_key)) {
1744 $this->import_key = trim($this->import_key);
1746 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1747 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1754 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1755 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1756 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1757 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1758 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1759 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1760 if (!empty($this->fin_validite)) {
1761 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1763 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1764 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1765 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1766 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1767 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1768 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1769 $sql .=
" fk_statut=".(isset($this->
statut) ? $this->
statut :
"null").
",";
1770 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1771 $sql .=
" fk_user_valid = ".(!empty($this->user_validation_id) ? (int) $this->user_validation_id :
"null").
",";
1772 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1773 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1774 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1775 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1776 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1777 $sql .=
" fk_shipping_method=".(isset($this->shipping_method_id) ? (int) $this->shipping_method_id :
"null").
",";
1778 $sql .=
" fk_availability=".(isset($this->availability_id) ? (int) $this->availability_id :
"null").
",";
1779 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1780 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1781 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1782 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1783 $sql .=
" WHERE rowid=".((int) $this->
id);
1787 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1788 $resql = $this->db->query($sql);
1791 $this->errors[] =
"Error ".$this->db->lasterror();
1801 if (!$error && !$notrigger) {
1812 foreach ($this->errors as $errmsg) {
1813 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1814 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1816 $this->db->rollback();
1819 $this->db->commit();
1834 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $sqlforgedfilters =
'')
1837 $this->lines = array();
1839 $sql =
'SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.vat_src_code, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.localtax1_type, d.localtax2_type, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,';
1840 $sql .=
' d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,';
1841 $sql .=
' d.fk_unit,';
1842 $sql .=
' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label, p.tobatch as product_tobatch, p.barcode as product_barcode,';
1843 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1844 $sql .=
' d.date_start, d.date_end,';
1845 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1846 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1847 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1848 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1849 if ($only_product) {
1850 $sql .=
' AND p.fk_product_type = 0';
1852 if ($sqlforgedfilters) {
1853 $sql .= $sqlforgedfilters;
1855 $sql .=
' ORDER by d.rang';
1857 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1858 $result = $this->db->query($sql);
1860 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1862 $num = $this->db->num_rows($result);
1866 $objp = $this->db->fetch_object($result);
1870 $line->rowid = $objp->rowid;
1871 $line->id = $objp->rowid;
1872 $line->fk_propal = $objp->fk_propal;
1873 $line->fk_parent_line = $objp->fk_parent_line;
1874 $line->product_type = $objp->product_type;
1875 $line->label = $objp->custom_label;
1876 $line->desc = $objp->description;
1877 $line->description = $objp->description;
1878 $line->qty = $objp->qty;
1879 $line->vat_src_code = $objp->vat_src_code;
1880 $line->tva_tx = $objp->tva_tx;
1881 $line->localtax1_tx = $objp->localtax1_tx;
1882 $line->localtax2_tx = $objp->localtax2_tx;
1883 $line->localtax1_type = $objp->localtax1_type;
1884 $line->localtax2_type = $objp->localtax2_type;
1885 $line->subprice = $objp->subprice;
1886 $line->fk_remise_except = $objp->fk_remise_except;
1887 $line->remise_percent = $objp->remise_percent;
1888 $line->price = $objp->price;
1890 $line->info_bits = $objp->info_bits;
1891 $line->total_ht = $objp->total_ht;
1892 $line->total_tva = $objp->total_tva;
1893 $line->total_localtax1 = $objp->total_localtax1;
1894 $line->total_localtax2 = $objp->total_localtax2;
1895 $line->total_ttc = $objp->total_ttc;
1896 $line->fk_fournprice = $objp->fk_fournprice;
1897 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1898 $line->pa_ht = $marginInfos[0];
1899 $line->marge_tx = $marginInfos[1];
1900 $line->marque_tx = $marginInfos[2];
1901 $line->special_code = $objp->special_code;
1902 $line->rang = $objp->rang;
1904 $line->fk_product = $objp->fk_product;
1906 $line->ref = $objp->product_ref;
1907 $line->libelle = $objp->product_label;
1909 $line->product_ref = $objp->product_ref;
1910 $line->product_label = $objp->product_label;
1911 $line->product_desc = $objp->product_desc;
1912 $line->product_tobatch = $objp->product_tobatch;
1913 $line->product_barcode = $objp->product_barcode;
1915 $line->fk_product_type = $objp->fk_product_type;
1916 $line->fk_unit = $objp->fk_unit;
1917 $line->weight = $objp->weight;
1918 $line->weight_units = $objp->weight_units;
1919 $line->volume = $objp->volume;
1920 $line->volume_units = $objp->volume_units;
1922 $line->date_start = $this->db->jdate($objp->date_start);
1923 $line->date_end = $this->db->jdate($objp->date_end);
1926 $line->fk_multicurrency = $objp->fk_multicurrency;
1927 $line->multicurrency_code = $objp->multicurrency_code;
1928 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1929 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1930 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1931 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1933 $line->fetch_optionals();
1936 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1937 $tmpproduct =
new Product($this->db);
1938 $tmpproduct->fetch($objp->fk_product);
1939 $tmpproduct->getMultiLangs();
1941 $line->multilangs = $tmpproduct->multilangs;
1944 $this->lines[$i] = $line;
1949 $this->db->free($result);
1953 $this->error = $this->db->lasterror();
1965 public function valid($user, $notrigger = 0)
1969 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1974 if ($this->
statut == self::STATUS_VALIDATED) {
1975 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
1979 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'creer'))
1980 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'propal_advance',
'validate')))) {
1981 $this->error =
'ErrorPermissionDenied';
1982 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
1991 $soc =
new Societe($this->db);
1992 $soc->fetch($this->socid);
1995 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2002 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2003 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2004 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2007 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2008 $resql = $this->db->query($sql);
2015 if (!$error && !$notrigger) {
2017 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2025 $this->oldref = $this->ref;
2028 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2030 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filename = CONCAT('".$this->db->escape($this->newref).
"', SUBSTR(filename, ".(strlen($this->
ref) + 1).
")), filepath = 'propale/".$this->db->escape($this->newref).
"'";
2031 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2032 $resql = $this->db->query($sql);
2035 $this->error = $this->db->lasterror();
2037 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2038 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2039 $resql = $this->db->query($sql);
2042 $this->error = $this->db->lasterror();
2048 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2049 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2050 if (!$error && file_exists($dirsource)) {
2051 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2052 if (@rename($dirsource, $dirdest)) {
2055 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2056 foreach ($listoffiles as $fileentry) {
2057 $dirsource = $fileentry[
'name'];
2058 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2059 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2060 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2061 @rename($dirsource, $dirdest);
2069 $this->user_validation_id = $user->id;
2070 $this->datev = $now;
2071 $this->date_validation = $now;
2073 $this->db->commit();
2076 $this->db->rollback();
2095 $this->error =
'ErrorBadParameter';
2096 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2100 if ($user->hasRight(
'propal',
'creer')) {
2105 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2106 $sql .=
" WHERE rowid = ".((int) $this->
id);
2109 $resql = $this->db->query($sql);
2111 $this->errors[] = $this->db->error();
2116 $this->oldcopy = clone $this;
2117 $this->date = $date;
2118 $this->datep = $date;
2121 if (!$notrigger && empty($error)) {
2131 $this->db->commit();
2134 foreach ($this->errors as $errmsg) {
2135 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2136 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2138 $this->db->rollback();
2158 if ($user->hasRight(
'propal',
'creer')) {
2163 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2164 $sql .=
" WHERE rowid = ".((int) $this->
id);
2168 $resql = $this->db->query($sql);
2170 $this->errors[] = $this->db->error();
2176 $this->oldcopy = clone $this;
2177 $this->fin_validite = $date_end_validity;
2180 if (!$notrigger && empty($error)) {
2190 $this->db->commit();
2193 foreach ($this->errors as $errmsg) {
2194 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2195 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2197 $this->db->rollback();
2231 if ($user->hasRight(
'propal',
'creer')) {
2236 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2237 $sql .=
" SET date_livraison = ".($delivery_date !=
'' ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2238 $sql .=
" WHERE rowid = ".((int) $this->
id);
2241 $resql = $this->db->query($sql);
2243 $this->errors[] = $this->db->error();
2248 $this->oldcopy = clone $this;
2249 $this->delivery_date = $delivery_date;
2252 if (!$notrigger && empty($error)) {
2262 $this->db->commit();
2265 foreach ($this->errors as $errmsg) {
2266 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2267 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2269 $this->db->rollback();
2289 if ($user->hasRight(
'propal',
'creer') && $this->statut >= self::STATUS_DRAFT) {
2294 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2295 $sql .=
" SET fk_availability = ".((int) $id);
2296 $sql .=
" WHERE rowid = ".((int) $this->
id);
2298 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2299 $resql = $this->db->query($sql);
2301 $this->errors[] = $this->db->error();
2306 $this->oldcopy = clone $this;
2307 $this->fk_availability = $id;
2308 $this->availability_id = $id;
2311 if (!$notrigger && empty($error)) {
2321 $this->db->commit();
2324 foreach ($this->errors as $errmsg) {
2325 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2326 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2328 $this->db->rollback();
2332 $error_str =
'Propal status do not meet requirement '.$this->statut;
2334 $this->error = $error_str;
2335 $this->errors[] = $this->error;
2352 if ($user->hasRight(
'propal',
'creer') && $this->statut >= self::STATUS_DRAFT) {
2357 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2358 $sql .=
" SET fk_input_reason = ".((int) $id);
2359 $sql .=
" WHERE rowid = ".((int) $this->
id);
2362 $resql = $this->db->query($sql);
2364 $this->errors[] = $this->db->error();
2370 $this->oldcopy = clone $this;
2372 $this->demand_reason_id = $id;
2376 if (!$notrigger && empty($error)) {
2386 $this->db->commit();
2389 foreach ($this->errors as $errmsg) {
2390 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2391 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2393 $this->db->rollback();
2397 $error_str =
'Propal status do not meet requirement '.$this->statut;
2399 $this->error = $error_str;
2400 $this->errors[] = $this->error;
2417 if ($user->hasRight(
'propal',
'creer')) {
2422 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2423 $sql .=
" WHERE rowid = ".((int) $this->
id);
2425 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2426 $resql = $this->db->query($sql);
2428 $this->errors[] = $this->db->error();
2433 $this->oldcopy = clone $this;
2434 $this->ref_client = $ref_client;
2437 if (!$notrigger && empty($error)) {
2447 $this->db->commit();
2450 foreach ($this->errors as $errmsg) {
2451 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2452 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2454 $this->db->rollback();
2472 public function reopen($user, $status, $note =
'', $notrigger = 0)
2476 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2477 $sql .=
" SET fk_statut = ".((int) $status).
",";
2478 if (!empty($note)) {
2479 $sql .=
" note_private = '".$this->db->escape($note).
"',";
2481 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2482 $sql .=
" WHERE rowid = ".((int) $this->
id);
2486 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2487 $resql = $this->db->query($sql);
2490 $this->errors[] =
"Error ".$this->db->lasterror();
2505 if (!empty($this->errors)) {
2506 foreach ($this->errors as $errmsg) {
2507 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2508 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2511 $this->db->rollback();
2517 $this->db->commit();
2533 global $langs,$conf;
2543 $date_signature = $now;
2544 $fk_user_signature = $user->id;
2546 $this->
info($this->
id);
2547 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2548 $date_signature = $now;
2549 $fk_user_signature = $user->id;
2551 $date_signature = $this->date_signature;
2552 $fk_user_signature = $this->user_signature->id;
2556 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2557 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"'";
2558 if ($status == self::STATUS_SIGNED) {
2559 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2561 $sql .=
" WHERE rowid = ".((int) $this->
id);
2563 $resql = $this->db->query($sql);
2567 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2569 if ($status == self::STATUS_SIGNED) {
2570 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2571 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_TOBILL') ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2574 $soc =
new Societe($this->db);
2575 $soc->id = $this->socid;
2576 $result = $soc->setAsCustomer();
2579 $this->error = $this->db->lasterror();
2580 $this->db->rollback();
2587 $outputlangs = $langs;
2589 $outputlangs =
new Translate(
"", $conf);
2590 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2591 $outputlangs->setDefaultLang($newlang);
2600 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2604 $this->oldcopy = clone $this;
2607 $this->date_signature = $date_signature;
2608 $this->note_private = $newprivatenote;
2611 if (!$notrigger && empty($error)) {
2621 $this->db->commit();
2624 $this->
statut = $this->oldcopy->statut;
2625 $this->
status = $this->oldcopy->statut;
2626 $this->date_signature = $this->oldcopy->date_signature;
2627 $this->note_private = $this->oldcopy->note_private;
2629 $this->db->rollback();
2633 $this->error = $this->db->lasterror();
2634 $this->db->rollback();
2649 global $conf, $langs;
2656 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2662 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2663 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2664 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2667 $resql = $this->db->query($sql);
2669 $this->errors[] = $this->db->error();
2672 $num = $this->db->affected_rows($resql);
2680 $outputlangs = $langs;
2682 $outputlangs =
new Translate(
"", $conf);
2683 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2684 $outputlangs->setDefaultLang($newlang);
2693 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2696 $this->oldcopy = clone $this;
2698 $this->date_cloture = $now;
2699 $this->note_private = $newprivatenote;
2702 if (!$notrigger && empty($error)) {
2712 $this->db->commit();
2715 foreach ($this->errors as $errmsg) {
2716 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2717 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2719 $this->db->rollback();
2736 $sql =
"UPDATE ". MAIN_DB_PREFIX .
"propal";
2737 $sql .=
" SET fk_statut = " . self::STATUS_CANCELED .
",";
2738 $sql .=
" fk_user_modif = " . ((int) $user->id);
2739 $sql .=
" WHERE rowid = " . ((int) $this->
id);
2741 dol_syslog(get_class($this).
"::cancel", LOG_DEBUG);
2742 if ($this->db->query($sql)) {
2754 $this->db->commit();
2757 foreach ($this->errors as $errmsg) {
2758 dol_syslog(get_class($this).
"::cancel ".$errmsg, LOG_ERR);
2759 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2761 $this->db->rollback();
2765 $this->error = $this->db->error();
2766 $this->db->rollback();
2785 if ($this->
statut <= self::STATUS_DRAFT) {
2789 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2793 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2794 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2795 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2796 $sql .=
" WHERE rowid = ".((int) $this->
id);
2798 $resql = $this->db->query($sql);
2800 $this->errors[] = $this->db->error();
2805 $this->oldcopy = clone $this;
2808 if (!$notrigger && empty($error)) {
2821 $this->db->commit();
2824 foreach ($this->errors as $errmsg) {
2825 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2826 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2828 $this->db->rollback();
2848 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2855 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2856 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2857 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2858 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2859 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2860 $sql .=
" AND p.fk_soc = s.rowid";
2861 $sql .=
" AND p.fk_statut = c.id";
2865 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
2866 $search_sale = $user->id;
2869 if ($search_sale && $search_sale !=
'-1') {
2870 if ($search_sale == -2) {
2871 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
2872 } elseif ($search_sale > 0) {
2873 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc AND sc.fk_user = ".((int) $search_sale).
")";
2878 $sql .=
" AND p.fk_soc = ".((int) $socid);
2881 $sql .=
" AND p.fk_statut = ".((int) self::STATUS_DRAFT);
2883 if ($notcurrentuser > 0) {
2884 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2886 $sql .= $this->db->order($sortfield, $sortorder);
2887 $sql .= $this->db->plimit($limit, $offset);
2889 $result = $this->db->query($sql);
2891 $num = $this->db->num_rows($result);
2895 $obj = $this->db->fetch_object($result);
2897 if ($shortlist == 1) {
2898 $ga[$obj->propalid] = $obj->ref;
2899 } elseif ($shortlist == 2) {
2900 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2902 $ga[$i][
'id'] = $obj->propalid;
2903 $ga[$i][
'ref'] = $obj->ref;
2904 $ga[$i][
'name'] = $obj->name;
2938 $linkedInvoices = array();
2941 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
2944 foreach ($objectid as $key =>
$object) {
2946 if ($objecttype ==
'facture') {
2951 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
2952 foreach ($subobjectid as $subkey => $subobject) {
2953 if ($subobjecttype ==
'facture') {
2954 $linkedInvoices[] = $subobject;
2962 if (count($linkedInvoices) > 0) {
2963 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
2964 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
2965 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
2967 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
2968 $resql = $this->db->query($sql);
2971 $tab_sqlobj = array();
2972 $nump = $this->db->num_rows($resql);
2973 for ($i = 0; $i < $nump; $i++) {
2974 $sqlobj = $this->db->fetch_object($resql);
2975 $tab_sqlobj[] = $sqlobj;
2977 $this->db->free($resql);
2979 $nump = count($tab_sqlobj);
2983 while ($i < $nump) {
2984 $obj = array_shift($tab_sqlobj);
3007 public function delete($user, $notrigger = 0)
3010 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3026 if (!$error && !empty($this->table_element_line)) {
3027 $tabletodelete = $this->table_element_line;
3028 $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).
")";
3029 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3030 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3032 $this->error = $this->db->lasterror();
3033 $this->errors[] = $this->error;
3034 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3059 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3065 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3066 $res = $this->db->query($sql);
3069 $this->error = $this->db->lasterror();
3070 $this->errors[] = $this->error;
3071 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3087 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3088 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3089 $file = $dir.
"/".$ref.
".pdf";
3090 if (file_exists($file)) {
3094 $this->error =
'ErrorFailToDeleteFile';
3095 $this->errors[] = $this->error;
3096 $this->db->rollback();
3100 if (file_exists($dir)) {
3103 $this->error =
'ErrorFailToDeleteDir';
3104 $this->errors[] = $this->error;
3105 $this->db->rollback();
3113 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3114 $this->db->commit();
3117 $this->db->rollback();
3134 if ($this->
statut >= self::STATUS_DRAFT) {
3139 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3140 $sql .=
' SET fk_availability = '.((int) $availability_id);
3141 $sql .=
' WHERE rowid='.((int) $this->
id);
3143 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3144 $resql = $this->db->query($sql);
3146 $this->errors[] = $this->db->error();
3151 $this->oldcopy = clone $this;
3152 $this->availability_id = $availability_id;
3155 if (!$notrigger && empty($error)) {
3165 $this->db->commit();
3168 foreach ($this->errors as $errmsg) {
3169 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3170 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3172 $this->db->rollback();
3176 $error_str =
'Propal status do not meet requirement '.$this->statut;
3178 $this->error = $error_str;
3179 $this->errors[] = $this->error;
3198 if ($this->
status >= self::STATUS_DRAFT) {
3203 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3204 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3205 $sql .=
' WHERE rowid='.((int) $this->
id);
3207 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3208 $resql = $this->db->query($sql);
3210 $this->errors[] = $this->db->error();
3215 $this->oldcopy = clone $this;
3216 $this->demand_reason_id = $demand_reason_id;
3219 if (!$notrigger && empty($error)) {
3229 $this->db->commit();
3232 foreach ($this->errors as $errmsg) {
3233 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3234 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3236 $this->db->rollback();
3240 $error_str =
'Propal status do not meet requirement '.$this->statut;
3242 $this->error = $error_str;
3243 $this->errors[] = $this->error;
3257 $sql =
"SELECT c.rowid, ";
3258 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3259 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3260 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3261 $sql .=
" WHERE c.rowid = ".((int) $id);
3263 $result = $this->db->query($sql);
3266 if ($this->db->num_rows($result)) {
3267 $obj = $this->db->fetch_object($result);
3269 $this->
id = $obj->rowid;
3271 $this->date_creation = $this->db->jdate($obj->datec);
3272 $this->date_validation = $this->db->jdate($obj->datev);
3273 $this->date_signature = $this->db->jdate($obj->date_signature);
3274 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3276 $this->user_creation_id = $obj->fk_user_author;
3277 $this->user_validation_id = $obj->fk_user_valid;
3279 if ($obj->fk_user_signature) {
3280 $user_signature =
new User($this->db);
3281 $user_signature->fetch($obj->fk_user_signature);
3282 $this->user_signature = $user_signature;
3285 $this->user_closing_id = $obj->fk_user_cloture;
3287 $this->db->free($result);
3316 global $hookmanager;
3319 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3321 $langs->load(
"propal");
3322 $this->labelStatus[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceled");
3323 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3324 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3325 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3326 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3327 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3328 $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceledShort");
3329 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3330 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3331 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3332 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3333 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3337 if ($status == self::STATUS_CANCELED) {
3338 $statusType =
'status9';
3339 } elseif ($status == self::STATUS_DRAFT) {
3340 $statusType =
'status0';
3341 } elseif ($status == self::STATUS_VALIDATED) {
3342 $statusType =
'status1';
3343 } elseif ($status == self::STATUS_SIGNED) {
3344 $statusType =
'status4';
3345 } elseif ($status == self::STATUS_NOTSIGNED) {
3346 $statusType =
'status9';
3347 } elseif ($status == self::STATUS_BILLED) {
3348 $statusType =
'status6';
3351 $parameters = array(
'status' => $status,
'mode' => $mode);
3352 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3355 return $hookmanager->resPrint;
3358 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3373 global $conf, $langs;
3377 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3378 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3379 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3380 if ($mode ==
'opened') {
3381 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3383 if ($mode ==
'signed') {
3384 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3388 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
3389 $search_sale = $user->id;
3392 if ($search_sale && $search_sale !=
'-1') {
3393 if ($search_sale == -2) {
3394 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3395 } elseif ($search_sale > 0) {
3396 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc AND sc.fk_user = ".((int) $search_sale).
")";
3400 $resql = $this->db->query($sql);
3402 $langs->load(
"propal");
3407 $label = $labelShort =
'';
3408 if ($mode ==
'opened') {
3409 $delay_warning = $conf->propal->cloture->warning_delay;
3411 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3412 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3414 if ($mode ==
'signed') {
3415 $delay_warning = $conf->propal->facturation->warning_delay;
3417 $label = $langs->trans(
"PropalsToBill");
3418 $labelShort = $langs->trans(
"ToBill");
3422 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3423 $response->label = $label;
3424 $response->labelShort = $labelShort;
3425 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3426 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3430 while ($obj = $this->db->fetch_object($resql)) {
3431 $response->nbtodo++;
3432 $response->total += $obj->total_ht;
3434 if ($mode ==
'opened') {
3435 $datelimit = $this->db->jdate($obj->datefin);
3436 if ($datelimit < ($now - $delay_warning)) {
3437 $response->nbtodolate++;
3446 $this->error = $this->db->error();
3461 global $conf, $langs;
3466 $sql =
"SELECT rowid";
3467 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3468 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3469 $sql .= $this->db->plimit(100);
3471 $resql = $this->db->query($sql);
3473 $num_prods = $this->db->num_rows($resql);
3475 while ($i < $num_prods) {
3477 $row = $this->db->fetch_row($resql);
3478 $prodids[$i] = $row[0];
3484 $this->
ref =
'SPECIMEN';
3485 $this->ref_client =
'NEMICEPS';
3486 $this->specimen = 1;
3488 $this->date = time();
3489 $this->fin_validite = $this->date + 3600 * 24 * 30;
3490 $this->cond_reglement_id = 1;
3491 $this->cond_reglement_code =
'RECEP';
3492 $this->mode_reglement_id = 7;
3493 $this->mode_reglement_code =
'CHQ';
3494 $this->availability_id = 1;
3495 $this->availability_code =
'AV_NOW';
3496 $this->demand_reason_id = 1;
3497 $this->demand_reason_code =
'SRC_00';
3498 $this->note_public =
'This is a comment (public)';
3499 $this->note_private =
'This is a comment (private)';
3501 $this->multicurrency_tx = 1;
3502 $this->multicurrency_code = $conf->currency;
3507 while ($xnbp < $nbp) {
3509 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3511 $line->subprice = 100;
3514 $line->localtax1_tx = 0;
3515 $line->localtax2_tx = 0;
3517 $line->total_ht = 50;
3518 $line->total_ttc = 60;
3519 $line->total_tva = 10;
3520 $line->remise_percent = 50;
3522 $line->total_ht = 100;
3523 $line->total_ttc = 120;
3524 $line->total_tva = 20;
3525 $line->remise_percent = 00;
3528 if ($num_prods > 0) {
3529 $prodid = mt_rand(1, $num_prods);
3530 $line->fk_product = $prodids[$prodid];
3531 $line->product_ref =
'SPECIMEN';
3534 $this->lines[$xnbp] = $line;
3536 $this->total_ht += $line->total_ht;
3537 $this->total_tva += $line->total_tva;
3538 $this->total_ttc += $line->total_ttc;
3555 $this->nb = array();
3558 $sql =
"SELECT count(p.rowid) as nb";
3559 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3560 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3561 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3565 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
3566 $search_sale = $user->id;
3569 if ($search_sale && $search_sale !=
'-1') {
3570 if ($search_sale == -2) {
3571 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3572 } elseif ($search_sale > 0) {
3573 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc AND sc.fk_user = ".((int) $search_sale).
")";
3577 $resql = $this->db->query($sql);
3580 while ($obj = $this->db->fetch_object($resql)) {
3581 $this->nb[
"proposals"] = $obj->nb;
3583 $this->db->free($resql);
3587 $this->error = $this->db->error();
3602 global $conf, $langs;
3603 $langs->load(
"propal");
3607 if (!empty($classname)) {
3610 $file = $classname.
".php";
3613 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3614 foreach ($dirmodels as $reldir) {
3618 $mybool = ((bool) @include_once $dir.$file) || $mybool;
3626 $obj =
new $classname();
3628 $numref = $obj->getNextValue($soc, $this);
3630 if ($numref !=
"") {
3633 $this->error = $obj->error;
3638 $langs->load(
"errors");
3639 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3652 global $conf, $langs, $user;
3654 $langs->load(
'propal');
3656 $nofetch = !empty($params[
'nofetch']);
3659 return [
'optimize' => $langs->trans(
"Proposal")];
3661 if ($user->hasRight(
'propal',
'lire')) {
3662 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3663 if (isset($this->
status)) {
3664 $datas[
'status'] =
' '.$this->getLibStatut(5);
3666 if (!empty($this->
ref)) {
3667 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3670 $langs->load(
'companies');
3671 if (empty($this->thirdparty)) {
3674 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3676 if (!empty($this->ref_customer)) {
3677 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
3680 $langs->load(
'project');
3681 if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) {
3683 if ($res > 0 && $this->project instanceof
Project) {
3684 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3688 if (!empty($this->total_ht)) {
3689 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3691 if (!empty($this->total_tva)) {
3692 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3694 if (!empty($this->total_ttc)) {
3695 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3697 if (!empty($this->date)) {
3698 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3700 if (!empty($this->delivery_date)) {
3701 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3719 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3721 global $langs, $conf, $user, $hookmanager;
3723 if (!empty($conf->dol_no_mouse_hover)) {
3730 'objecttype' => $this->element,
3731 'option' => $option,
3734 $classfortooltip =
'classfortooltip';
3737 $classfortooltip =
'classforajaxtooltip';
3738 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3745 if ($user->hasRight(
'propal',
'lire')) {
3746 if ($option ==
'') {
3747 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3748 } elseif ($option ==
'compta') {
3749 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3750 } elseif ($option ==
'expedition') {
3751 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3752 } elseif ($option ==
'document') {
3753 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3756 if ($option !=
'nolink') {
3758 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3759 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3760 $add_save_lastsearch_values = 1;
3762 if ($add_save_lastsearch_values) {
3763 $url .=
'&save_lastsearch_values=1';
3769 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3771 $label = $langs->trans(
"Proposal");
3772 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3774 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3775 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3778 $linkstart =
'<a href="'.$url.
'"';
3779 $linkstart .= $linkclose.
'>';
3782 $result .= $linkstart;
3784 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3786 if ($withpicto != 2) {
3787 $result .= $this->ref;
3789 $result .= $linkend;
3791 if ($addlinktonotes >= 0) {
3794 if ($addlinktonotes == 0) {
3795 if (!empty($this->note_private) || !empty($this->note_public)) {
3796 $txttoshow = $langs->trans(
'ViewPrivateNote');
3798 } elseif ($addlinktonotes == 1) {
3799 if (!empty($this->note_private)) {
3802 } elseif ($addlinktonotes == 2) {
3803 if (!empty($this->note_public)) {
3806 } elseif ($addlinktonotes == 3) {
3807 if ($user->socid > 0) {
3808 if (!empty($this->note_public)) {
3812 if (!empty($this->note_public)) {
3815 if (!empty($this->note_private)) {
3816 if (!empty($txttoshow)) {
3817 $txttoshow .=
'<br><br>';
3825 $result .=
' <span class="note inline-block">';
3826 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3829 $result .=
'</span>';
3834 $hookmanager->initHooks(array($this->element .
'dao'));
3835 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
3836 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3838 $result = $hookmanager->resPrint;
3840 $result .= $hookmanager->resPrint;
3853 return $this->
fetch_lines(0, 0, $sqlforgedfilters);
3867 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3869 global $conf, $langs;
3871 $langs->load(
"propale");
3872 $outputlangs->load(
"products");
3877 if ($this->model_pdf) {
3878 $modele = $this->model_pdf;
3884 $modelpath =
"core/modules/propale/doc/";
3886 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3934 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
3936 $return =
'<div class="box-flex-item box-flex-grow-zero">';
3937 $return .=
'<div class="info-box info-box-sm">';
3938 $return .=
'<div class="info-box-icon bg-infobox-action">';
3940 $return .=
'</div>';
3941 $return .=
'<div class="info-box-content">';
3942 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
3943 if ($selected >= 0) {
3944 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
3946 if (!empty($arraydata[
'projectlink'])) {
3947 $return .=
'<span class="info-box-ref"> | '.$arraydata[
'projectlink'].
'</span>';
3950 if (property_exists($this,
'thirdparty') && is_object($this->thirdparty)) {
3951 $return .=
'<div class="info-box-ref tdoverflowmax150">'.$this->thirdparty->getNomUrl(1).
'</div>';
3953 if (property_exists($this,
'total_ht')) {
3954 $return .=
'<span class="info-box-label amount" title="'.$langs->trans(
"AmountHT").
'">'.
price($this->total_ht).
'</span>';
3956 if (!empty($arraydata[
'authorlink'])) {
3957 $return .=
' <span class="info-box-label">'.$arraydata[
'authorlink'].
'</span>';
3959 if (method_exists($this,
'getLibStatut')) {
3960 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
3962 $return .=
'</div>';
3963 $return .=
'</div>';
3964 $return .=
'</div>';
3977 public $element =
'propaldet';
3982 public $table_element =
'propaldet';
3998 public $fk_parent_line;
4016 public $vat_src_code;
4023 public $remise_percent;
4024 public $fk_remise_except;
4028 public $fk_fournprice;
4044 public $special_code;
4046 public $info_bits = 0;
4075 public $product_ref;
4090 public $product_label;
4095 public $product_desc;
4101 public $product_tobatch;
4107 public $product_barcode;
4109 public $localtax1_tx;
4110 public $localtax2_tx;
4111 public $localtax1_type;
4112 public $localtax2_type;
4113 public $total_localtax1;
4114 public $total_localtax2;
4119 public $skip_update_total;
4122 public $fk_multicurrency;
4123 public $multicurrency_code;
4124 public $multicurrency_subprice;
4125 public $multicurrency_total_ht;
4126 public $multicurrency_total_tva;
4127 public $multicurrency_total_ttc;
4148 $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,';
4149 $sql .=
' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
4150 $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,';
4151 $sql .=
' pd.fk_unit,';
4152 $sql .=
' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,';
4153 $sql .=
' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,';
4154 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
4155 $sql .=
' pd.date_start, pd.date_end, pd.product_type';
4156 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as pd';
4157 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON pd.fk_product = p.rowid';
4158 $sql .=
' WHERE pd.rowid = '.((int) $rowid);
4160 $result = $this->db->query($sql);
4162 $objp = $this->db->fetch_object($result);
4165 $this->
id = $objp->rowid;
4166 $this->
rowid = $objp->rowid;
4167 $this->fk_propal = $objp->fk_propal;
4168 $this->fk_parent_line = $objp->fk_parent_line;
4169 $this->label = $objp->custom_label;
4170 $this->desc = $objp->description;
4171 $this->qty = $objp->qty;
4172 $this->
price = $objp->price;
4173 $this->subprice = $objp->subprice;
4174 $this->vat_src_code = $objp->vat_src_code;
4175 $this->tva_tx = $objp->tva_tx;
4176 $this->remise = $objp->remise;
4177 $this->remise_percent = $objp->remise_percent;
4178 $this->fk_remise_except = $objp->fk_remise_except;
4179 $this->fk_product = $objp->fk_product;
4180 $this->info_bits = $objp->info_bits;
4182 $this->total_ht = $objp->total_ht;
4183 $this->total_tva = $objp->total_tva;
4184 $this->total_ttc = $objp->total_ttc;
4186 $this->fk_fournprice = $objp->fk_fournprice;
4188 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
4189 $this->pa_ht = $marginInfos[0];
4190 $this->marge_tx = $marginInfos[1];
4191 $this->marque_tx = $marginInfos[2];
4193 $this->special_code = $objp->special_code;
4194 $this->product_type = $objp->product_type;
4195 $this->rang = $objp->rang;
4197 $this->
ref = $objp->product_ref;
4198 $this->product_ref = $objp->product_ref;
4199 $this->libelle = $objp->product_label;
4200 $this->product_label = $objp->product_label;
4201 $this->product_desc = $objp->product_desc;
4202 $this->fk_unit = $objp->fk_unit;
4204 $this->date_start = $this->db->jdate($objp->date_start);
4205 $this->date_end = $this->db->jdate($objp->date_end);
4208 $this->fk_multicurrency = $objp->fk_multicurrency;
4209 $this->multicurrency_code = $objp->multicurrency_code;
4210 $this->multicurrency_subprice = $objp->multicurrency_subprice;
4211 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
4212 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
4213 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
4217 $this->db->free($result);
4236 global $conf, $user;
4240 dol_syslog(get_class($this).
"::insert rang=".$this->rang);
4242 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4243 $this->pa_ht = (float) $this->pa_ht;
4246 if (empty($this->tva_tx)) {
4249 if (empty($this->localtax1_tx)) {
4250 $this->localtax1_tx = 0;
4252 if (empty($this->localtax2_tx)) {
4253 $this->localtax2_tx = 0;
4255 if (empty($this->localtax1_type)) {
4256 $this->localtax1_type = 0;
4258 if (empty($this->localtax2_type)) {
4259 $this->localtax2_type = 0;
4261 if (empty($this->total_localtax1)) {
4262 $this->total_localtax1 = 0;
4264 if (empty($this->total_localtax2)) {
4265 $this->total_localtax2 = 0;
4267 if (empty($this->rang)) {
4270 if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) {
4271 $this->remise_percent = 0;
4273 if (empty($this->info_bits)) {
4274 $this->info_bits = 0;
4276 if (empty($this->special_code)) {
4277 $this->special_code = 0;
4279 if (empty($this->fk_parent_line)) {
4280 $this->fk_parent_line = 0;
4282 if (empty($this->fk_fournprice)) {
4283 $this->fk_fournprice = 0;
4285 if (!is_numeric($this->qty)) {
4288 if (empty($this->multicurrency_subprice)) {
4289 $this->multicurrency_subprice = 0;
4291 if (empty($this->multicurrency_total_ht)) {
4292 $this->multicurrency_total_ht = 0;
4294 if (empty($this->multicurrency_total_tva)) {
4295 $this->multicurrency_total_tva = 0;
4297 if (empty($this->multicurrency_total_ttc)) {
4298 $this->multicurrency_total_ttc = 0;
4302 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4303 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4306 $this->pa_ht = $result;
4311 if ($this->product_type < 0) {
4318 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'propaldet';
4319 $sql .=
' (fk_propal, fk_parent_line, label, description, fk_product, product_type,';
4320 $sql .=
' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
4321 $sql .=
' subprice, remise_percent, ';
4322 $sql .=
' info_bits, ';
4323 $sql .=
' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,';
4324 $sql .=
' fk_unit,';
4325 $sql .=
' date_start, date_end';
4326 $sql .=
', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)';
4327 $sql .=
" VALUES (".$this->fk_propal.
",";
4328 $sql .=
" ".($this->fk_parent_line > 0 ?
"'".$this->db->escape($this->fk_parent_line).
"'" :
"null").
",";
4329 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
4330 $sql .=
" '".$this->db->escape($this->desc).
"',";
4331 $sql .=
" ".($this->fk_product ?
"'".$this->db->escape($this->fk_product).
"'" :
"null").
",";
4332 $sql .=
" '".$this->db->escape($this->product_type).
"',";
4333 $sql .=
" ".($this->fk_remise_except ?
"'".$this->db->escape($this->fk_remise_except).
"'" :
"null").
",";
4334 $sql .=
" ".price2num($this->qty,
'MS').
",";
4335 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
4336 $sql .=
" ".price2num($this->tva_tx).
",";
4337 $sql .=
" ".price2num($this->localtax1_tx).
",";
4338 $sql .=
" ".price2num($this->localtax2_tx).
",";
4339 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
4340 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
4341 $sql .=
" ".(price2num($this->subprice) !==
'' ?
price2num($this->subprice,
'MU') :
"null").
",";
4342 $sql .=
" ".price2num($this->remise_percent, 3).
",";
4343 $sql .=
" ".(isset($this->info_bits) ? ((int) $this->info_bits) :
"null").
",";
4344 $sql .=
" ".price2num($this->total_ht,
'MT').
",";
4345 $sql .=
" ".price2num($this->total_tva,
'MT').
",";
4346 $sql .=
" ".price2num($this->total_localtax1,
'MT').
",";
4347 $sql .=
" ".price2num($this->total_localtax2,
'MT').
",";
4348 $sql .=
" ".price2num($this->total_ttc,
'MT').
",";
4349 $sql .=
" ".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null").
",";
4350 $sql .=
" ".(isset($this->pa_ht) ?
"'".price2num($this->pa_ht).
"'" :
"null").
",";
4351 $sql .=
' '.((int) $this->special_code).
',';
4352 $sql .=
' '.((int) $this->rang).
',';
4353 $sql .=
' '.(empty($this->fk_unit) ?
'NULL' : ((int) $this->fk_unit)).
',';
4354 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
',';
4355 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4356 $sql .=
", ".($this->fk_multicurrency > 0 ? ((int) $this->fk_multicurrency) :
'null');
4357 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
4358 $sql .=
", ".price2num($this->multicurrency_subprice,
'CU');
4359 $sql .=
", ".price2num($this->multicurrency_total_ht,
'CT');
4360 $sql .=
", ".price2num($this->multicurrency_total_tva,
'CT');
4361 $sql .=
", ".price2num($this->multicurrency_total_ttc,
'CT');
4364 dol_syslog(get_class($this).
'::insert', LOG_DEBUG);
4365 $resql = $this->db->query($sql);
4367 $this->
rowid = $this->db->last_insert_id(MAIN_DB_PREFIX.
'propaldet');
4370 $this->
id = $this->rowid;
4377 if (!$error && !$notrigger) {
4379 $result = $this->
call_trigger(
'LINEPROPAL_INSERT', $user);
4381 $this->db->rollback();
4388 $this->db->commit();
4392 foreach ($this->errors as $errmsg) {
4393 dol_syslog(get_class($this).
"::insert ".$errmsg, LOG_ERR);
4394 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4396 $this->db->rollback();
4399 $this->error = $this->db->error().
" sql=".$sql;
4400 $this->db->rollback();
4412 public function delete(
User $user, $notrigger = 0)
4421 $result = $this->
call_trigger(
'LINEPROPAL_DELETE', $user);
4429 $sql =
"DELETE FROM " . MAIN_DB_PREFIX .
"propaldet WHERE rowid = " . ((int) $this->
rowid);
4430 dol_syslog(
"PropaleLigne::delete", LOG_DEBUG);
4431 if ($this->db->query($sql)) {
4434 $this->
id = $this->rowid;
4438 dol_syslog(get_class($this) .
"::delete error -4 " . $this->error, LOG_ERR);
4442 $this->error = $this->db->error() .
" sql=" . $sql;
4448 $this->db->rollback();
4451 $this->db->commit();
4464 global $conf, $user;
4468 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4469 $this->pa_ht = (float) $this->pa_ht;
4471 if (empty($this->
id) && !empty($this->
rowid)) {
4472 $this->
id = $this->rowid;
4476 if (empty($this->tva_tx)) {
4479 if (empty($this->localtax1_tx)) {
4480 $this->localtax1_tx = 0;
4482 if (empty($this->localtax2_tx)) {
4483 $this->localtax2_tx = 0;
4485 if (empty($this->total_localtax1)) {
4486 $this->total_localtax1 = 0;
4488 if (empty($this->total_localtax2)) {
4489 $this->total_localtax2 = 0;
4491 if (empty($this->localtax1_type)) {
4492 $this->localtax1_type = 0;
4494 if (empty($this->localtax2_type)) {
4495 $this->localtax2_type = 0;
4497 if (empty($this->marque_tx)) {
4498 $this->marque_tx = 0;
4500 if (empty($this->marge_tx)) {
4501 $this->marge_tx = 0;
4503 if (empty($this->
price)) {
4506 if (empty($this->remise_percent)) {
4507 $this->remise_percent = 0;
4509 if (empty($this->info_bits)) {
4510 $this->info_bits = 0;
4512 if (empty($this->special_code)) {
4513 $this->special_code = 0;
4515 if (empty($this->fk_parent_line)) {
4516 $this->fk_parent_line = 0;
4518 if (empty($this->fk_fournprice)) {
4519 $this->fk_fournprice = 0;
4521 if (empty($this->subprice)) {
4522 $this->subprice = 0;
4526 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4527 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4530 $this->pa_ht = $result;
4537 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4538 $sql .=
" description='".$this->db->escape($this->desc).
"'";
4539 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
4540 $sql .=
", product_type=".$this->product_type;
4541 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"'";
4542 $sql .=
", tva_tx='".price2num($this->tva_tx).
"'";
4543 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
4544 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
4545 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
4546 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
4547 $sql .=
", qty='".price2num($this->qty).
"'";
4548 $sql .=
", subprice=".price2num($this->subprice);
4549 $sql .=
", remise_percent=".price2num($this->remise_percent);
4551 $sql .=
", remise=".(float)
price2num($this->remise);
4552 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
4553 if (empty($this->skip_update_total)) {
4554 $sql .=
", total_ht=".price2num($this->total_ht);
4555 $sql .=
", total_tva=".price2num($this->total_tva);
4556 $sql .=
", total_ttc=".price2num($this->total_ttc);
4557 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
4558 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
4560 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
4561 $sql .=
", buy_price_ht=".price2num($this->pa_ht);
4562 $sql .=
", special_code=".((int) $this->special_code);
4563 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? (int) $this->fk_parent_line :
"null");
4564 if (!empty($this->rang)) {
4565 $sql .=
", rang=".((int) $this->rang);
4567 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
4568 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4569 $sql .=
", fk_unit=".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
4572 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
4573 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
4574 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
4575 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
4577 $sql .=
" WHERE rowid = ".((int) $this->
id);
4579 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
4580 $resql = $this->db->query($sql);
4589 if (!$error && !$notrigger) {
4591 $result = $this->
call_trigger(
'LINEPROPAL_MODIFY', $user);
4593 $this->db->rollback();
4600 $this->db->commit();
4604 foreach ($this->errors as $errmsg) {
4605 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
4606 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
4608 $this->db->rollback();
4611 $this->error = $this->db->error();
4612 $this->db->rollback();
4630 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4631 $sql .=
" total_ht=".price2num($this->total_ht,
'MT');
4632 $sql .=
",total_tva=".price2num($this->total_tva,
'MT');
4633 $sql .=
",total_ttc=".price2num($this->total_ttc,
'MT');
4634 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
4636 dol_syslog(
"PropaleLigne::update_total", LOG_DEBUG);
4638 $resql = $this->db->query($sql);
4640 $this->db->commit();
4643 $this->error = $this->db->error();
4644 $this->db->rollback();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
line_order($renum=false, $rowidorder='ASC', $fk_parent_line=true)
Save a new position (field rang) for details lines.
deleteEcmFiles($mode=0)
Delete related files of object in database.
update_price($exclspec=0, $roundingadjust='auto', $nodatabaseupdate=0, $seller=null)
Update total_ht, total_ttc, total_vat, total_localtax1, total_localtax2 for an object (sum of lines).
add_object_linked($origin=null, $origin_id=null, $f_user=null, $notrigger=0)
Add an object link into llx_element_element.
defineBuyPrice($unitPrice=0.0, $discountPercent=0.0, $fk_product=0)
Get buy price to use for margin calculation.
commonGenerateDocument($modelspath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams=null)
Common function for all objects extending CommonObject for generating documents.
fetch_thirdparty($force_thirdparty_id=0)
Load the third party of object, from id $this->socid or $this->fk_soc, into this->thirdparty.
deleteObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $rowid=0, $f_user=null, $notrigger=0)
Delete all links between an object $this.
setErrorsFromObject($object)
setErrorsFromObject
static isExistingObject($element, $id, $ref='', $ref_ext='')
Check if an object id or ref exists If you don't need or want to instantiate the object and just need...
updateRangOfLine($rowid, $rang)
Update position of line (rang)
fetch_project()
Load the project with id $this->fk_project into this->project.
deleteExtraFields()
Delete all extra fields values for the current object.
fetchObjectLinked($sourceid=null, $sourcetype='', $targetid=null, $targettype='', $clause='OR', $alsosametype=1, $orderby='sourcetype', $loadalsoobjects=1)
Fetch array of objects linked to current object (object of enabled modules only).
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
static commonReplaceProduct(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a product id with another one.
line_max($fk_parent_line=0)
Get max value used for position of line (rang)
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
delete_linked_contact($source='', $code='')
Delete all links between an object $this and all its contacts in llx_element_contact.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Parent class for class inheritance lines of business objects This class is useless for the moment so ...
Class to manage absolute discounts.
Class to manage Dolibarr database access.
static getIdFromCode($dbs, $code)
Get id of currency from code.
static getIdAndTxFromCode($dbs, $code, $date_document='')
Get id and rate of currency from code.
File of class to manage predefined price products or services by customer.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
Class to manage projects.
Class to manage proposals.
getTooltipContentArray($params)
getTooltipContentArray
const STATUS_DRAFT
Draft status.
set_date($user, $date, $notrigger=0)
Define proposal date.
const STATUS_SIGNED
Signed quote.
getNomUrl($withpicto=0, $option='', $get_params='', $notooltip=0, $save_lastsearch_value=-1, $addlinktonotes=-1)
Return 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.
classifyBilled(User $user, $notrigger=0, $note='')
Classify the proposal to status Billed.
getLinesArray($sqlforgedfilters='')
Retrieve an array of proposal lines.
fetch($rowid, $ref='', $ref_ext='', $forceentity=0)
Load a proposal from database.
set_availability($user, $id, $notrigger=0)
Set delivery.
fetch_lines($only_product=0, $loadalsotranslation=0, $sqlforgedfilters='')
Load array lines.
updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=0, $pa_ht=0, $label='', $type=0, $date_start='', $date_end='', $array_options=array(), $fk_unit=null, $pu_ht_devise=0, $notrigger=0, $rang=0)
Update a proposal line.
update(User $user, $notrigger=0)
Update database.
demand_reason($demand_reason_id, $notrigger=0)
Change source demand.
info($id)
Object Proposal Information.
const STATUS_BILLED
Billed or processed quote.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
getLibStatut($mode=0)
Return label of status of proposal (draft, validated, ...)
const STATUS_CANCELED
Canceled status.
insert_discount($idremise)
Adding line of fixed discount in the proposal in DB.
getNextNumRef($soc)
Returns the reference to the following non used Proposal used depending on the active numbering modul...
LibStatut($status, $mode=1)
Return label of a status (draft, validated, ...)
valid($user, $notrigger=0)
Set status to validated.
static replaceProduct(DoliDB $db, $origin_id, $dest_id)
Function used to replace a product id with another one.
set_ref_client($user, $ref_client, $notrigger=0)
Set customer reference number.
setDraft($user, $notrigger=0)
Set draft status.
set_echeance($user, $date_end_validity, $notrigger=0)
Define end validity date.
set_demand_reason($user, $id, $notrigger=0)
Set source of demand.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
create($user, $notrigger=0)
Create commercial proposal into database this->ref can be set or empty.
liste_array($shortlist=0, $draft=0, $notcurrentuser=0, $socid=0, $limit=0, $offset=0, $sortfield='p.datep', $sortorder='DESC')
Return list of proposal (eventually filtered on user) into an array.
add_product($idproduct, $qty, $remise_percent=0)
Add line into array ->lines $this->thirdparty should be loaded.
initAsSpecimen()
Initialise an instance with random values.
closeProposal($user, $status, $note='', $notrigger=0)
Close/set the commercial proposal to status signed or refused (fill also date signature)
reopen($user, $status, $note='', $notrigger=0)
Reopen the commercial proposal.
deleteLine($lineid, $id=0)
Delete detail line.
__construct($db, $socid=0, $propalid=0)
Constructor.
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
setCancel(User $user)
Cancel the proposal.
addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=0, $pa_ht=0, $label='', $date_start='', $date_end='', $array_options=array(), $fk_unit=null, $origin='', $origin_id=0, $pu_ht_devise=0, $fk_remise_except=0, $noupdateafterinsertline=0)
Add a proposal line into database (linked to product/service or not) The parameters are already suppo...
getInvoiceArrayList()
Returns an array with the numbers of related invoices.
set_date_livraison($user, $delivery_date, $notrigger=0)
Set delivery date.
const STATUS_VALIDATED
Validated status.
loadStateBoard()
Load the indicators this->nb for the state board.
createFromClone(User $user, $socid=0, $forceentity=null, $update_prices=false, $update_desc=false)
Load an object from its id and create a new one in database.
Class to manage commercial proposal lines.
__construct($db)
Class line Constructor.
update($notrigger=0)
Update propal line object into DB.
fetch($rowid)
Retrieve the propal line object.
insert($notrigger=0)
Insert object line propal in database.
update_total()
Update DB line fields total_xxx Used by migration.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
trait CommonIncoterm
Superclass for incoterm classes.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
dol_delete_preview($object)
Delete all preview files linked to object instance.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisid=0)
Get type and rate of localtaxes for a particular vat rate/country of a thirdparty.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
get_default_npr(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that returns whether VAT must be recoverable collected VAT (e.g.: VAT NPR in France)
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
getMarginInfos($pv_ht, $remise_percent, $tva_tx, $localtax1_tx, $localtax2_tx, $fk_pa, $pa_ht)
Return an array with margins information of a line.
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.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e e e e e statut
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall TAKEPOS_SHOW_SUBPRICE right right right takeposterminal SELECT e rowid