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;
161 public $date_validation;
166 public $date_signature;
171 public $user_signature;
187 public $delivery_date;
193 public $fin_validite;
198 public $user_author_id;
217 public $cond_reglement_code;
218 public $cond_reglement;
219 public $cond_reglement_doc;
221 public $mode_reglement_code;
222 public $mode_reglement;
224 public $deposit_percent;
232 public $address_type;
238 public $availability_id;
245 public $fk_availability;
250 public $availability_code;
255 public $availability;
257 public $duree_validite;
262 public $demand_reason_id;
267 public $demand_reason_code;
272 public $demand_reason;
277 public $warehouse_id;
282 public $lines = array();
289 public $labelStatus = array();
290 public $labelStatusShort = array();
321 public $fields = array(
322 'rowid' => array(
'type' =>
'integer',
'label' =>
'TechnicalID',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 10),
323 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'default' =>
'1',
'enabled' => 1,
'visible' => -2,
'notnull' => 1,
'position' => 15,
'index' => 1),
324 'ref' => array(
'type' =>
'varchar(30)',
'label' =>
'Ref',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'showoncombobox' => 1,
'position' => 20),
325 'ref_client' => array(
'type' =>
'varchar(255)',
'label' =>
'RefCustomer',
'enabled' => 1,
'visible' => -1,
'position' => 22),
326 'ref_ext' => array(
'type' =>
'varchar(255)',
'label' =>
'RefExt',
'enabled' => 1,
'visible' => 0,
'position' => 40),
327 'fk_soc' => array(
'type' =>
'integer:Societe:societe/class/societe.class.php',
'label' =>
'ThirdParty',
'enabled' =>
'isModEnabled("societe")',
'visible' => -1,
'position' => 23),
328 '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),
329 'tms' => array(
'type' =>
'timestamp',
'label' =>
'DateModification',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 25),
330 'datec' => array(
'type' =>
'datetime',
'label' =>
'DateCreation',
'enabled' => 1,
'visible' => -1,
'position' => 55),
331 'datep' => array(
'type' =>
'date',
'label' =>
'Date',
'enabled' => 1,
'visible' => -1,
'position' => 60),
332 'fin_validite' => array(
'type' =>
'datetime',
'label' =>
'DateEnd',
'enabled' => 1,
'visible' => -1,
'position' => 65),
333 'date_valid' => array(
'type' =>
'datetime',
'label' =>
'DateValidation',
'enabled' => 1,
'visible' => -1,
'position' => 70),
334 'date_cloture' => array(
'type' =>
'datetime',
'label' =>
'DateClosing',
'enabled' => 1,
'visible' => -1,
'position' => 75),
335 'fk_user_author' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user author',
'enabled' => 1,
'visible' => -1,
'position' => 80),
336 'fk_user_modif' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserModif',
'enabled' => 1,
'visible' => -2,
'notnull' => -1,
'position' => 85),
337 'fk_user_valid' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'UserValidation',
'enabled' => 1,
'visible' => -1,
'position' => 90),
338 'fk_user_cloture' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'Fk user cloture',
'enabled' => 1,
'visible' => -1,
'position' => 95),
339 'price' => array(
'type' =>
'double',
'label' =>
'Price',
'enabled' => 1,
'visible' => -1,
'position' => 105),
340 'total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalHT',
'enabled' => 1,
'visible' => -1,
'position' => 125,
'isameasure' => 1),
341 'total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'VAT',
'enabled' => 1,
'visible' => -1,
'position' => 130,
'isameasure' => 1),
342 'localtax1' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax1',
'enabled' => 1,
'visible' => -1,
'position' => 135,
'isameasure' => 1),
343 'localtax2' => array(
'type' =>
'double(24,8)',
'label' =>
'LocalTax2',
'enabled' => 1,
'visible' => -1,
'position' => 140,
'isameasure' => 1),
344 'total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'TotalTTC',
'enabled' => 1,
'visible' => -1,
'position' => 145,
'isameasure' => 1),
345 'fk_account' => array(
'type' =>
'integer',
'label' =>
'BankAccount',
'enabled' =>
'isModEnabled("bank")',
'visible' => -1,
'position' => 150),
346 'fk_currency' => array(
'type' =>
'varchar(3)',
'label' =>
'Currency',
'enabled' => 1,
'visible' => -1,
'position' => 155),
347 'fk_cond_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentTerm',
'enabled' => 1,
'visible' => -1,
'position' => 160),
348 'deposit_percent' => array(
'type' =>
'varchar(63)',
'label' =>
'DepositPercent',
'enabled' => 1,
'visible' => -1,
'position' => 161),
349 'fk_mode_reglement' => array(
'type' =>
'integer',
'label' =>
'PaymentMode',
'enabled' => 1,
'visible' => -1,
'position' => 165),
350 'note_private' => array(
'type' =>
'html',
'label' =>
'NotePrivate',
'enabled' => 1,
'visible' => 0,
'position' => 170),
351 'note_public' => array(
'type' =>
'html',
'label' =>
'NotePublic',
'enabled' => 1,
'visible' => 0,
'position' => 175),
352 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'PDFTemplate',
'enabled' => 1,
'visible' => 0,
'position' => 180),
353 'date_livraison' => array(
'type' =>
'date',
'label' =>
'DateDeliveryPlanned',
'enabled' => 1,
'visible' => -1,
'position' => 185),
354 'fk_shipping_method' => array(
'type' =>
'integer',
'label' =>
'ShippingMethod',
'enabled' => 1,
'visible' => -1,
'position' => 190),
355 'fk_warehouse' => array(
'type' =>
'integer:Entrepot:product/stock/class/entrepot.class.php',
'label' =>
'Fk warehouse',
'enabled' =>
'isModEnabled("stock")',
'visible' => -1,
'position' => 191),
356 'fk_availability' => array(
'type' =>
'integer',
'label' =>
'Availability',
'enabled' => 1,
'visible' => -1,
'position' => 195),
357 'fk_delivery_address' => array(
'type' =>
'integer',
'label' =>
'DeliveryAddress',
'enabled' => 1,
'visible' => 0,
'position' => 200),
358 'fk_input_reason' => array(
'type' =>
'integer',
'label' =>
'InputReason',
'enabled' => 1,
'visible' => -1,
'position' => 205),
359 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => -1,
'position' => 215),
360 'fk_incoterms' => array(
'type' =>
'integer',
'label' =>
'IncotermCode',
'enabled' =>
'$conf->incoterm->enabled',
'visible' => -1,
'position' => 220),
361 'location_incoterms' => array(
'type' =>
'varchar(255)',
'label' =>
'IncotermLabel',
'enabled' =>
'$conf->incoterm->enabled',
'visible' => -1,
'position' => 225),
362 'fk_multicurrency' => array(
'type' =>
'integer',
'label' =>
'MulticurrencyID',
'enabled' => 1,
'visible' => -1,
'position' => 230),
363 'multicurrency_code' => array(
'type' =>
'varchar(255)',
'label' =>
'MulticurrencyCurrency',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 235),
364 'multicurrency_tx' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyRate',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 240,
'isameasure' => 1),
365 'multicurrency_total_ht' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountHT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 245,
'isameasure' => 1),
366 'multicurrency_total_tva' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountVAT',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 250,
'isameasure' => 1),
367 'multicurrency_total_ttc' => array(
'type' =>
'double(24,8)',
'label' =>
'MulticurrencyAmountTTC',
'enabled' =>
'isModEnabled("multicurrency")',
'visible' => -1,
'position' => 255,
'isameasure' => 1),
368 'last_main_doc' => array(
'type' =>
'varchar(255)',
'label' =>
'LastMainDoc',
'enabled' => 1,
'visible' => -1,
'position' => 260),
369 'fk_statut' => array(
'type' =>
'smallint(6)',
'label' =>
'Status',
'enabled' => 1,
'visible' => -1,
'notnull' => 1,
'position' => 500),
370 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -2,
'position' => 900),
411 $this->ismultientitymanaged = 1;
412 $this->socid = $socid;
413 $this->
id = $propalid;
415 $this->duree_validite =
getDolGlobalInt(
'PROPALE_VALIDITY_DURATION', 0);
431 public function add_product($idproduct, $qty, $remise_percent = 0)
434 global $conf, $mysoc;
440 dol_syslog(get_class($this).
"::add_product $idproduct, $qty, $remise_percent");
441 if ($idproduct > 0) {
442 $prod =
new Product($this->db);
443 $prod->fetch($idproduct);
445 $productdesc = $prod->description;
449 if (empty($tva_tx)) {
454 $localtax1_tx =
get_localtax($tva_tx, 1, $mysoc, $this->thirdparty, $tva_npr);
455 $localtax2_tx =
get_localtax($tva_tx, 2, $mysoc, $this->thirdparty, $tva_npr);
458 if ($conf->global->PRODUIT_MULTIPRICES && $this->thirdparty->price_level) {
459 $price = $prod->multiprices[$this->thirdparty->price_level];
466 $line->fk_product = $idproduct;
467 $line->desc = $productdesc;
470 $line->remise_percent = $remise_percent;
471 $line->vat_src_code = $vat_src_code;
472 $line->tva_tx = $tva_tx;
473 $line->fk_unit = $prod->fk_unit;
475 $line->info_bits = 1;
478 $this->lines[] = $line;
496 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
497 include_once DOL_DOCUMENT_ROOT.
'/core/class/discount.class.php';
502 $result = $remise->fetch($idremise);
505 if ($remise->fk_facture) {
506 $this->error = $langs->trans(
"ErrorDiscountAlreadyUsed");
507 $this->db->rollback();
513 $line->context = $this->context;
515 $line->fk_propal = $this->id;
516 $line->fk_remise_except = $remise->id;
517 $line->desc = $remise->description;
518 $line->vat_src_code = $remise->vat_src_code;
519 $line->tva_tx = $remise->tva_tx;
520 $line->subprice = -$remise->amount_ht;
521 $line->fk_product = 0;
523 $line->remise_percent = 0;
525 $line->info_bits = 2;
528 $line->price = -$remise->amount_ht;
530 $line->total_ht = -$remise->amount_ht;
531 $line->total_tva = -$remise->amount_tva;
532 $line->total_ttc = -$remise->amount_ttc;
534 $result = $line->insert();
541 $this->db->rollback();
545 $this->error = $line->error;
546 $this->errors = $line->errors;
547 $this->db->rollback();
551 $this->db->rollback();
593 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)
595 global $mysoc, $conf, $langs;
597 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);
599 if ($this->
statut == self::STATUS_DRAFT) {
600 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
603 if (empty($remise_percent)) {
609 if (empty($info_bits)) {
615 if (empty($fk_parent_line) || $fk_parent_line < 0) {
619 $remise_percent =
price2num($remise_percent);
622 $pu_ht_devise =
price2num($pu_ht_devise);
624 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
630 if ($price_base_type ==
'HT') {
641 if ($date_start && $date_end && $date_start > $date_end) {
642 $langs->load(
"errors");
643 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
649 $product_type = $type;
650 if (!empty($fk_product) && $fk_product > 0) {
651 $product =
new Product($this->db);
652 $result = $product->fetch($fk_product);
653 $product_type = $product->type;
655 if (
getDolGlobalString(
'STOCK_MUST_BE_ENOUGH_FOR_PROPOSAL') && $product_type == 0 && $product->stock_reel < $qty) {
656 $langs->load(
"errors");
657 $this->error = $langs->trans(
'ErrorStockIsNotEnoughToAddProductOnProposal', $product->ref);
658 $this->db->rollback();
673 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
674 $vat_src_code = $reg[1];
675 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
678 $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);
680 $total_ht = $tabprice[0];
681 $total_tva = $tabprice[1];
682 $total_ttc = $tabprice[2];
683 $total_localtax1 = $tabprice[9];
684 $total_localtax2 = $tabprice[10];
685 $pu_ht = $tabprice[3];
686 $pu_tva = $tabprice[4];
687 $pu_ttc = $tabprice[5];
690 $multicurrency_total_ht = $tabprice[16];
691 $multicurrency_total_tva = $tabprice[17];
692 $multicurrency_total_ttc = $tabprice[18];
693 $pu_ht_devise = $tabprice[19];
697 if ($ranktouse == -1) {
698 $rangmax = $this->
line_max($fk_parent_line);
699 $ranktouse = $rangmax + 1;
706 if ((
float) $remise_percent > 0) {
707 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
708 $price = (float) $pu - $remise;
714 $this->line->context = $this->context;
716 $this->line->fk_propal = $this->id;
717 $this->line->label = $label;
718 $this->line->desc = $desc;
719 $this->line->qty = $qty;
721 $this->line->vat_src_code = $vat_src_code;
722 $this->line->tva_tx = $txtva;
723 $this->line->localtax1_tx = ($total_localtax1 ? $localtaxes_type[1] : 0);
724 $this->line->localtax2_tx = ($total_localtax2 ? $localtaxes_type[3] : 0);
725 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
726 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
727 $this->line->fk_product = $fk_product;
728 $this->line->product_type = $type;
729 $this->line->fk_remise_except = $fk_remise_except;
730 $this->line->remise_percent = $remise_percent;
731 $this->line->subprice = $pu_ht;
732 $this->line->rang = $ranktouse;
733 $this->line->info_bits = $info_bits;
734 $this->line->total_ht = $total_ht;
735 $this->line->total_tva = $total_tva;
736 $this->line->total_localtax1 = $total_localtax1;
737 $this->line->total_localtax2 = $total_localtax2;
738 $this->line->total_ttc = $total_ttc;
739 $this->line->special_code = $special_code;
740 $this->line->fk_parent_line = $fk_parent_line;
741 $this->line->fk_unit = $fk_unit;
743 $this->line->date_start = $date_start;
744 $this->line->date_end = $date_end;
746 $this->line->fk_fournprice = $fk_fournprice;
747 $this->line->pa_ht = $pa_ht;
749 $this->line->origin_id = $origin_id;
750 $this->line->origin = $origin;
753 $this->line->fk_multicurrency = $this->fk_multicurrency;
754 $this->line->multicurrency_code = $this->multicurrency_code;
755 $this->line->multicurrency_subprice = $pu_ht_devise;
756 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
757 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
758 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
761 if (empty($qty) && empty($special_code)) {
762 $this->line->special_code = 3;
766 $this->line->price =
$price;
768 if (is_array($array_options) && count($array_options) > 0) {
769 $this->line->array_options = $array_options;
772 $result = $this->line->insert();
775 if (!empty($fk_parent_line)) {
777 } elseif ($ranktouse > 0 && $ranktouse <= count($this->lines)) {
778 $linecount = count($this->lines);
779 for ($ii = $ranktouse; $ii <= $linecount; $ii++) {
785 if (empty($noupdateafterinsertline)) {
791 return $this->line->id;
793 $this->error = $this->db->error();
794 $this->db->rollback();
798 $this->error = $this->line->error;
799 $this->errors = $this->line->errors;
800 $this->db->rollback();
804 dol_syslog(get_class($this).
"::addline status of proposal must be Draft to allow use of ->addline()", LOG_ERR);
839 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)
841 global $mysoc, $langs;
843 dol_syslog(get_class($this).
"::updateLine rowid=$rowid, pu=$pu, qty=$qty, remise_percent=$remise_percent,
844 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");
845 include_once DOL_DOCUMENT_ROOT.
'/core/lib/price.lib.php';
848 $remise_percent =
price2num($remise_percent);
851 $pu_ht_devise =
price2num($pu_ht_devise);
852 if (!preg_match(
'/\((.*)\)/', (
string) $txtva)) {
858 if (empty($qty) && empty($special_code)) {
861 if (!empty($qty) && $special_code == 3) {
868 if ($date_start && $date_end && $date_start > $date_end) {
869 $langs->load(
"errors");
870 $this->error = $langs->trans(
'ErrorStartDateGreaterEnd');
874 if ($this->
status == self::STATUS_DRAFT) {
887 if (preg_match(
'/\((.*)\)/', $txtva, $reg)) {
888 $vat_src_code = $reg[1];
889 $txtva = preg_replace(
'/\s*\(.*\)/',
'', $txtva);
894 $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);
895 $total_ht = $tabprice[0];
896 $total_tva = $tabprice[1];
897 $total_ttc = $tabprice[2];
898 $total_localtax1 = $tabprice[9];
899 $total_localtax2 = $tabprice[10];
900 $pu_ht = $tabprice[3];
901 $pu_tva = $tabprice[4];
902 $pu_ttc = $tabprice[5];
905 $multicurrency_total_ht = $tabprice[16];
906 $multicurrency_total_tva = $tabprice[17];
907 $multicurrency_total_ttc = $tabprice[18];
908 $pu_ht_devise = $tabprice[19];
913 if ((
float) $remise_percent > 0) {
914 $remise = round(((
float) $pu * (
float) $remise_percent / 100), 2);
915 $price = (float) $pu - $remise;
920 $line->fetch($rowid);
922 $staticline = clone $line;
924 $line->oldline = $staticline;
926 $this->line->context = $this->context;
927 $this->line->rang = $rang;
930 if (!empty($fk_parent_line) && !empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line) {
931 $rangmax = $this->
line_max($fk_parent_line);
932 $this->line->rang = $rangmax + 1;
935 $this->line->id = $rowid;
936 $this->line->label = $label;
937 $this->line->desc = $desc;
938 $this->line->qty = $qty;
939 $this->line->product_type = $type;
940 $this->line->vat_src_code = $vat_src_code;
941 $this->line->tva_tx = $txtva;
942 $this->line->localtax1_tx = $txlocaltax1;
943 $this->line->localtax2_tx = $txlocaltax2;
944 $this->line->localtax1_type = empty($localtaxes_type[0]) ?
'' : $localtaxes_type[0];
945 $this->line->localtax2_type = empty($localtaxes_type[2]) ?
'' : $localtaxes_type[2];
946 $this->line->remise_percent = $remise_percent;
947 $this->line->subprice = $pu_ht;
948 $this->line->info_bits = $info_bits;
950 $this->line->total_ht = $total_ht;
951 $this->line->total_tva = $total_tva;
952 $this->line->total_localtax1 = $total_localtax1;
953 $this->line->total_localtax2 = $total_localtax2;
954 $this->line->total_ttc = $total_ttc;
955 $this->line->special_code = $special_code;
956 $this->line->fk_parent_line = $fk_parent_line;
957 $this->line->skip_update_total = $skip_update_total;
958 $this->line->fk_unit = $fk_unit;
960 $this->line->fk_fournprice = $fk_fournprice;
961 $this->line->pa_ht = $pa_ht;
963 $this->line->date_start = $date_start;
964 $this->line->date_end = $date_end;
966 if (is_array($array_options) && count($array_options) > 0) {
968 foreach ($array_options as $key => $value) {
969 $this->line->array_options[$key] = $array_options[$key];
974 $this->line->multicurrency_subprice = $pu_ht_devise;
975 $this->line->multicurrency_total_ht = $multicurrency_total_ht;
976 $this->line->multicurrency_total_tva = $multicurrency_total_tva;
977 $this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
979 $result = $this->line->update($notrigger);
982 if (!empty($fk_parent_line)) {
995 $this->error = $this->line->error;
996 $this->errors = $this->line->errors;
997 $this->db->rollback();
1001 dol_syslog(get_class($this).
"::updateline Erreur -2 Propal en mode incompatible pour cette action");
1018 if ($this->
status == self::STATUS_DRAFT) {
1023 $line->context = $this->context;
1026 $line->fetch($lineid);
1028 if ($id > 0 && $line->fk_propal != $id) {
1029 $this->error =
'ErrorLineIDDoesNotMatchWithObjectID';
1034 $staticline = clone $line;
1035 $line->oldline = $staticline;
1037 if ($line->delete($user) > 0) {
1040 $this->db->commit();
1043 $this->error = $line->error;
1044 $this->errors = $line->errors;
1045 $this->db->rollback();
1049 $this->error =
'ErrorDeleteLineNotAllowedByObjectStatus';
1063 public function create($user, $notrigger = 0)
1065 global $conf, $hookmanager, $mysoc;
1071 if (empty($this->date)) {
1074 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1075 if (empty($this->availability_id)) {
1076 $this->availability_id = 0;
1078 if (empty($this->demand_reason_id)) {
1079 $this->demand_reason_id = 0;
1083 if (!empty($this->multicurrency_code) && empty($this->multicurrency_tx)) {
1088 if (empty($this->fk_multicurrency)) {
1089 $this->multicurrency_code = $conf->currency;
1090 $this->fk_multicurrency = 0;
1091 $this->multicurrency_tx = 1;
1095 $delivery_date = $this->delivery_date;
1102 $this->error =
"Failed to fetch company";
1103 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1108 if (!empty($this->
ref)) {
1111 $this->error =
'ErrorRefAlreadyExists';
1112 dol_syslog(get_class($this).
"::create ".$this->error, LOG_WARNING);
1113 $this->db->rollback();
1118 if (empty($this->date)) {
1119 $this->error =
"Date of proposal is required";
1120 dol_syslog(get_class($this).
"::create ".$this->error, LOG_ERR);
1128 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"propal (";
1131 $sql .=
", total_tva";
1132 $sql .=
", total_ttc";
1136 $sql .=
", fk_user_author";
1137 $sql .=
", note_private";
1138 $sql .=
", note_public";
1139 $sql .=
", model_pdf";
1140 $sql .=
", fin_validite";
1141 $sql .=
", fk_cond_reglement";
1142 $sql .=
", deposit_percent";
1143 $sql .=
", fk_mode_reglement";
1144 $sql .=
", fk_account";
1145 $sql .=
", ref_client";
1146 $sql .=
", ref_ext";
1147 $sql .=
", date_livraison";
1148 $sql .=
", fk_shipping_method";
1149 $sql .=
", fk_warehouse";
1150 $sql .=
", fk_availability";
1151 $sql .=
", fk_input_reason";
1152 $sql .=
", fk_projet";
1153 $sql .=
", fk_incoterms";
1154 $sql .=
", location_incoterms";
1156 $sql .=
", fk_multicurrency";
1157 $sql .=
", multicurrency_code";
1158 $sql .=
", multicurrency_tx";
1160 $sql .=
" VALUES (";
1161 $sql .= $this->socid;
1165 $sql .=
", '".$this->db->idate($this->date).
"'";
1166 $sql .=
", '".$this->db->idate($now).
"'";
1167 $sql .=
", '(PROV)'";
1168 $sql .=
", ".($user->id > 0 ? ((int) $user->id) :
"NULL");
1169 $sql .=
", '".$this->db->escape($this->note_private).
"'";
1170 $sql .=
", '".$this->db->escape($this->note_public).
"'";
1171 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
1172 $sql .=
", ".($this->fin_validite !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
"NULL");
1173 $sql .=
", ".($this->cond_reglement_id > 0 ? ((int) $this->cond_reglement_id) :
'NULL');
1174 $sql .=
", ".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
'NULL');
1175 $sql .=
", ".($this->mode_reglement_id > 0 ? ((int) $this->mode_reglement_id) :
'NULL');
1176 $sql .=
", ".($this->fk_account > 0 ? ((int) $this->fk_account) :
'NULL');
1177 $sql .=
", '".$this->db->escape($this->ref_client).
"'";
1178 $sql .=
", '".$this->db->escape($this->ref_ext).
"'";
1179 $sql .=
", ".(!
isDolTms($delivery_date) ?
"NULL" :
"'".$this->db->idate($delivery_date).
"'");
1180 $sql .=
", ".($this->shipping_method_id > 0 ? $this->shipping_method_id :
'NULL');
1181 $sql .=
", ".($this->warehouse_id > 0 ? $this->warehouse_id :
'NULL');
1182 $sql .=
", ".$this->availability_id;
1183 $sql .=
", ".$this->demand_reason_id;
1184 $sql .=
", ".($this->fk_project ? $this->fk_project :
"null");
1185 $sql .=
", ".(int) $this->fk_incoterms;
1186 $sql .=
", '".$this->db->escape($this->location_incoterms).
"'";
1187 $sql .=
", ".setEntity($this);
1188 $sql .=
", ".(int) $this->fk_multicurrency;
1189 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
1190 $sql .=
", ".(float) $this->multicurrency_tx;
1193 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1194 $resql = $this->db->query($sql);
1196 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"propal");
1199 $this->
ref =
'(PROV'.$this->id.
')';
1200 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"propal SET ref='".$this->db->escape($this->
ref).
"' WHERE rowid=".((int) $this->
id);
1202 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
1203 $resql = $this->db->query($sql);
1208 if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) {
1209 $this->linked_objects = $this->linkedObjectsIds;
1213 if (!$error && $this->
id && !empty($this->linked_objects) && is_array($this->linked_objects)) {
1214 foreach ($this->linked_objects as $origin => $tmp_origin_id) {
1215 if (is_array($tmp_origin_id)) {
1216 foreach ($tmp_origin_id as $origin_id) {
1219 $this->error = $this->db->lasterror();
1224 $origin_id = $tmp_origin_id;
1227 $this->error = $this->db->lasterror();
1239 $fk_parent_line = 0;
1240 $num = count($this->lines);
1242 for ($i = 0; $i < $num; $i++) {
1243 if (!is_object($this->lines[$i])) {
1245 $line = (object) $this->lines[$i];
1247 $line = $this->lines[$i];
1250 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
1251 $fk_parent_line = 0;
1254 $vatrate = $line->tva_tx;
1255 if ($line->vat_src_code && !preg_match(
'/\(.*\)/', $vatrate)) {
1256 $vatrate .=
' ('.$line->vat_src_code.
')';
1260 $originid = $line->origin_id;
1261 $origintype = $line->origin;
1263 $originid = $line->id;
1264 $origintype = $this->element;
1272 $line->localtax1_tx,
1273 $line->localtax2_tx,
1275 $line->remise_percent,
1279 $line->product_type,
1281 $line->special_code,
1283 $line->fk_fournprice,
1288 $line->array_options,
1299 $this->error = $this->db->error;
1305 $line->id = $result;
1308 if ($result > 0 && $line->product_type == 9) {
1309 $fk_parent_line = $result;
1339 if (!$error && !$notrigger) {
1348 $this->error = $this->db->lasterror();
1353 $this->error = $this->db->lasterror();
1358 $this->db->commit();
1359 dol_syslog(get_class($this).
"::create done id=".$this->
id);
1362 $this->db->rollback();
1366 $this->error = $this->db->lasterror();
1367 $this->db->rollback();
1382 public function createFromClone(
User $user, $socid = 0, $forceentity =
null, $update_prices =
false, $update_desc =
false)
1384 global $conf, $hookmanager, $mysoc;
1393 $object =
new self($this->db);
1400 $objsoc =
new Societe($this->db);
1403 if (!empty($socid) && $socid !=
$object->socid) {
1404 if ($objsoc->fetch($socid) > 0) {
1406 $object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
1407 $object->deposit_percent = (!empty($objsoc->deposit_percent) ? $objsoc->deposit_percent :
null);
1408 $object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
1409 $object->fk_delivery_address = 0;
1432 $objsoc->fetch(
$object->socid);
1436 if ($update_prices ===
true || $update_desc ===
true) {
1437 if ($objsoc->id > 0 && !empty(
$object->lines)) {
1440 require_once DOL_DOCUMENT_ROOT .
'/product/class/productcustomerprice.class.php';
1443 foreach (
$object->lines as $line) {
1446 if ($line->fk_product > 0) {
1447 $prod =
new Product($this->db);
1448 $res = $prod->fetch($line->fk_product);
1450 if ($update_prices ===
true) {
1451 $pu_ht = $prod->price;
1453 $remise_percent = $objsoc->remise_percent;
1456 $pu_ht = $prod->multiprices[$objsoc->price_level];
1458 if (isset($prod->multiprices_tva_tx[$objsoc->price_level])) {
1459 $tva_tx = $prod->multiprices_tva_tx[$objsoc->price_level];
1464 $filter = array(
't.fk_product' => $prod->id,
't.fk_soc' => $objsoc->id);
1465 $result = $prodcustprice->fetchAll(
'',
'', 0, 0, $filter);
1468 if (count($prodcustprice->lines) > 0) {
1469 $pu_ht =
price($prodcustprice->lines[0]->price);
1470 $tva_tx = ($prodcustprice->lines[0]->default_vat_code ? $prodcustprice->lines[0]->tva_tx.
' ('.$prodcustprice->lines[0]->default_vat_code.
' )' : $prodcustprice->lines[0]->tva_tx);
1471 if ($prodcustprice->lines[0]->default_vat_code && !preg_match(
'/\(.*\)/', $tva_tx)) {
1472 $tva_tx .=
' ('.$prodcustprice->lines[0]->default_vat_code.
')';
1478 $line->subprice = $pu_ht;
1479 $line->tva_tx = $tva_tx;
1480 $line->remise_percent = $remise_percent;
1482 if ($update_desc ===
true) {
1483 $line->desc = $prod->description;
1493 $object->entity = (!empty($forceentity) ? $forceentity :
$object->entity);
1497 $object->user_creation_id = $user->id;
1498 $object->user_validation_id = 0;
1511 $object->context[
'createfromclone'] =
'createfromclone';
1512 $result =
$object->create($user);
1514 $this->error =
$object->error;
1515 $this->errors = array_merge($this->errors,
$object->errors);
1521 if (
$object->copy_linked_contact($this,
'internal') < 0) {
1528 if ($this->socid ==
$object->socid) {
1529 if (
$object->copy_linked_contact($this,
'external') < 0) {
1537 if (is_object($hookmanager)) {
1538 $parameters = array(
'objFrom' => $this,
'clonedObj' =>
$object);
1540 $reshook = $hookmanager->executeHooks(
'createFrom', $parameters,
$object, $action);
1548 unset(
$object->context[
'createfromclone']);
1552 $this->db->commit();
1555 $this->db->rollback();
1569 public function fetch($rowid, $ref =
'', $ref_ext =
'', $forceentity = 0)
1571 $sql =
"SELECT p.rowid, p.ref, p.entity, p.fk_soc";
1572 $sql .=
", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht";
1573 $sql .=
", p.datec";
1574 $sql .=
", p.date_signature as dates";
1575 $sql .=
", p.date_valid as datev";
1576 $sql .=
", p.datep as dp";
1577 $sql .=
", p.fin_validite as dfv";
1578 $sql .=
", p.date_livraison as delivery_date";
1579 $sql .=
", p.model_pdf, p.last_main_doc, p.ref_client, ref_ext, p.extraparams";
1580 $sql .=
", p.note_private, p.note_public";
1581 $sql .=
", p.fk_projet as fk_project, p.fk_statut";
1582 $sql .=
", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
1583 $sql .=
", p.fk_delivery_address";
1584 $sql .=
", p.fk_availability";
1585 $sql .=
", p.fk_input_reason";
1586 $sql .=
", p.fk_cond_reglement";
1587 $sql .=
", p.fk_mode_reglement";
1588 $sql .=
', p.fk_account';
1589 $sql .=
", p.fk_shipping_method";
1590 $sql .=
", p.fk_warehouse";
1591 $sql .=
", p.fk_incoterms, p.location_incoterms";
1592 $sql .=
", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
1593 $sql .=
", p.tms as date_modification";
1594 $sql .=
", i.libelle as label_incoterms";
1595 $sql .=
", c.label as statut_label";
1596 $sql .=
", ca.code as availability_code, ca.label as availability";
1597 $sql .=
", dr.code as demand_reason_code, dr.label as demand_reason";
1598 $sql .=
", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc, p.deposit_percent";
1599 $sql .=
", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
1600 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
1601 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_propalst as c ON p.fk_statut = c.id';
1602 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_paiement as cp ON p.fk_mode_reglement = cp.id AND cp.entity IN ('.
getEntity(
'c_paiement').
')';
1603 $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').
')';
1604 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_availability as ca ON p.fk_availability = ca.rowid';
1605 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
1606 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'c_incoterms as i ON p.fk_incoterms = i.rowid';
1609 if (!empty($forceentity)) {
1610 $sql .=
" WHERE p.entity = ".(int) $forceentity;
1612 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
1614 $sql .=
" AND p.ref='".$this->db->escape($ref).
"'";
1617 $sql .=
" WHERE p.rowid = ".((int) $rowid);
1620 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
1621 $resql = $this->db->query($sql);
1623 if ($this->db->num_rows($resql)) {
1624 $obj = $this->db->fetch_object($resql);
1626 $this->
id = $obj->rowid;
1627 $this->entity = $obj->entity;
1629 $this->
ref = $obj->ref;
1630 $this->ref_client = $obj->ref_client;
1631 $this->ref_customer = $obj->ref_client;
1632 $this->ref_ext = $obj->ref_ext;
1634 $this->total = $obj->total_ttc;
1635 $this->total_ttc = $obj->total_ttc;
1636 $this->total_ht = $obj->total_ht;
1637 $this->total_tva = $obj->total_tva;
1638 $this->total_localtax1 = $obj->localtax1;
1639 $this->total_localtax2 = $obj->localtax2;
1641 $this->socid = $obj->fk_soc;
1642 $this->thirdparty =
null;
1644 $this->fk_project = $obj->fk_project;
1645 $this->project =
null;
1647 $this->model_pdf = $obj->model_pdf;
1648 $this->last_main_doc = $obj->last_main_doc;
1649 $this->note = $obj->note_private;
1650 $this->note_private = $obj->note_private;
1651 $this->note_public = $obj->note_public;
1653 $this->
status = (int) $obj->fk_statut;
1654 $this->
statut = $this->status;
1656 $this->datec = $this->db->jdate($obj->datec);
1657 $this->datev = $this->db->jdate($obj->datev);
1658 $this->date_creation = $this->db->jdate($obj->datec);
1659 $this->date_validation = $this->db->jdate($obj->datev);
1660 $this->date_modification = $this->db->jdate($obj->date_modification);
1661 $this->date_signature = $this->db->jdate($obj->dates);
1662 $this->date = $this->db->jdate($obj->dp);
1663 $this->datep = $this->db->jdate($obj->dp);
1664 $this->fin_validite = $this->db->jdate($obj->dfv);
1665 $this->delivery_date = $this->db->jdate($obj->delivery_date);
1666 $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method :
null;
1667 $this->warehouse_id = ($obj->fk_warehouse > 0) ? $obj->fk_warehouse :
null;
1668 $this->availability_id = $obj->fk_availability;
1669 $this->availability_code = $obj->availability_code;
1671 $this->demand_reason_id = $obj->fk_input_reason;
1672 $this->demand_reason_code = $obj->demand_reason_code;
1674 $this->fk_address = $obj->fk_delivery_address;
1676 $this->mode_reglement_id = $obj->fk_mode_reglement;
1677 $this->mode_reglement_code = $obj->mode_reglement_code;
1678 $this->mode_reglement = $obj->mode_reglement;
1679 $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account :
null;
1680 $this->cond_reglement_id = $obj->fk_cond_reglement;
1681 $this->cond_reglement_code = $obj->cond_reglement_code;
1682 $this->cond_reglement = $obj->cond_reglement;
1683 $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
1684 $this->deposit_percent = $obj->deposit_percent;
1686 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
1688 $this->user_author_id = $obj->fk_user_author;
1689 $this->user_validation_id = $obj->fk_user_valid;
1690 $this->user_closing_id = $obj->fk_user_cloture;
1693 $this->fk_incoterms = $obj->fk_incoterms;
1694 $this->location_incoterms = $obj->location_incoterms;
1695 $this->label_incoterms = $obj->label_incoterms;
1698 $this->fk_multicurrency = $obj->fk_multicurrency;
1699 $this->multicurrency_code = $obj->multicurrency_code;
1700 $this->multicurrency_tx = $obj->multicurrency_tx;
1701 $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
1702 $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
1703 $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
1709 $this->db->free($resql);
1711 $this->lines = array();
1722 $this->error =
"Record Not Found";
1725 $this->error = $this->db->lasterror();
1744 if (isset($this->
ref)) {
1745 $this->
ref = trim($this->
ref);
1747 if (isset($this->ref_client)) {
1748 $this->ref_client = trim($this->ref_client);
1750 if (isset($this->note) || isset($this->note_private)) {
1751 $this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note));
1753 if (isset($this->note_public)) {
1754 $this->note_public = trim($this->note_public);
1756 if (isset($this->model_pdf)) {
1757 $this->model_pdf = trim($this->model_pdf);
1759 if (isset($this->import_key)) {
1760 $this->import_key = trim($this->import_key);
1762 if (!empty($this->duree_validite) && is_numeric($this->duree_validite)) {
1763 $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
1770 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET";
1771 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"null").
",";
1772 $sql .=
" ref_client=".(isset($this->ref_client) ?
"'".$this->db->escape($this->ref_client).
"'" :
"null").
",";
1773 $sql .=
" ref_ext=".(isset($this->ref_ext) ?
"'".$this->db->escape($this->ref_ext).
"'" :
"null").
",";
1774 $sql .=
" fk_soc=".(isset($this->socid) ? $this->socid :
"null").
",";
1775 $sql .=
" datep=".(strval($this->date) !=
'' ?
"'".$this->db->idate($this->date).
"'" :
'null').
",";
1776 if (!empty($this->fin_validite)) {
1777 $sql .=
" fin_validite=".(strval($this->fin_validite) !=
'' ?
"'".$this->db->idate($this->fin_validite).
"'" :
'null').
",";
1779 $sql .=
" date_valid=".(strval($this->date_validation) !=
'' ?
"'".$this->db->idate($this->date_validation).
"'" :
'null').
",";
1780 $sql .=
" total_tva=".(isset($this->total_tva) ? $this->total_tva :
"null").
",";
1781 $sql .=
" localtax1=".(isset($this->total_localtax1) ? $this->total_localtax1 :
"null").
",";
1782 $sql .=
" localtax2=".(isset($this->total_localtax2) ? $this->total_localtax2 :
"null").
",";
1783 $sql .=
" total_ht=".(isset($this->total_ht) ? $this->total_ht :
"null").
",";
1784 $sql .=
" total_ttc=".(isset($this->total_ttc) ? $this->total_ttc :
"null").
",";
1785 $sql .=
" fk_statut=".(isset($this->
status) ? $this->
status :
"null").
",";
1786 $sql .=
" fk_user_author=".(isset($this->user_author_id) ? $this->user_author_id :
"null").
",";
1787 $sql .=
" fk_user_valid=".(isset($this->user_validation_id) ? $this->user_validation_id :
"null").
",";
1788 $sql .=
" fk_projet=".(isset($this->fk_project) ? $this->fk_project :
"null").
",";
1789 $sql .=
" fk_cond_reglement=".(isset($this->cond_reglement_id) ? $this->cond_reglement_id :
"null").
",";
1790 $sql .=
" deposit_percent=".(!empty($this->deposit_percent) ?
"'".$this->db->escape($this->deposit_percent).
"'" :
"null").
",";
1791 $sql .=
" fk_mode_reglement=".(isset($this->mode_reglement_id) ? $this->mode_reglement_id :
"null").
",";
1792 $sql .=
" fk_input_reason=".(isset($this->demand_reason_id) ? $this->demand_reason_id :
"null").
",";
1793 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1794 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1795 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1796 $sql .=
" import_key=".(isset($this->import_key) ?
"'".$this->db->escape($this->import_key).
"'" :
"null");
1797 $sql .=
" WHERE rowid=".((int) $this->
id);
1801 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
1802 $resql = $this->db->query($sql);
1805 $this->errors[] =
"Error ".$this->db->lasterror();
1815 if (!$error && !$notrigger) {
1826 foreach ($this->errors as $errmsg) {
1827 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1828 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1830 $this->db->rollback();
1833 $this->db->commit();
1848 public function fetch_lines($only_product = 0, $loadalsotranslation = 0, $sqlforgedfilters =
'')
1851 $this->lines = array();
1853 $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,';
1854 $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,';
1855 $sql .=
' d.fk_unit,';
1856 $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,';
1857 $sql .=
' p.weight, p.weight_units, p.volume, p.volume_units,';
1858 $sql .=
' d.date_start, d.date_end,';
1859 $sql .=
' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc';
1860 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as d';
1861 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON (d.fk_product = p.rowid)';
1862 $sql .=
' WHERE d.fk_propal = '.((int) $this->
id);
1863 if ($only_product) {
1864 $sql .=
' AND p.fk_product_type = 0';
1866 if ($sqlforgedfilters) {
1867 $sql .= $sqlforgedfilters;
1869 $sql .=
' ORDER by d.rang';
1871 dol_syslog(get_class($this).
"::fetch_lines", LOG_DEBUG);
1872 $result = $this->db->query($sql);
1874 require_once DOL_DOCUMENT_ROOT.
'/core/class/extrafields.class.php';
1876 $num = $this->db->num_rows($result);
1880 $objp = $this->db->fetch_object($result);
1884 $line->rowid = $objp->rowid;
1885 $line->id = $objp->rowid;
1886 $line->fk_propal = $objp->fk_propal;
1887 $line->fk_parent_line = $objp->fk_parent_line;
1888 $line->product_type = $objp->product_type;
1889 $line->label = $objp->custom_label;
1890 $line->desc = $objp->description;
1891 $line->description = $objp->description;
1892 $line->qty = $objp->qty;
1893 $line->vat_src_code = $objp->vat_src_code;
1894 $line->tva_tx = $objp->tva_tx;
1895 $line->localtax1_tx = $objp->localtax1_tx;
1896 $line->localtax2_tx = $objp->localtax2_tx;
1897 $line->localtax1_type = $objp->localtax1_type;
1898 $line->localtax2_type = $objp->localtax2_type;
1899 $line->subprice = $objp->subprice;
1900 $line->fk_remise_except = $objp->fk_remise_except;
1901 $line->remise_percent = $objp->remise_percent;
1902 $line->price = $objp->price;
1904 $line->info_bits = $objp->info_bits;
1905 $line->total_ht = $objp->total_ht;
1906 $line->total_tva = $objp->total_tva;
1907 $line->total_localtax1 = $objp->total_localtax1;
1908 $line->total_localtax2 = $objp->total_localtax2;
1909 $line->total_ttc = $objp->total_ttc;
1910 $line->fk_fournprice = $objp->fk_fournprice;
1911 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
1912 $line->pa_ht = $marginInfos[0];
1913 $line->marge_tx = $marginInfos[1];
1914 $line->marque_tx = $marginInfos[2];
1915 $line->special_code = $objp->special_code;
1916 $line->rang = $objp->rang;
1918 $line->fk_product = $objp->fk_product;
1920 $line->ref = $objp->product_ref;
1921 $line->libelle = $objp->product_label;
1923 $line->product_ref = $objp->product_ref;
1924 $line->product_label = $objp->product_label;
1925 $line->product_desc = $objp->product_desc;
1926 $line->product_tobatch = $objp->product_tobatch;
1927 $line->product_barcode = $objp->product_barcode;
1929 $line->fk_product_type = $objp->fk_product_type;
1930 $line->fk_unit = $objp->fk_unit;
1931 $line->weight = $objp->weight;
1932 $line->weight_units = $objp->weight_units;
1933 $line->volume = $objp->volume;
1934 $line->volume_units = $objp->volume_units;
1936 $line->date_start = $this->db->jdate($objp->date_start);
1937 $line->date_end = $this->db->jdate($objp->date_end);
1940 $line->fk_multicurrency = $objp->fk_multicurrency;
1941 $line->multicurrency_code = $objp->multicurrency_code;
1942 $line->multicurrency_subprice = $objp->multicurrency_subprice;
1943 $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
1944 $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
1945 $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
1947 $line->fetch_optionals();
1950 if (
getDolGlobalInt(
'MAIN_MULTILANGS') && !empty($objp->fk_product) && !empty($loadalsotranslation)) {
1951 $tmpproduct =
new Product($this->db);
1952 $tmpproduct->fetch($objp->fk_product);
1953 $tmpproduct->getMultiLangs();
1955 $line->multilangs = $tmpproduct->multilangs;
1958 $this->lines[$i] = $line;
1963 $this->db->free($result);
1967 $this->error = $this->db->lasterror();
1979 public function valid($user, $notrigger = 0)
1983 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
1988 if ($this->
status == self::STATUS_VALIDATED) {
1989 dol_syslog(get_class($this).
"::valid action abandoned: already validated", LOG_WARNING);
1993 if (!((!
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'creer'))
1994 || (
getDolGlobalString(
'MAIN_USE_ADVANCED_PERMS') && $user->hasRight(
'propal',
'propal_advance',
'validate')))) {
1995 $this->error =
'ErrorPermissionDenied';
1996 dol_syslog(get_class($this).
"::valid ".$this->error, LOG_ERR);
2005 $soc =
new Societe($this->db);
2006 $soc->fetch($this->socid);
2009 if (!$error && (preg_match(
'/^[\(]?PROV/i', $this->
ref) || empty($this->
ref))) {
2016 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2017 $sql .=
" SET ref = '".$this->db->escape($num).
"',";
2018 $sql .=
" fk_statut = ".self::STATUS_VALIDATED.
", date_valid='".$this->db->idate($now).
"', fk_user_valid=".((int) $user->id);
2021 dol_syslog(get_class($this).
"::valid", LOG_DEBUG);
2022 $resql = $this->db->query($sql);
2029 if (!$error && !$notrigger) {
2031 $result = $this->
call_trigger(
'PROPAL_VALIDATE', $user);
2039 $this->oldref = $this->ref;
2042 if (preg_match(
'/^[\(]?PROV/i', $this->
ref)) {
2044 $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).
"'";
2045 $sql .=
" WHERE filename LIKE '".$this->db->escape($this->
ref).
"%' AND filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".((int) $conf->entity);
2046 $resql = $this->db->query($sql);
2049 $this->error = $this->db->lasterror();
2051 $sql =
'UPDATE '.MAIN_DB_PREFIX.
"ecm_files set filepath = 'propale/".$this->db->escape($this->newref).
"'";
2052 $sql .=
" WHERE filepath = 'propale/".$this->db->escape($this->
ref).
"' and entity = ".$conf->entity;
2053 $resql = $this->db->query($sql);
2056 $this->error = $this->db->lasterror();
2062 $dirsource = $conf->propal->multidir_output[$this->entity].
'/'.$oldref;
2063 $dirdest = $conf->propal->multidir_output[$this->entity].
'/'.$newref;
2064 if (!$error && file_exists($dirsource)) {
2065 dol_syslog(get_class($this).
"::validate rename dir ".$dirsource.
" into ".$dirdest);
2066 if (@rename($dirsource, $dirdest)) {
2069 $listoffiles =
dol_dir_list($dirdest,
'files', 1,
'^'.preg_quote($oldref,
'/'));
2070 foreach ($listoffiles as $fileentry) {
2071 $dirsource = $fileentry[
'name'];
2072 $dirdest = preg_replace(
'/^'.preg_quote($oldref,
'/').
'/', $newref, $dirsource);
2073 $dirsource = $fileentry[
'path'].
'/'.$dirsource;
2074 $dirdest = $fileentry[
'path'].
'/'.$dirdest;
2075 @rename($dirsource, $dirdest);
2084 $this->user_validation_id = $user->id;
2085 $this->datev = $now;
2086 $this->date_validation = $now;
2088 $this->db->commit();
2091 $this->db->rollback();
2110 $this->error =
'ErrorBadParameter';
2111 dol_syslog(get_class($this).
"::set_date ".$this->error, LOG_ERR);
2115 if ($user->hasRight(
'propal',
'creer')) {
2120 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET datep = '".$this->db->idate($date).
"'";
2121 $sql .=
" WHERE rowid = ".((int) $this->
id);
2124 $resql = $this->db->query($sql);
2126 $this->errors[] = $this->db->error();
2131 $this->oldcopy = clone $this;
2132 $this->date = $date;
2133 $this->datep = $date;
2136 if (!$notrigger && empty($error)) {
2146 $this->db->commit();
2149 foreach ($this->errors as $errmsg) {
2150 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2151 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2153 $this->db->rollback();
2173 if ($user->hasRight(
'propal',
'creer')) {
2178 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET fin_validite = ".($date_end_validity !=
'' ?
"'".$this->db->idate($date_end_validity).
"'" :
'null');
2179 $sql .=
" WHERE rowid = ".((int) $this->
id);
2183 $resql = $this->db->query($sql);
2185 $this->errors[] = $this->db->error();
2191 $this->oldcopy = clone $this;
2192 $this->fin_validite = $date_end_validity;
2195 if (!$notrigger && empty($error)) {
2205 $this->db->commit();
2208 foreach ($this->errors as $errmsg) {
2209 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2210 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2212 $this->db->rollback();
2246 if ($user->hasRight(
'propal',
'creer')) {
2251 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2252 $sql .=
" SET date_livraison = ".(isDolTms($delivery_date) ?
"'".$this->db->idate($delivery_date).
"'" :
'null');
2253 $sql .=
" WHERE rowid = ".((int) $this->
id);
2256 $resql = $this->db->query($sql);
2258 $this->errors[] = $this->db->error();
2263 $this->oldcopy = clone $this;
2264 $this->delivery_date = $delivery_date;
2267 if (!$notrigger && empty($error)) {
2277 $this->db->commit();
2280 foreach ($this->errors as $errmsg) {
2281 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2282 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2284 $this->db->rollback();
2304 if ($user->hasRight(
'propal',
'creer') && $this->status >= self::STATUS_DRAFT) {
2309 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2310 $sql .=
" SET fk_availability = ".((int) $id);
2311 $sql .=
" WHERE rowid = ".((int) $this->
id);
2313 dol_syslog(__METHOD__.
' availability('.$id.
')', LOG_DEBUG);
2314 $resql = $this->db->query($sql);
2316 $this->errors[] = $this->db->error();
2321 $this->oldcopy = clone $this;
2322 $this->fk_availability = $id;
2323 $this->availability_id = $id;
2326 if (!$notrigger && empty($error)) {
2336 $this->db->commit();
2339 foreach ($this->errors as $errmsg) {
2340 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2341 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2343 $this->db->rollback();
2347 $error_str =
'Propal status do not meet requirement '.$this->status;
2349 $this->error = $error_str;
2350 $this->errors[] = $this->error;
2367 if ($user->hasRight(
'propal',
'creer') && $this->status >= self::STATUS_DRAFT) {
2372 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal ";
2373 $sql .=
" SET fk_input_reason = ".((int) $id);
2374 $sql .=
" WHERE rowid = ".((int) $this->
id);
2377 $resql = $this->db->query($sql);
2379 $this->errors[] = $this->db->error();
2385 $this->oldcopy = clone $this;
2387 $this->demand_reason_id = $id;
2391 if (!$notrigger && empty($error)) {
2401 $this->db->commit();
2404 foreach ($this->errors as $errmsg) {
2405 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2406 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2408 $this->db->rollback();
2412 $error_str =
'Propal status do not meet requirement '.$this->status;
2414 $this->error = $error_str;
2415 $this->errors[] = $this->error;
2432 if ($user->hasRight(
'propal',
'creer')) {
2437 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal SET ref_client = ".(empty($ref_client) ?
'NULL' :
"'".$this->db->escape($ref_client).
"'");
2438 $sql .=
" WHERE rowid = ".((int) $this->
id);
2440 dol_syslog(__METHOD__.
' $this->id='.$this->id.
', ref_client='.$ref_client, LOG_DEBUG);
2441 $resql = $this->db->query($sql);
2443 $this->errors[] = $this->db->error();
2448 $this->oldcopy = clone $this;
2449 $this->ref_client = $ref_client;
2452 if (!$notrigger && empty($error)) {
2462 $this->db->commit();
2465 foreach ($this->errors as $errmsg) {
2466 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2467 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2469 $this->db->rollback();
2487 public function reopen($user, $status, $note =
'', $notrigger = 0)
2491 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2492 $sql .=
" SET fk_statut = ".((int) $status).
",";
2493 if (!empty($note)) {
2494 $sql .=
" note_private = '".$this->db->escape($note).
"',";
2496 $sql .=
" date_cloture=NULL, fk_user_cloture=NULL";
2497 $sql .=
" WHERE rowid = ".((int) $this->
id);
2501 dol_syslog(get_class($this).
"::reopen", LOG_DEBUG);
2502 $resql = $this->db->query($sql);
2505 $this->errors[] =
"Error ".$this->db->lasterror();
2520 if (!empty($this->errors)) {
2521 foreach ($this->errors as $errmsg) {
2522 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
2523 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2526 $this->db->rollback();
2532 $this->db->commit();
2548 global $langs,$conf;
2558 $date_signature = $now;
2559 $fk_user_signature = $user->id;
2561 $this->
info($this->
id);
2562 if (!isset($this->date_signature) || $this->date_signature ==
'') {
2563 $date_signature = $now;
2564 $fk_user_signature = $user->id;
2566 $date_signature = $this->date_signature;
2567 $fk_user_signature = $this->user_signature->id;
2571 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2572 $sql .=
" SET fk_statut = ".((int) $status).
", note_private = '".$this->db->escape($newprivatenote).
"'";
2573 if ($status == self::STATUS_SIGNED) {
2574 $sql .=
", date_signature='".$this->db->idate($now).
"', fk_user_signature = ".($fk_user_signature);
2576 $sql .=
" WHERE rowid = ".((int) $this->
id);
2578 $resql = $this->db->query($sql);
2582 $trigger_name =
'PROPAL_CLOSE_REFUSED';
2584 if ($status == self::STATUS_SIGNED) {
2585 $trigger_name =
'PROPAL_CLOSE_SIGNED';
2586 $modelpdf =
getDolGlobalString(
'PROPALE_ADDON_PDF_ODT_TOBILL') ? $conf->global->PROPALE_ADDON_PDF_ODT_TOBILL : $this->model_pdf;
2589 $soc =
new Societe($this->db);
2590 $soc->id = $this->socid;
2591 $result = $soc->setAsCustomer();
2594 $this->error = $this->db->lasterror();
2595 $this->db->rollback();
2602 $outputlangs = $langs;
2604 $outputlangs =
new Translate(
"", $conf);
2605 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2606 $outputlangs->setDefaultLang($newlang);
2615 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2619 $this->oldcopy = clone $this;
2622 $this->date_signature = $date_signature;
2623 $this->note_private = $newprivatenote;
2626 if (!$notrigger && empty($error)) {
2636 $this->db->commit();
2639 $this->
statut = $this->oldcopy->status;
2640 $this->
status = $this->oldcopy->status;
2641 $this->date_signature = $this->oldcopy->date_signature;
2642 $this->note_private = $this->oldcopy->note_private;
2644 $this->db->rollback();
2648 $this->error = $this->db->lasterror();
2649 $this->db->rollback();
2664 global $conf, $langs;
2671 $triggerName =
'PROPAL_CLASSIFY_BILLED';
2677 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal SET fk_statut = '.self::STATUS_BILLED.
", ";
2678 $sql .=
" note_private = '".$this->db->escape($newprivatenote).
"', date_cloture='".$this->db->idate($now).
"', fk_user_cloture=".((int) $user->id);
2679 $sql .=
' WHERE rowid = '.((int) $this->
id).
' AND fk_statut = '.((int) self::STATUS_SIGNED);
2682 $resql = $this->db->query($sql);
2684 $this->errors[] = $this->db->error();
2687 $num = $this->db->affected_rows($resql);
2695 $outputlangs = $langs;
2697 $outputlangs =
new Translate(
"", $conf);
2698 $newlang = (
GETPOST(
'lang_id',
'aZ09') ?
GETPOST(
'lang_id',
'aZ09') : $this->thirdparty->default_lang);
2699 $outputlangs->setDefaultLang($newlang);
2708 $this->
generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
2711 $this->oldcopy = clone $this;
2714 $this->date_cloture = $now;
2715 $this->note_private = $newprivatenote;
2718 if (!$notrigger && empty($error)) {
2728 $this->db->commit();
2731 foreach ($this->errors as $errmsg) {
2732 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2733 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2735 $this->db->rollback();
2752 $sql =
"UPDATE ". MAIN_DB_PREFIX .
"propal";
2753 $sql .=
" SET fk_statut = " . self::STATUS_CANCELED .
",";
2754 $sql .=
" fk_user_modif = " . ((int) $user->id);
2755 $sql .=
" WHERE rowid = " . ((int) $this->
id);
2757 dol_syslog(get_class($this).
"::cancel", LOG_DEBUG);
2758 if ($this->db->query($sql)) {
2771 $this->db->commit();
2774 foreach ($this->errors as $errmsg) {
2775 dol_syslog(get_class($this).
"::cancel ".$errmsg, LOG_ERR);
2776 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2778 $this->db->rollback();
2782 $this->error = $this->db->error();
2783 $this->db->rollback();
2802 if ($this->
status <= self::STATUS_DRAFT) {
2806 dol_syslog(get_class($this).
"::setDraft", LOG_DEBUG);
2810 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propal";
2811 $sql .=
" SET fk_statut = ".self::STATUS_DRAFT;
2812 $sql .=
", online_sign_ip = NULL , online_sign_name = NULL";
2813 $sql .=
" WHERE rowid = ".((int) $this->
id);
2815 $resql = $this->db->query($sql);
2817 $this->errors[] = $this->db->error();
2822 $this->oldcopy = clone $this;
2825 if (!$notrigger && empty($error)) {
2838 $this->db->commit();
2841 foreach ($this->errors as $errmsg) {
2842 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
2843 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
2845 $this->db->rollback();
2865 public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield =
'p.datep', $sortorder =
'DESC')
2872 $sql =
"SELECT s.rowid, s.nom as name, s.client,";
2873 $sql .=
" p.rowid as propalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
2874 $sql .=
" p.datep as dp, p.fin_validite as datelimite";
2875 $sql .=
" FROM ".MAIN_DB_PREFIX.
"societe as s, ".MAIN_DB_PREFIX.
"propal as p, ".MAIN_DB_PREFIX.
"c_propalst as c";
2876 $sql .=
" WHERE p.entity IN (".getEntity(
'propal').
")";
2877 $sql .=
" AND p.fk_soc = s.rowid";
2878 $sql .=
" AND p.fk_statut = c.id";
2882 if (!$user->hasRight(
'societe',
'client',
'voir')) {
2883 $search_sale = $user->id;
2886 if ($search_sale && $search_sale !=
'-1') {
2887 if ($search_sale == -2) {
2888 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
2889 } elseif ($search_sale > 0) {
2890 $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).
")";
2895 $sql .=
" AND p.fk_soc = ".((int) $socid);
2898 $sql .=
" AND p.fk_statut = ".((int) self::STATUS_DRAFT);
2900 if ($notcurrentuser > 0) {
2901 $sql .=
" AND p.fk_user_author <> ".((int) $user->id);
2903 $sql .= $this->db->order($sortfield, $sortorder);
2904 $sql .= $this->db->plimit($limit, $offset);
2906 $result = $this->db->query($sql);
2908 $num = $this->db->num_rows($result);
2912 $obj = $this->db->fetch_object($result);
2914 if ($shortlist == 1) {
2915 $ga[$obj->propalid] = $obj->ref;
2916 } elseif ($shortlist == 2) {
2917 $ga[$obj->propalid] = $obj->ref.
' ('.$obj->name.
')';
2919 $ga[$i][
'id'] = $obj->propalid;
2920 $ga[$i][
'ref'] = $obj->ref;
2921 $ga[$i][
'name'] = $obj->name;
2955 $linkedInvoices = array();
2958 foreach ($this->linkedObjectsIds as $objecttype => $objectid) {
2961 foreach ($objectid as $key =>
$object) {
2963 if ($objecttype ==
'facture') {
2968 foreach ($this->linkedObjectsIds as $subobjecttype => $subobjectid) {
2969 foreach ($subobjectid as $subkey => $subobject) {
2970 if ($subobjecttype ==
'facture') {
2971 $linkedInvoices[] = $subobject;
2979 if (count($linkedInvoices) > 0) {
2980 $sql =
"SELECT rowid as facid, ref, total_ht as total, datef as df, fk_user_author, fk_statut, paye";
2981 $sql .=
" FROM ".MAIN_DB_PREFIX.
"facture";
2982 $sql .=
" WHERE rowid IN (".$this->db->sanitize(implode(
',', $linkedInvoices)).
")";
2984 dol_syslog(get_class($this).
"::InvoiceArrayList", LOG_DEBUG);
2985 $resql = $this->db->query($sql);
2988 $tab_sqlobj = array();
2989 $nump = $this->db->num_rows($resql);
2990 for ($i = 0; $i < $nump; $i++) {
2991 $sqlobj = $this->db->fetch_object($resql);
2992 $tab_sqlobj[] = $sqlobj;
2994 $this->db->free($resql);
2996 $nump = count($tab_sqlobj);
3000 while ($i < $nump) {
3001 $obj = array_shift($tab_sqlobj);
3024 public function delete($user, $notrigger = 0)
3027 require_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
3043 if (!$error && !empty($this->table_element_line)) {
3044 $tabletodelete = $this->table_element_line;
3045 $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).
")";
3046 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete.
" WHERE ".$this->fk_element.
" = ".((int) $this->
id);
3047 if (!$this->db->query($sqlef) || !$this->db->query($sql)) {
3049 $this->error = $this->db->lasterror();
3050 $this->errors[] = $this->error;
3051 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3076 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3082 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.$this->table_element.
" WHERE rowid = ".((int) $this->
id);
3083 $res = $this->db->query($sql);
3086 $this->error = $this->db->lasterror();
3087 $this->errors[] = $this->error;
3088 dol_syslog(get_class($this).
"::delete error ".$this->error, LOG_ERR);
3104 if ($conf->propal->multidir_output[$this->entity] && !empty($this->
ref)) {
3105 $dir = $conf->propal->multidir_output[$this->entity].
"/".$ref;
3106 $file = $dir.
"/".$ref.
".pdf";
3107 if (file_exists($file)) {
3111 $this->error =
'ErrorFailToDeleteFile';
3112 $this->errors[] = $this->error;
3113 $this->db->rollback();
3117 if (file_exists($dir)) {
3120 $this->error =
'ErrorFailToDeleteDir';
3121 $this->errors[] = $this->error;
3122 $this->db->rollback();
3130 dol_syslog(get_class($this).
"::delete ".$this->
id.
" by ".$user->id, LOG_DEBUG);
3131 $this->db->commit();
3134 $this->db->rollback();
3151 if ($this->
status >= self::STATUS_DRAFT) {
3156 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3157 $sql .=
' SET fk_availability = '.((int) $availability_id);
3158 $sql .=
' WHERE rowid='.((int) $this->
id);
3160 dol_syslog(__METHOD__.
' availability('.$availability_id.
')', LOG_DEBUG);
3161 $resql = $this->db->query($sql);
3163 $this->errors[] = $this->db->error();
3168 $this->oldcopy = clone $this;
3169 $this->availability_id = $availability_id;
3172 if (!$notrigger && empty($error)) {
3182 $this->db->commit();
3185 foreach ($this->errors as $errmsg) {
3186 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3187 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3189 $this->db->rollback();
3193 $error_str =
'Propal status do not meet requirement '.$this->status;
3195 $this->error = $error_str;
3196 $this->errors[] = $this->error;
3215 if ($this->
status >= self::STATUS_DRAFT) {
3220 $sql =
'UPDATE '.MAIN_DB_PREFIX.
'propal';
3221 $sql .=
' SET fk_input_reason = '.((int) $demand_reason_id);
3222 $sql .=
' WHERE rowid='.((int) $this->
id);
3224 dol_syslog(__METHOD__.
' demand_reason('.$demand_reason_id.
')', LOG_DEBUG);
3225 $resql = $this->db->query($sql);
3227 $this->errors[] = $this->db->error();
3232 $this->oldcopy = clone $this;
3233 $this->demand_reason_id = $demand_reason_id;
3236 if (!$notrigger && empty($error)) {
3246 $this->db->commit();
3249 foreach ($this->errors as $errmsg) {
3250 dol_syslog(__METHOD__.
' Error: '.$errmsg, LOG_ERR);
3251 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
3253 $this->db->rollback();
3257 $error_str =
'Propal status do not meet requirement '.$this->status;
3259 $this->error = $error_str;
3260 $this->errors[] = $this->error;
3274 $sql =
"SELECT c.rowid, ";
3275 $sql .=
" c.datec, c.date_valid as datev, c.date_signature, c.date_cloture,";
3276 $sql .=
" c.fk_user_author, c.fk_user_valid, c.fk_user_signature, c.fk_user_cloture";
3277 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as c";
3278 $sql .=
" WHERE c.rowid = ".((int) $id);
3280 $result = $this->db->query($sql);
3283 if ($this->db->num_rows($result)) {
3284 $obj = $this->db->fetch_object($result);
3286 $this->
id = $obj->rowid;
3288 $this->date_creation = $this->db->jdate($obj->datec);
3289 $this->date_validation = $this->db->jdate($obj->datev);
3290 $this->date_signature = $this->db->jdate($obj->date_signature);
3291 $this->date_cloture = $this->db->jdate($obj->date_cloture);
3293 $this->user_creation_id = $obj->fk_user_author;
3294 $this->user_validation_id = $obj->fk_user_valid;
3296 if ($obj->fk_user_signature) {
3297 $user_signature =
new User($this->db);
3298 $user_signature->fetch($obj->fk_user_signature);
3299 $this->user_signature = $user_signature;
3302 $this->user_closing_id = $obj->fk_user_cloture;
3304 $this->db->free($result);
3333 global $hookmanager;
3336 if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
3338 $langs->load(
"propal");
3339 $this->labelStatus[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceled");
3340 $this->labelStatus[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraft");
3341 $this->labelStatus[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidated");
3342 $this->labelStatus[2] = $langs->transnoentitiesnoconv(
"PropalStatusSigned");
3343 $this->labelStatus[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSigned");
3344 $this->labelStatus[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilled");
3345 $this->labelStatusShort[-1] = $langs->transnoentitiesnoconv(
"PropalStatusCanceledShort");
3346 $this->labelStatusShort[0] = $langs->transnoentitiesnoconv(
"PropalStatusDraftShort");
3347 $this->labelStatusShort[1] = $langs->transnoentitiesnoconv(
"PropalStatusValidatedShort");
3348 $this->labelStatusShort[2] = $langs->transnoentitiesnoconv(
"PropalStatusSignedShort");
3349 $this->labelStatusShort[3] = $langs->transnoentitiesnoconv(
"PropalStatusNotSignedShort");
3350 $this->labelStatusShort[4] = $langs->transnoentitiesnoconv(
"PropalStatusBilledShort");
3354 if ($status == self::STATUS_CANCELED) {
3355 $statusType =
'status9';
3356 } elseif ($status == self::STATUS_DRAFT) {
3357 $statusType =
'status0';
3358 } elseif ($status == self::STATUS_VALIDATED) {
3359 $statusType =
'status1';
3360 } elseif ($status == self::STATUS_SIGNED) {
3361 $statusType =
'status4';
3362 } elseif ($status == self::STATUS_NOTSIGNED) {
3363 $statusType =
'status9';
3364 } elseif ($status == self::STATUS_BILLED) {
3365 $statusType =
'status6';
3368 $parameters = array(
'status' => $status,
'mode' => $mode);
3369 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
3372 return $hookmanager->resPrint;
3375 return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status],
'', $statusType, $mode);
3390 global $conf, $langs;
3394 $sql =
"SELECT p.rowid, p.ref, p.datec as datec, p.fin_validite as datefin, p.total_ht";
3395 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3396 $sql .= $clause.
" p.entity IN (".
getEntity(
'propal').
")";
3397 if ($mode ==
'opened') {
3398 $sql .=
" AND p.fk_statut = ".self::STATUS_VALIDATED;
3400 if ($mode ==
'signed') {
3401 $sql .=
" AND p.fk_statut = ".self::STATUS_SIGNED;
3405 if (!$user->hasRight(
'societe',
'client',
'voir')) {
3406 $search_sale = $user->id;
3409 if ($search_sale && $search_sale !=
'-1') {
3410 if ($search_sale == -2) {
3411 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3412 } elseif ($search_sale > 0) {
3413 $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).
")";
3417 $resql = $this->db->query($sql);
3419 $langs->load(
"propal");
3424 $label = $labelShort =
'';
3425 if ($mode ==
'opened') {
3426 $delay_warning = $conf->propal->cloture->warning_delay;
3428 $label = $langs->transnoentitiesnoconv(
"PropalsToClose");
3429 $labelShort = $langs->transnoentitiesnoconv(
"ToAcceptRefuse");
3431 if ($mode ==
'signed') {
3432 $delay_warning = $conf->propal->facturation->warning_delay;
3434 $label = $langs->trans(
"PropalsToBill");
3435 $labelShort = $langs->trans(
"ToBill");
3439 $response->warning_delay = $delay_warning / 60 / 60 / 24;
3440 $response->label = $label;
3441 $response->labelShort = $labelShort;
3442 $response->url = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals';
3443 $response->url_late = DOL_URL_ROOT.
'/comm/propal/list.php?search_status='.$status.
'&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
3447 while ($obj = $this->db->fetch_object($resql)) {
3448 $response->nbtodo++;
3449 $response->total += $obj->total_ht;
3451 if ($mode ==
'opened') {
3452 $datelimit = $this->db->jdate($obj->datefin);
3453 if ($datelimit < ($now - $delay_warning)) {
3454 $response->nbtodolate++;
3463 $this->error = $this->db->error();
3478 global $conf, $langs;
3483 $sql =
"SELECT rowid";
3484 $sql .=
" FROM ".MAIN_DB_PREFIX.
"product";
3485 $sql .=
" WHERE entity IN (".getEntity(
'product').
")";
3486 $sql .= $this->db->plimit(100);
3488 $resql = $this->db->query($sql);
3490 $num_prods = $this->db->num_rows($resql);
3492 while ($i < $num_prods) {
3494 $row = $this->db->fetch_row($resql);
3495 $prodids[$i] = $row[0];
3501 $this->
ref =
'SPECIMEN';
3502 $this->ref_client =
'NEMICEPS';
3503 $this->specimen = 1;
3505 $this->date = time();
3506 $this->fin_validite = $this->date + 3600 * 24 * 30;
3507 $this->cond_reglement_id = 1;
3508 $this->cond_reglement_code =
'RECEP';
3509 $this->mode_reglement_id = 7;
3510 $this->mode_reglement_code =
'CHQ';
3511 $this->availability_id = 1;
3512 $this->availability_code =
'AV_NOW';
3513 $this->demand_reason_id = 1;
3514 $this->demand_reason_code =
'SRC_00';
3515 $this->note_public =
'This is a comment (public)';
3516 $this->note_private =
'This is a comment (private)';
3518 $this->multicurrency_tx = 1;
3519 $this->multicurrency_code = $conf->currency;
3524 while ($xnbp < $nbp) {
3526 $line->desc = $langs->trans(
"Description").
" ".$xnbp;
3528 $line->subprice = 100;
3531 $line->localtax1_tx = 0;
3532 $line->localtax2_tx = 0;
3534 $line->total_ht = 50;
3535 $line->total_ttc = 60;
3536 $line->total_tva = 10;
3537 $line->remise_percent = 50;
3539 $line->total_ht = 100;
3540 $line->total_ttc = 120;
3541 $line->total_tva = 20;
3542 $line->remise_percent = 00;
3545 if ($num_prods > 0) {
3546 $prodid = mt_rand(1, $num_prods);
3547 $line->fk_product = $prodids[$prodid];
3548 $line->product_ref =
'SPECIMEN';
3551 $this->lines[$xnbp] = $line;
3553 $this->total_ht += $line->total_ht;
3554 $this->total_tva += $line->total_tva;
3555 $this->total_ttc += $line->total_ttc;
3572 $this->nb = array();
3575 $sql =
"SELECT count(p.rowid) as nb";
3576 $sql .=
" FROM ".MAIN_DB_PREFIX.
"propal as p";
3577 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3578 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'propal').
")";
3582 if (!$user->hasRight(
'societe',
'client',
'voir')) {
3583 $search_sale = $user->id;
3586 if ($search_sale && $search_sale !=
'-1') {
3587 if ($search_sale == -2) {
3588 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = p.fk_soc)";
3589 } elseif ($search_sale > 0) {
3590 $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).
")";
3594 $resql = $this->db->query($sql);
3597 while ($obj = $this->db->fetch_object($resql)) {
3598 $this->nb[
"proposals"] = $obj->nb;
3600 $this->db->free($resql);
3604 $this->error = $this->db->error();
3619 global $conf, $langs;
3620 $langs->load(
"propal");
3624 if (!empty($classname)) {
3627 $file = $classname.
".php";
3630 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
3631 foreach ($dirmodels as $reldir) {
3635 $mybool = ((bool) @include_once $dir.$file) || $mybool;
3643 $obj =
new $classname();
3645 $numref = $obj->getNextValue($soc, $this);
3647 if ($numref !=
"") {
3650 $this->error = $obj->error;
3655 $langs->load(
"errors");
3656 print $langs->trans(
"Error").
" ".$langs->trans(
"ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv(
"Proposal"));
3669 global $conf, $langs, $user;
3671 $langs->load(
'propal');
3673 $nofetch = !empty($params[
'nofetch']);
3676 return [
'optimize' => $langs->trans(
"Proposal")];
3678 if ($user->hasRight(
'propal',
'lire')) {
3679 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Proposal").
'</u>';
3680 if (isset($this->
status)) {
3681 $datas[
'status'] =
' '.$this->getLibStatut(5);
3683 if (!empty($this->
ref)) {
3684 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
3687 $langs->load(
'companies');
3688 if (empty($this->thirdparty)) {
3691 $datas[
'customer'] =
'<br><b>'.$langs->trans(
'Customer').
':</b> '.$this->thirdparty->getNomUrl(1,
'', 0, 1);
3693 if (!empty($this->ref_customer)) {
3694 $datas[
'refcustomer'] =
'<br><b>'.$langs->trans(
'RefCustomer').
':</b> '.$this->ref_customer;
3697 $langs->load(
'project');
3698 if (is_null($this->project) || (is_object($this->project) && $this->project->isEmpty())) {
3700 if ($res > 0 && $this->project instanceof
Project) {
3701 $datas[
'project'] =
'<br><b>'.$langs->trans(
'Project').
':</b> '.$this->project->getNomUrl(1,
'', 0, 1);
3705 if (!empty($this->total_ht)) {
3706 $datas[
'amountht'] =
'<br><b>'.$langs->trans(
'AmountHT').
':</b> '.
price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
3708 if (!empty($this->total_tva)) {
3709 $datas[
'vat'] =
'<br><b>'.$langs->trans(
'VAT').
':</b> '.
price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
3711 if (!empty($this->total_ttc)) {
3712 $datas[
'amountttc'] =
'<br><b>'.$langs->trans(
'AmountTTC').
':</b> '.
price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
3714 if (!empty($this->date)) {
3715 $datas[
'date'] =
'<br><b>'.$langs->trans(
'Date').
':</b> '.
dol_print_date($this->date,
'day');
3717 if (!empty($this->delivery_date)) {
3718 $datas[
'deliverydate'] =
'<br><b>'.$langs->trans(
'DeliveryDate').
':</b> '.
dol_print_date($this->delivery_date,
'dayhour');
3736 public function getNomUrl($withpicto = 0, $option =
'', $get_params =
'', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = -1)
3738 global $langs, $conf, $user, $hookmanager;
3740 if (!empty($conf->dol_no_mouse_hover)) {
3747 'objecttype' => $this->element,
3748 'option' => $option,
3751 $classfortooltip =
'classfortooltip';
3754 $classfortooltip =
'classforajaxtooltip';
3755 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
3762 if ($user->hasRight(
'propal',
'lire')) {
3763 if ($option ==
'') {
3764 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3765 } elseif ($option ==
'compta') {
3766 $url = DOL_URL_ROOT.
'/comm/propal/card.php?id='.$this->
id.$get_params;
3767 } elseif ($option ==
'expedition') {
3768 $url = DOL_URL_ROOT.
'/expedition/propal.php?id='.$this->
id.$get_params;
3769 } elseif ($option ==
'document') {
3770 $url = DOL_URL_ROOT.
'/comm/propal/document.php?id='.$this->
id.$get_params;
3773 if ($option !=
'nolink') {
3775 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
3776 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
3777 $add_save_lastsearch_values = 1;
3779 if ($add_save_lastsearch_values) {
3780 $url .=
'&save_lastsearch_values=1';
3786 if (empty($notooltip) && $user->hasRight(
'propal',
'lire')) {
3788 $label = $langs->trans(
"Proposal");
3789 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
3791 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
3792 $linkclose .= $dataparams.
' class="'.$classfortooltip.
'"';
3795 $linkstart =
'<a href="'.$url.
'"';
3796 $linkstart .= $linkclose.
'>';
3799 $result .= $linkstart;
3801 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
3803 if ($withpicto != 2) {
3804 $result .= $this->ref;
3806 $result .= $linkend;
3808 if ($addlinktonotes >= 0) {
3811 if ($addlinktonotes == 0) {
3812 if (!empty($this->note_private) || !empty($this->note_public)) {
3813 $txttoshow = $langs->trans(
'ViewPrivateNote');
3815 } elseif ($addlinktonotes == 1) {
3816 if (!empty($this->note_private)) {
3819 } elseif ($addlinktonotes == 2) {
3820 if (!empty($this->note_public)) {
3823 } elseif ($addlinktonotes == 3) {
3824 if ($user->socid > 0) {
3825 if (!empty($this->note_public)) {
3829 if (!empty($this->note_public)) {
3832 if (!empty($this->note_private)) {
3833 if (!empty($txttoshow)) {
3834 $txttoshow .=
'<br><br>';
3842 $result .=
' <span class="note inline-block">';
3843 $result .=
'<a href="'.DOL_URL_ROOT.
'/comm/propal/note.php?id='.$this->
id.
'" class="classfortooltip" title="'.
dol_escape_htmltag($txttoshow).
'">';
3846 $result .=
'</span>';
3851 $hookmanager->initHooks(array($this->element .
'dao'));
3852 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
3853 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
3855 $result = $hookmanager->resPrint;
3857 $result .= $hookmanager->resPrint;
3870 return $this->
fetch_lines(0, 0, $sqlforgedfilters);
3884 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3886 global $conf, $langs;
3888 $langs->load(
"propale");
3889 $outputlangs->load(
"products");
3894 if ($this->model_pdf) {
3895 $modele = $this->model_pdf;
3901 $modelpath =
"core/modules/propale/doc/";
3903 return $this->
commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3951 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
3953 $return =
'<div class="box-flex-item box-flex-grow-zero">';
3954 $return .=
'<div class="info-box info-box-sm">';
3955 $return .=
'<div class="info-box-icon bg-infobox-action">';
3957 $return .=
'</div>';
3958 $return .=
'<div class="info-box-content">';
3959 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->
getNomUrl() : $this->ref).
'</span>';
3960 if ($selected >= 0) {
3961 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
3963 if (!empty($arraydata[
'projectlink'])) {
3964 $return .=
'<span class="info-box-ref"> | '.$arraydata[
'projectlink'].
'</span>';
3967 if (property_exists($this,
'thirdparty') && is_object($this->thirdparty)) {
3968 $return .=
'<div class="info-box-ref tdoverflowmax150">'.$this->thirdparty->getNomUrl(1).
'</div>';
3970 if (property_exists($this,
'total_ht')) {
3971 $return .=
'<span class="info-box-label amount" title="'.$langs->trans(
"AmountHT").
'">'.
price($this->total_ht).
'</span>';
3973 if (!empty($arraydata[
'authorlink'])) {
3974 $return .=
' <span class="info-box-label">'.$arraydata[
'authorlink'].
'</span>';
3976 if (method_exists($this,
'getLibStatut')) {
3977 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
3979 $return .=
'</div>';
3980 $return .=
'</div>';
3981 $return .=
'</div>';
3994 public $element =
'propaldet';
3999 public $table_element =
'propaldet';
4015 public $fk_parent_line;
4033 public $vat_src_code;
4040 public $remise_percent;
4041 public $fk_remise_except;
4045 public $fk_fournprice;
4056 public $special_code;
4058 public $info_bits = 0;
4087 public $product_ref;
4102 public $product_label;
4107 public $product_desc;
4113 public $product_tobatch;
4119 public $product_barcode;
4121 public $localtax1_tx;
4122 public $localtax2_tx;
4123 public $localtax1_type;
4124 public $localtax2_type;
4125 public $total_localtax1;
4126 public $total_localtax2;
4131 public $skip_update_total;
4134 public $fk_multicurrency;
4135 public $multicurrency_code;
4136 public $multicurrency_subprice;
4137 public $multicurrency_total_ht;
4138 public $multicurrency_total_tva;
4139 public $multicurrency_total_ttc;
4160 $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,';
4161 $sql .=
' pd.remise, pd.remise_percent, pd.fk_remise_except, pd.subprice,';
4162 $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,';
4163 $sql .=
' pd.fk_unit,';
4164 $sql .=
' pd.localtax1_tx, pd.localtax2_tx, pd.total_localtax1, pd.total_localtax2,';
4165 $sql .=
' pd.fk_multicurrency, pd.multicurrency_code, pd.multicurrency_subprice, pd.multicurrency_total_ht, pd.multicurrency_total_tva, pd.multicurrency_total_ttc,';
4166 $sql .=
' p.ref as product_ref, p.label as product_label, p.description as product_desc,';
4167 $sql .=
' pd.date_start, pd.date_end, pd.product_type';
4168 $sql .=
' FROM '.MAIN_DB_PREFIX.
'propaldet as pd';
4169 $sql .=
' LEFT JOIN '.MAIN_DB_PREFIX.
'product as p ON pd.fk_product = p.rowid';
4170 $sql .=
' WHERE pd.rowid = '.((int) $rowid);
4172 $result = $this->db->query($sql);
4174 $objp = $this->db->fetch_object($result);
4177 $this->
id = $objp->rowid;
4178 $this->
rowid = $objp->rowid;
4179 $this->fk_propal = $objp->fk_propal;
4180 $this->fk_parent_line = $objp->fk_parent_line;
4181 $this->label = $objp->custom_label;
4182 $this->desc = $objp->description;
4183 $this->qty = $objp->qty;
4184 $this->
price = $objp->price;
4185 $this->subprice = $objp->subprice;
4186 $this->vat_src_code = $objp->vat_src_code;
4187 $this->tva_tx = $objp->tva_tx;
4188 $this->remise = $objp->remise;
4189 $this->remise_percent = $objp->remise_percent;
4190 $this->fk_remise_except = $objp->fk_remise_except;
4191 $this->fk_product = $objp->fk_product;
4192 $this->info_bits = $objp->info_bits;
4194 $this->total_ht = $objp->total_ht;
4195 $this->total_tva = $objp->total_tva;
4196 $this->total_ttc = $objp->total_ttc;
4198 $this->fk_fournprice = $objp->fk_fournprice;
4200 $marginInfos =
getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $this->fk_fournprice, $objp->pa_ht);
4201 $this->pa_ht = $marginInfos[0];
4202 $this->marge_tx = $marginInfos[1];
4203 $this->marque_tx = $marginInfos[2];
4205 $this->special_code = $objp->special_code;
4206 $this->product_type = $objp->product_type;
4207 $this->rang = $objp->rang;
4209 $this->
ref = $objp->product_ref;
4210 $this->product_ref = $objp->product_ref;
4211 $this->libelle = $objp->product_label;
4212 $this->product_label = $objp->product_label;
4213 $this->product_desc = $objp->product_desc;
4214 $this->fk_unit = $objp->fk_unit;
4216 $this->date_start = $this->db->jdate($objp->date_start);
4217 $this->date_end = $this->db->jdate($objp->date_end);
4220 $this->fk_multicurrency = $objp->fk_multicurrency;
4221 $this->multicurrency_code = $objp->multicurrency_code;
4222 $this->multicurrency_subprice = $objp->multicurrency_subprice;
4223 $this->multicurrency_total_ht = $objp->multicurrency_total_ht;
4224 $this->multicurrency_total_tva = $objp->multicurrency_total_tva;
4225 $this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
4229 $this->db->free($result);
4248 global $conf, $user;
4252 dol_syslog(get_class($this).
"::insert rang=".$this->rang);
4254 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4257 if (empty($this->tva_tx)) {
4260 if (empty($this->localtax1_tx)) {
4261 $this->localtax1_tx = 0;
4263 if (empty($this->localtax2_tx)) {
4264 $this->localtax2_tx = 0;
4266 if (empty($this->localtax1_type)) {
4267 $this->localtax1_type = 0;
4269 if (empty($this->localtax2_type)) {
4270 $this->localtax2_type = 0;
4272 if (empty($this->total_localtax1)) {
4273 $this->total_localtax1 = 0;
4275 if (empty($this->total_localtax2)) {
4276 $this->total_localtax2 = 0;
4278 if (empty($this->rang)) {
4281 if (empty($this->remise_percent) || !is_numeric($this->remise_percent)) {
4282 $this->remise_percent = 0;
4284 if (empty($this->info_bits)) {
4285 $this->info_bits = 0;
4287 if (empty($this->special_code)) {
4288 $this->special_code = 0;
4290 if (empty($this->fk_parent_line)) {
4291 $this->fk_parent_line = 0;
4293 if (empty($this->fk_fournprice)) {
4294 $this->fk_fournprice = 0;
4296 if (!is_numeric($this->qty)) {
4299 if (empty($this->pa_ht)) {
4302 if (empty($this->multicurrency_subprice)) {
4303 $this->multicurrency_subprice = 0;
4305 if (empty($this->multicurrency_total_ht)) {
4306 $this->multicurrency_total_ht = 0;
4308 if (empty($this->multicurrency_total_tva)) {
4309 $this->multicurrency_total_tva = 0;
4311 if (empty($this->multicurrency_total_ttc)) {
4312 $this->multicurrency_total_ttc = 0;
4316 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4317 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4320 $this->pa_ht = $result;
4325 if ($this->product_type < 0) {
4332 $sql =
'INSERT INTO '.MAIN_DB_PREFIX.
'propaldet';
4333 $sql .=
' (fk_propal, fk_parent_line, label, description, fk_product, product_type,';
4334 $sql .=
' fk_remise_except, qty, vat_src_code, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type,';
4335 $sql .=
' subprice, remise_percent, ';
4336 $sql .=
' info_bits, ';
4337 $sql .=
' total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_product_fournisseur_price, buy_price_ht, special_code, rang,';
4338 $sql .=
' fk_unit,';
4339 $sql .=
' date_start, date_end';
4340 $sql .=
', fk_multicurrency, multicurrency_code, multicurrency_subprice, multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc)';
4341 $sql .=
" VALUES (".$this->fk_propal.
",";
4342 $sql .=
" ".($this->fk_parent_line > 0 ?
"'".$this->db->escape($this->fk_parent_line).
"'" :
"null").
",";
4343 $sql .=
" ".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null").
",";
4344 $sql .=
" '".$this->db->escape($this->desc).
"',";
4345 $sql .=
" ".($this->fk_product ?
"'".$this->db->escape($this->fk_product).
"'" :
"null").
",";
4346 $sql .=
" '".$this->db->escape($this->product_type).
"',";
4347 $sql .=
" ".($this->fk_remise_except ?
"'".$this->db->escape($this->fk_remise_except).
"'" :
"null").
",";
4348 $sql .=
" ".price2num($this->qty,
'MS').
",";
4349 $sql .=
" ".(empty($this->vat_src_code) ?
"''" :
"'".$this->db->escape($this->vat_src_code).
"'").
",";
4350 $sql .=
" ".price2num($this->tva_tx).
",";
4351 $sql .=
" ".price2num($this->localtax1_tx).
",";
4352 $sql .=
" ".price2num($this->localtax2_tx).
",";
4353 $sql .=
" '".$this->db->escape($this->localtax1_type).
"',";
4354 $sql .=
" '".$this->db->escape($this->localtax2_type).
"',";
4355 $sql .=
" ".(price2num($this->subprice) !==
'' ?
price2num($this->subprice,
'MU') :
"null").
",";
4356 $sql .=
" ".price2num($this->remise_percent).
",";
4357 $sql .=
" ".(isset($this->info_bits) ? ((int) $this->info_bits) :
"null").
",";
4358 $sql .=
" ".price2num($this->total_ht,
'MT').
",";
4359 $sql .=
" ".price2num($this->total_tva,
'MT').
",";
4360 $sql .=
" ".price2num($this->total_localtax1,
'MT').
",";
4361 $sql .=
" ".price2num($this->total_localtax2,
'MT').
",";
4362 $sql .=
" ".price2num($this->total_ttc,
'MT').
",";
4363 $sql .=
" ".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null").
",";
4364 $sql .=
" ".(isset($this->pa_ht) ?
"'".price2num($this->pa_ht).
"'" :
"null").
",";
4365 $sql .=
' '.((int) $this->special_code).
',';
4366 $sql .=
' '.((int) $this->rang).
',';
4367 $sql .=
' '.(empty($this->fk_unit) ?
'NULL' : ((int) $this->fk_unit)).
',';
4368 $sql .=
" ".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null").
',';
4369 $sql .=
" ".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4370 $sql .=
", ".($this->fk_multicurrency > 0 ? ((int) $this->fk_multicurrency) :
'null');
4371 $sql .=
", '".$this->db->escape($this->multicurrency_code).
"'";
4372 $sql .=
", ".price2num($this->multicurrency_subprice,
'CU');
4373 $sql .=
", ".price2num($this->multicurrency_total_ht,
'CT');
4374 $sql .=
", ".price2num($this->multicurrency_total_tva,
'CT');
4375 $sql .=
", ".price2num($this->multicurrency_total_ttc,
'CT');
4378 dol_syslog(get_class($this).
'::insert', LOG_DEBUG);
4379 $resql = $this->db->query($sql);
4381 $this->
rowid = $this->db->last_insert_id(MAIN_DB_PREFIX.
'propaldet');
4384 $this->
id = $this->rowid;
4391 if (!$error && !$notrigger) {
4393 $result = $this->
call_trigger(
'LINEPROPAL_INSERT', $user);
4395 $this->db->rollback();
4401 $this->db->commit();
4404 $this->error = $this->db->error().
" sql=".$sql;
4405 $this->db->rollback();
4417 public function delete(
User $user, $notrigger = 0)
4426 $result = $this->
call_trigger(
'LINEPROPAL_DELETE', $user);
4434 $sql =
"DELETE FROM " . MAIN_DB_PREFIX .
"propaldet WHERE rowid = " . ((int) $this->
rowid);
4435 dol_syslog(
"PropaleLigne::delete", LOG_DEBUG);
4436 if ($this->db->query($sql)) {
4439 $this->
id = $this->rowid;
4443 dol_syslog(get_class($this) .
"::delete error -4 " . $this->error, LOG_ERR);
4447 $this->error = $this->db->error() .
" sql=" . $sql;
4453 $this->db->rollback();
4456 $this->db->commit();
4469 global $conf, $user;
4473 $pa_ht_isemptystring = (empty($this->pa_ht) && $this->pa_ht ==
'');
4475 if (empty($this->
id) && !empty($this->
rowid)) {
4476 $this->
id = $this->rowid;
4480 if (empty($this->tva_tx)) {
4483 if (empty($this->localtax1_tx)) {
4484 $this->localtax1_tx = 0;
4486 if (empty($this->localtax2_tx)) {
4487 $this->localtax2_tx = 0;
4489 if (empty($this->total_localtax1)) {
4490 $this->total_localtax1 = 0;
4492 if (empty($this->total_localtax2)) {
4493 $this->total_localtax2 = 0;
4495 if (empty($this->localtax1_type)) {
4496 $this->localtax1_type = 0;
4498 if (empty($this->localtax2_type)) {
4499 $this->localtax2_type = 0;
4501 if (empty($this->marque_tx)) {
4502 $this->marque_tx = 0;
4504 if (empty($this->marge_tx)) {
4505 $this->marge_tx = 0;
4507 if (empty($this->
price)) {
4510 if (empty($this->remise_percent)) {
4511 $this->remise_percent = 0;
4513 if (empty($this->info_bits)) {
4514 $this->info_bits = 0;
4516 if (empty($this->special_code)) {
4517 $this->special_code = 0;
4519 if (empty($this->fk_parent_line)) {
4520 $this->fk_parent_line = 0;
4522 if (empty($this->fk_fournprice)) {
4523 $this->fk_fournprice = 0;
4525 if (empty($this->subprice)) {
4526 $this->subprice = 0;
4528 if (empty($this->pa_ht)) {
4533 if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
4534 if (($result = $this->
defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) {
4537 $this->pa_ht = $result;
4544 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4545 $sql .=
" description='".$this->db->escape($this->desc).
"'";
4546 $sql .=
", label=".(!empty($this->label) ?
"'".$this->db->escape($this->label).
"'" :
"null");
4547 $sql .=
", product_type=".$this->product_type;
4548 $sql .=
", vat_src_code = '".(empty($this->vat_src_code) ?
'' : $this->vat_src_code).
"'";
4549 $sql .=
", tva_tx='".price2num($this->tva_tx).
"'";
4550 $sql .=
", localtax1_tx=".price2num($this->localtax1_tx);
4551 $sql .=
", localtax2_tx=".price2num($this->localtax2_tx);
4552 $sql .=
", localtax1_type='".$this->db->escape($this->localtax1_type).
"'";
4553 $sql .=
", localtax2_type='".$this->db->escape($this->localtax2_type).
"'";
4554 $sql .=
", qty='".price2num($this->qty).
"'";
4555 $sql .=
", subprice=".price2num($this->subprice);
4556 $sql .=
", remise_percent=".price2num($this->remise_percent);
4558 $sql .=
", remise=".(float)
price2num($this->remise);
4559 $sql .=
", info_bits='".$this->db->escape($this->info_bits).
"'";
4560 if (empty($this->skip_update_total)) {
4561 $sql .=
", total_ht=".price2num($this->total_ht);
4562 $sql .=
", total_tva=".price2num($this->total_tva);
4563 $sql .=
", total_ttc=".price2num($this->total_ttc);
4564 $sql .=
", total_localtax1=".price2num($this->total_localtax1);
4565 $sql .=
", total_localtax2=".price2num($this->total_localtax2);
4567 $sql .=
", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ?
"'".$this->db->escape($this->fk_fournprice).
"'" :
"null");
4568 $sql .=
", buy_price_ht=".price2num($this->pa_ht);
4569 $sql .=
", special_code=".((int) $this->special_code);
4570 $sql .=
", fk_parent_line=".($this->fk_parent_line > 0 ? (int) $this->fk_parent_line :
"null");
4571 if (!empty($this->rang)) {
4572 $sql .=
", rang=".((int) $this->rang);
4574 $sql .=
", date_start=".(!empty($this->date_start) ?
"'".$this->db->idate($this->date_start).
"'" :
"null");
4575 $sql .=
", date_end=".(!empty($this->date_end) ?
"'".$this->db->idate($this->date_end).
"'" :
"null");
4576 $sql .=
", fk_unit=".(!$this->fk_unit ?
'NULL' : $this->fk_unit);
4579 $sql .=
", multicurrency_subprice=".price2num($this->multicurrency_subprice);
4580 $sql .=
", multicurrency_total_ht=".price2num($this->multicurrency_total_ht);
4581 $sql .=
", multicurrency_total_tva=".price2num($this->multicurrency_total_tva);
4582 $sql .=
", multicurrency_total_ttc=".price2num($this->multicurrency_total_ttc);
4584 $sql .=
" WHERE rowid = ".((int) $this->
id);
4586 dol_syslog(get_class($this).
"::update", LOG_DEBUG);
4587 $resql = $this->db->query($sql);
4596 if (!$error && !$notrigger) {
4598 $result = $this->
call_trigger(
'LINEPROPAL_MODIFY', $user);
4600 $this->db->rollback();
4606 $this->db->commit();
4609 $this->error = $this->db->error();
4610 $this->db->rollback();
4628 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"propaldet SET";
4629 $sql .=
" total_ht=".price2num($this->total_ht,
'MT');
4630 $sql .=
",total_tva=".price2num($this->total_tva,
'MT');
4631 $sql .=
",total_ttc=".price2num($this->total_ttc,
'MT');
4632 $sql .=
" WHERE rowid = ".((int) $this->
rowid);
4634 dol_syslog(
"PropaleLigne::update_total", LOG_DEBUG);
4636 $resql = $this->db->query($sql);
4638 $this->db->commit();
4641 $this->error = $this->db->error();
4642 $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 '.
isDolTms($timestamp)
isDolTms check if a timestamp is valid.
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