|
@@ -776,1897 +776,1897 @@ class SupplierProposal extends CommonObject
|
|
|
$this->line->multicurrency_total_tva = $multicurrency_total_tva;
|
|
|
$this->line->multicurrency_total_ttc = $multicurrency_total_ttc;
|
|
|
|
|
|
- $result = $this->line->update();
|
|
|
- if ($result > 0)
|
|
|
- {
|
|
|
- // Reorder if child line
|
|
|
- if (!empty($fk_parent_line)) $this->line_order(true, 'DESC');
|
|
|
-
|
|
|
- $this->update_price(1);
|
|
|
-
|
|
|
- $this->fk_supplier_proposal = $this->id;
|
|
|
-
|
|
|
- $this->db->commit();
|
|
|
- return $result;
|
|
|
- } else {
|
|
|
- $this->error = $this->db->error();
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- } else {
|
|
|
- dol_syslog(get_class($this)."::updateline Erreur -2 SupplierProposal en mode incompatible pour cette action");
|
|
|
- return -2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Delete detail line
|
|
|
- *
|
|
|
- * @param int $lineid Id of line to delete
|
|
|
- * @return int >0 if OK, <0 if KO
|
|
|
- */
|
|
|
- public function deleteline($lineid)
|
|
|
- {
|
|
|
- if ($this->statut == 0)
|
|
|
- {
|
|
|
- $line = new SupplierProposalLine($this->db);
|
|
|
-
|
|
|
- // For triggers
|
|
|
- $line->fetch($lineid);
|
|
|
-
|
|
|
- if ($line->delete() > 0)
|
|
|
- {
|
|
|
- $this->update_price(1);
|
|
|
-
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- } else {
|
|
|
- return -2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Create commercial proposal into database
|
|
|
- * this->ref can be set or empty. If empty, we will use "(PROVid)"
|
|
|
- *
|
|
|
- * @param User $user User that create
|
|
|
- * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
|
- * @return int <0 if KO, >=0 if OK
|
|
|
- */
|
|
|
- public function create($user, $notrigger = 0)
|
|
|
- {
|
|
|
- global $langs, $conf, $mysoc, $hookmanager;
|
|
|
- $error = 0;
|
|
|
-
|
|
|
- $now = dol_now();
|
|
|
-
|
|
|
- dol_syslog(get_class($this)."::create");
|
|
|
-
|
|
|
- // Check parameters
|
|
|
- $result = $this->fetch_thirdparty();
|
|
|
- if ($result < 0)
|
|
|
- {
|
|
|
- $this->error = "Failed to fetch company";
|
|
|
- dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
|
|
|
- return -3;
|
|
|
- }
|
|
|
-
|
|
|
- // Check parameters
|
|
|
- if (!empty($this->ref)) // We check that ref is not already used
|
|
|
- {
|
|
|
- $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
|
|
|
- if ($result > 0)
|
|
|
- {
|
|
|
- $this->error = 'ErrorRefAlreadyExists';
|
|
|
- dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Multicurrency
|
|
|
- if (!empty($this->multicurrency_code)) list($this->fk_multicurrency, $this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $now);
|
|
|
- if (empty($this->fk_multicurrency))
|
|
|
- {
|
|
|
- $this->multicurrency_code = $conf->currency;
|
|
|
- $this->fk_multicurrency = 0;
|
|
|
- $this->multicurrency_tx = 1;
|
|
|
- }
|
|
|
-
|
|
|
- $this->db->begin();
|
|
|
-
|
|
|
- // Insert into database
|
|
|
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."supplier_proposal (";
|
|
|
- $sql .= "fk_soc";
|
|
|
- $sql .= ", price";
|
|
|
- $sql .= ", remise";
|
|
|
- $sql .= ", remise_percent";
|
|
|
- $sql .= ", remise_absolue";
|
|
|
- $sql .= ", tva";
|
|
|
- $sql .= ", total";
|
|
|
- $sql .= ", datec";
|
|
|
- $sql .= ", ref";
|
|
|
- $sql .= ", fk_user_author";
|
|
|
- $sql .= ", note_private";
|
|
|
- $sql .= ", note_public";
|
|
|
- $sql .= ", model_pdf";
|
|
|
- $sql .= ", fk_cond_reglement";
|
|
|
- $sql .= ", fk_mode_reglement";
|
|
|
- $sql .= ", fk_account";
|
|
|
- $sql .= ", date_livraison";
|
|
|
- $sql .= ", fk_shipping_method";
|
|
|
- $sql .= ", fk_projet";
|
|
|
- $sql .= ", entity";
|
|
|
- $sql .= ", fk_multicurrency";
|
|
|
- $sql .= ", multicurrency_code";
|
|
|
- $sql .= ", multicurrency_tx";
|
|
|
- $sql .= ") ";
|
|
|
- $sql .= " VALUES (";
|
|
|
- $sql .= $this->socid;
|
|
|
- $sql .= ", 0";
|
|
|
- $sql .= ", ".$this->remise;
|
|
|
- $sql .= ", ".($this->remise_percent ? $this->db->escape($this->remise_percent) : 'null');
|
|
|
- $sql .= ", ".($this->remise_absolue ? $this->db->escape($this->remise_absolue) : 'null');
|
|
|
- $sql .= ", 0";
|
|
|
- $sql .= ", 0";
|
|
|
- $sql .= ", '".$this->db->idate($now)."'";
|
|
|
- $sql .= ", '(PROV)'";
|
|
|
- $sql .= ", ".($user->id > 0 ? "'".$user->id."'" : "null");
|
|
|
- $sql .= ", '".$this->db->escape($this->note_private)."'";
|
|
|
- $sql .= ", '".$this->db->escape($this->note_public)."'";
|
|
|
- $sql .= ", '".$this->db->escape($this->modelpdf)."'";
|
|
|
- $sql .= ", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id : 'NULL');
|
|
|
- $sql .= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id : 'NULL');
|
|
|
- $sql .= ", ".($this->fk_account > 0 ? $this->fk_account : 'NULL');
|
|
|
- $sql .= ", ".($this->date_livraison != '' ? "'".$this->db->idate($this->date_livraison)."'" : "null");
|
|
|
- $sql .= ", ".($this->shipping_method_id > 0 ? $this->shipping_method_id : 'NULL');
|
|
|
- $sql .= ", ".($this->fk_project ? $this->fk_project : "null");
|
|
|
- $sql .= ", ".$conf->entity;
|
|
|
- $sql .= ", ".(int) $this->fk_multicurrency;
|
|
|
- $sql .= ", '".$this->db->escape($this->multicurrency_code)."'";
|
|
|
- $sql .= ", ".(double) $this->multicurrency_tx;
|
|
|
- $sql .= ")";
|
|
|
-
|
|
|
- dol_syslog(get_class($this)."::create", LOG_DEBUG);
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if ($resql)
|
|
|
- {
|
|
|
- $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."supplier_proposal");
|
|
|
-
|
|
|
- if ($this->id)
|
|
|
- {
|
|
|
- $this->ref = '(PROV'.$this->id.')';
|
|
|
- $sql = 'UPDATE '.MAIN_DB_PREFIX."supplier_proposal SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".$this->id;
|
|
|
-
|
|
|
- dol_syslog(get_class($this)."::create", LOG_DEBUG);
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if (!$resql) $error++;
|
|
|
-
|
|
|
- if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) // To use new linkedObjectsIds instead of old linked_objects
|
|
|
- {
|
|
|
- $this->linked_objects = $this->linkedObjectsIds; // TODO Replace linked_objects with linkedObjectsIds
|
|
|
- }
|
|
|
-
|
|
|
- // Add object linked
|
|
|
- if (!$error && $this->id && is_array($this->linked_objects) && !empty($this->linked_objects))
|
|
|
- {
|
|
|
- foreach ($this->linked_objects as $origin => $tmp_origin_id)
|
|
|
- {
|
|
|
- if (is_array($tmp_origin_id)) // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
|
|
|
- {
|
|
|
- foreach ($tmp_origin_id as $origin_id)
|
|
|
- {
|
|
|
- $ret = $this->add_object_linked($origin, $origin_id);
|
|
|
- if (!$ret)
|
|
|
- {
|
|
|
- dol_print_error($this->db);
|
|
|
- $error++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /*
|
|
|
+ $result = $this->line->update();
|
|
|
+ if ($result > 0)
|
|
|
+ {
|
|
|
+ // Reorder if child line
|
|
|
+ if (!empty($fk_parent_line)) $this->line_order(true, 'DESC');
|
|
|
+
|
|
|
+ $this->update_price(1);
|
|
|
+
|
|
|
+ $this->fk_supplier_proposal = $this->id;
|
|
|
+
|
|
|
+ $this->db->commit();
|
|
|
+ return $result;
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ dol_syslog(get_class($this)."::updateline Erreur -2 SupplierProposal en mode incompatible pour cette action");
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Delete detail line
|
|
|
+ *
|
|
|
+ * @param int $lineid Id of line to delete
|
|
|
+ * @return int >0 if OK, <0 if KO
|
|
|
+ */
|
|
|
+ public function deleteline($lineid)
|
|
|
+ {
|
|
|
+ if ($this->statut == 0)
|
|
|
+ {
|
|
|
+ $line = new SupplierProposalLine($this->db);
|
|
|
+
|
|
|
+ // For triggers
|
|
|
+ $line->fetch($lineid);
|
|
|
+
|
|
|
+ if ($line->delete() > 0)
|
|
|
+ {
|
|
|
+ $this->update_price(1);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create commercial proposal into database
|
|
|
+ * this->ref can be set or empty. If empty, we will use "(PROVid)"
|
|
|
+ *
|
|
|
+ * @param User $user User that create
|
|
|
+ * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
|
+ * @return int <0 if KO, >=0 if OK
|
|
|
+ */
|
|
|
+ public function create($user, $notrigger = 0)
|
|
|
+ {
|
|
|
+ global $langs, $conf, $mysoc, $hookmanager;
|
|
|
+ $error = 0;
|
|
|
+
|
|
|
+ $now = dol_now();
|
|
|
+
|
|
|
+ dol_syslog(get_class($this)."::create");
|
|
|
+
|
|
|
+ // Check parameters
|
|
|
+ $result = $this->fetch_thirdparty();
|
|
|
+ if ($result < 0)
|
|
|
+ {
|
|
|
+ $this->error = "Failed to fetch company";
|
|
|
+ dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check parameters
|
|
|
+ if (!empty($this->ref)) // We check that ref is not already used
|
|
|
+ {
|
|
|
+ $result = self::isExistingObject($this->element, 0, $this->ref); // Check ref is not yet used
|
|
|
+ if ($result > 0)
|
|
|
+ {
|
|
|
+ $this->error = 'ErrorRefAlreadyExists';
|
|
|
+ dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING);
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Multicurrency
|
|
|
+ if (!empty($this->multicurrency_code)) list($this->fk_multicurrency, $this->multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $this->multicurrency_code, $now);
|
|
|
+ if (empty($this->fk_multicurrency))
|
|
|
+ {
|
|
|
+ $this->multicurrency_code = $conf->currency;
|
|
|
+ $this->fk_multicurrency = 0;
|
|
|
+ $this->multicurrency_tx = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->db->begin();
|
|
|
+
|
|
|
+ // Insert into database
|
|
|
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."supplier_proposal (";
|
|
|
+ $sql .= "fk_soc";
|
|
|
+ $sql .= ", price";
|
|
|
+ $sql .= ", remise";
|
|
|
+ $sql .= ", remise_percent";
|
|
|
+ $sql .= ", remise_absolue";
|
|
|
+ $sql .= ", tva";
|
|
|
+ $sql .= ", total";
|
|
|
+ $sql .= ", datec";
|
|
|
+ $sql .= ", ref";
|
|
|
+ $sql .= ", fk_user_author";
|
|
|
+ $sql .= ", note_private";
|
|
|
+ $sql .= ", note_public";
|
|
|
+ $sql .= ", model_pdf";
|
|
|
+ $sql .= ", fk_cond_reglement";
|
|
|
+ $sql .= ", fk_mode_reglement";
|
|
|
+ $sql .= ", fk_account";
|
|
|
+ $sql .= ", date_livraison";
|
|
|
+ $sql .= ", fk_shipping_method";
|
|
|
+ $sql .= ", fk_projet";
|
|
|
+ $sql .= ", entity";
|
|
|
+ $sql .= ", fk_multicurrency";
|
|
|
+ $sql .= ", multicurrency_code";
|
|
|
+ $sql .= ", multicurrency_tx";
|
|
|
+ $sql .= ") ";
|
|
|
+ $sql .= " VALUES (";
|
|
|
+ $sql .= $this->socid;
|
|
|
+ $sql .= ", 0";
|
|
|
+ $sql .= ", ".$this->remise;
|
|
|
+ $sql .= ", ".($this->remise_percent ? $this->db->escape($this->remise_percent) : 'null');
|
|
|
+ $sql .= ", ".($this->remise_absolue ? $this->db->escape($this->remise_absolue) : 'null');
|
|
|
+ $sql .= ", 0";
|
|
|
+ $sql .= ", 0";
|
|
|
+ $sql .= ", '".$this->db->idate($now)."'";
|
|
|
+ $sql .= ", '(PROV)'";
|
|
|
+ $sql .= ", ".($user->id > 0 ? "'".$user->id."'" : "null");
|
|
|
+ $sql .= ", '".$this->db->escape($this->note_private)."'";
|
|
|
+ $sql .= ", '".$this->db->escape($this->note_public)."'";
|
|
|
+ $sql .= ", '".$this->db->escape($this->modelpdf)."'";
|
|
|
+ $sql .= ", ".($this->cond_reglement_id > 0 ? $this->cond_reglement_id : 'NULL');
|
|
|
+ $sql .= ", ".($this->mode_reglement_id > 0 ? $this->mode_reglement_id : 'NULL');
|
|
|
+ $sql .= ", ".($this->fk_account > 0 ? $this->fk_account : 'NULL');
|
|
|
+ $sql .= ", ".($this->date_livraison != '' ? "'".$this->db->idate($this->date_livraison)."'" : "null");
|
|
|
+ $sql .= ", ".($this->shipping_method_id > 0 ? $this->shipping_method_id : 'NULL');
|
|
|
+ $sql .= ", ".($this->fk_project ? $this->fk_project : "null");
|
|
|
+ $sql .= ", ".$conf->entity;
|
|
|
+ $sql .= ", ".(int) $this->fk_multicurrency;
|
|
|
+ $sql .= ", '".$this->db->escape($this->multicurrency_code)."'";
|
|
|
+ $sql .= ", ".(double) $this->multicurrency_tx;
|
|
|
+ $sql .= ")";
|
|
|
+
|
|
|
+ dol_syslog(get_class($this)."::create", LOG_DEBUG);
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if ($resql)
|
|
|
+ {
|
|
|
+ $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."supplier_proposal");
|
|
|
+
|
|
|
+ if ($this->id)
|
|
|
+ {
|
|
|
+ $this->ref = '(PROV'.$this->id.')';
|
|
|
+ $sql = 'UPDATE '.MAIN_DB_PREFIX."supplier_proposal SET ref='".$this->db->escape($this->ref)."' WHERE rowid=".$this->id;
|
|
|
+
|
|
|
+ dol_syslog(get_class($this)."::create", LOG_DEBUG);
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if (!$resql) $error++;
|
|
|
+
|
|
|
+ if (!empty($this->linkedObjectsIds) && empty($this->linked_objects)) // To use new linkedObjectsIds instead of old linked_objects
|
|
|
+ {
|
|
|
+ $this->linked_objects = $this->linkedObjectsIds; // TODO Replace linked_objects with linkedObjectsIds
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add object linked
|
|
|
+ if (!$error && $this->id && is_array($this->linked_objects) && !empty($this->linked_objects))
|
|
|
+ {
|
|
|
+ foreach ($this->linked_objects as $origin => $tmp_origin_id)
|
|
|
+ {
|
|
|
+ if (is_array($tmp_origin_id)) // New behaviour, if linked_object can have several links per type, so is something like array('contract'=>array(id1, id2, ...))
|
|
|
+ {
|
|
|
+ foreach ($tmp_origin_id as $origin_id)
|
|
|
+ {
|
|
|
+ $ret = $this->add_object_linked($origin, $origin_id);
|
|
|
+ if (!$ret)
|
|
|
+ {
|
|
|
+ dol_print_error($this->db);
|
|
|
+ $error++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
* Insertion du detail des produits dans la base
|
|
|
*/
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- $fk_parent_line = 0;
|
|
|
- $num = count($this->lines);
|
|
|
-
|
|
|
- for ($i = 0; $i < $num; $i++)
|
|
|
- {
|
|
|
- // Reset fk_parent_line for no child products and special product
|
|
|
- if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) {
|
|
|
- $fk_parent_line = 0;
|
|
|
- }
|
|
|
-
|
|
|
- $result = $this->addline(
|
|
|
- $this->lines[$i]->desc,
|
|
|
- $this->lines[$i]->subprice,
|
|
|
- $this->lines[$i]->qty,
|
|
|
- $this->lines[$i]->tva_tx,
|
|
|
- $this->lines[$i]->localtax1_tx,
|
|
|
- $this->lines[$i]->localtax2_tx,
|
|
|
- $this->lines[$i]->fk_product,
|
|
|
- $this->lines[$i]->remise_percent,
|
|
|
- 'HT',
|
|
|
- 0,
|
|
|
- 0,
|
|
|
- $this->lines[$i]->product_type,
|
|
|
- $this->lines[$i]->rang,
|
|
|
- $this->lines[$i]->special_code,
|
|
|
- $fk_parent_line,
|
|
|
- $this->lines[$i]->fk_fournprice,
|
|
|
- $this->lines[$i]->pa_ht,
|
|
|
- $this->lines[$i]->label,
|
|
|
- $this->lines[$i]->array_options,
|
|
|
- $this->lines[$i]->ref_fourn,
|
|
|
- $this->lines[$i]->fk_unit,
|
|
|
- 'supplier_proposal',
|
|
|
- $this->lines[$i]->rowid
|
|
|
- );
|
|
|
-
|
|
|
- if ($result < 0)
|
|
|
- {
|
|
|
- $error++;
|
|
|
- $this->error = $this->db->error;
|
|
|
- dol_print_error($this->db);
|
|
|
- break;
|
|
|
- }
|
|
|
- // Defined the new fk_parent_line
|
|
|
- if ($result > 0 && $this->lines[$i]->product_type == 9) {
|
|
|
- $fk_parent_line = $result;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- // Mise a jour infos denormalisees
|
|
|
- $resql = $this->update_price(1);
|
|
|
- if ($resql)
|
|
|
- {
|
|
|
- $action = 'update';
|
|
|
-
|
|
|
- // Actions on extra fields
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- $result = $this->insertExtraFields();
|
|
|
- if ($result < 0)
|
|
|
- {
|
|
|
- $error++;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!$error && !$notrigger)
|
|
|
- {
|
|
|
- // Call trigger
|
|
|
- $result = $this->call_trigger('PROPOSAL_SUPPLIER_CREATE', $user);
|
|
|
- if ($result < 0) { $error++; }
|
|
|
- // End call triggers
|
|
|
- }
|
|
|
- } else {
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- $error++;
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- $error++;
|
|
|
- }
|
|
|
-
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- $this->db->commit();
|
|
|
- dol_syslog(get_class($this)."::create done id=".$this->id);
|
|
|
- return $this->id;
|
|
|
- } else {
|
|
|
- $this->db->rollback();
|
|
|
- return -2;
|
|
|
- }
|
|
|
- } else {
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Insert into DB a supplier_proposal object completely defined by its data members (ex, results from copy).
|
|
|
- *
|
|
|
- * @param User $user User that create
|
|
|
- * @return int Id of the new object if ok, <0 if ko
|
|
|
- * @see create()
|
|
|
- */
|
|
|
- public function create_from($user)
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
- $this->products = $this->lines;
|
|
|
-
|
|
|
- return $this->create($user);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Load an object from its id and create a new one in database
|
|
|
- *
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ $fk_parent_line = 0;
|
|
|
+ $num = count($this->lines);
|
|
|
+
|
|
|
+ for ($i = 0; $i < $num; $i++)
|
|
|
+ {
|
|
|
+ // Reset fk_parent_line for no child products and special product
|
|
|
+ if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) {
|
|
|
+ $fk_parent_line = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ $result = $this->addline(
|
|
|
+ $this->lines[$i]->desc,
|
|
|
+ $this->lines[$i]->subprice,
|
|
|
+ $this->lines[$i]->qty,
|
|
|
+ $this->lines[$i]->tva_tx,
|
|
|
+ $this->lines[$i]->localtax1_tx,
|
|
|
+ $this->lines[$i]->localtax2_tx,
|
|
|
+ $this->lines[$i]->fk_product,
|
|
|
+ $this->lines[$i]->remise_percent,
|
|
|
+ 'HT',
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ $this->lines[$i]->product_type,
|
|
|
+ $this->lines[$i]->rang,
|
|
|
+ $this->lines[$i]->special_code,
|
|
|
+ $fk_parent_line,
|
|
|
+ $this->lines[$i]->fk_fournprice,
|
|
|
+ $this->lines[$i]->pa_ht,
|
|
|
+ $this->lines[$i]->label,
|
|
|
+ $this->lines[$i]->array_options,
|
|
|
+ $this->lines[$i]->ref_fourn,
|
|
|
+ $this->lines[$i]->fk_unit,
|
|
|
+ 'supplier_proposal',
|
|
|
+ $this->lines[$i]->rowid
|
|
|
+ );
|
|
|
+
|
|
|
+ if ($result < 0)
|
|
|
+ {
|
|
|
+ $error++;
|
|
|
+ $this->error = $this->db->error;
|
|
|
+ dol_print_error($this->db);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ // Defined the new fk_parent_line
|
|
|
+ if ($result > 0 && $this->lines[$i]->product_type == 9) {
|
|
|
+ $fk_parent_line = $result;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ // Mise a jour infos denormalisees
|
|
|
+ $resql = $this->update_price(1);
|
|
|
+ if ($resql)
|
|
|
+ {
|
|
|
+ $action = 'update';
|
|
|
+
|
|
|
+ // Actions on extra fields
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ $result = $this->insertExtraFields();
|
|
|
+ if ($result < 0)
|
|
|
+ {
|
|
|
+ $error++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$error && !$notrigger)
|
|
|
+ {
|
|
|
+ // Call trigger
|
|
|
+ $result = $this->call_trigger('PROPOSAL_SUPPLIER_CREATE', $user);
|
|
|
+ if ($result < 0) { $error++; }
|
|
|
+ // End call triggers
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ $error++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ $error++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ $this->db->commit();
|
|
|
+ dol_syslog(get_class($this)."::create done id=".$this->id);
|
|
|
+ return $this->id;
|
|
|
+ } else {
|
|
|
+ $this->db->rollback();
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Insert into DB a supplier_proposal object completely defined by its data members (ex, results from copy).
|
|
|
+ *
|
|
|
+ * @param User $user User that create
|
|
|
+ * @return int Id of the new object if ok, <0 if ko
|
|
|
+ * @see create()
|
|
|
+ */
|
|
|
+ public function create_from($user)
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+ $this->products = $this->lines;
|
|
|
+
|
|
|
+ return $this->create($user);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Load an object from its id and create a new one in database
|
|
|
+ *
|
|
|
* @param User $user User making the clone
|
|
|
- * @param int $fromid Id of thirdparty
|
|
|
- * @return int New id of clone
|
|
|
- */
|
|
|
- public function createFromClone(User $user, $fromid = 0)
|
|
|
- {
|
|
|
- global $conf, $hookmanager;
|
|
|
-
|
|
|
- $error = 0;
|
|
|
- $now = dol_now();
|
|
|
-
|
|
|
- $this->db->begin();
|
|
|
-
|
|
|
- // get extrafields so they will be clone
|
|
|
- foreach ($this->lines as $line)
|
|
|
- $line->fetch_optionals();
|
|
|
-
|
|
|
- // Load source object
|
|
|
- $objFrom = clone $this;
|
|
|
-
|
|
|
- $objsoc = new Societe($this->db);
|
|
|
-
|
|
|
- // Change socid if needed
|
|
|
- if (!empty($fromid) && $fromid != $this->socid)
|
|
|
- {
|
|
|
- if ($objsoc->fetch($fromid) > 0)
|
|
|
- {
|
|
|
- $this->socid = $objsoc->id;
|
|
|
- $this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
|
|
|
- $this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
|
|
|
- $this->fk_project = '';
|
|
|
- }
|
|
|
-
|
|
|
- // TODO Change product price if multi-prices
|
|
|
- } else {
|
|
|
- $objsoc->fetch($this->socid);
|
|
|
- }
|
|
|
-
|
|
|
- $this->id = 0;
|
|
|
- $this->statut = 0;
|
|
|
-
|
|
|
- if (empty($conf->global->SUPPLIER_PROPOSAL_ADDON) || !is_readable(DOL_DOCUMENT_ROOT."/core/modules/supplier_proposal/".$conf->global->SUPPLIER_PROPOSAL_ADDON.".php"))
|
|
|
- {
|
|
|
- $this->error = 'ErrorSetupNotComplete';
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- // Clear fields
|
|
|
- $this->user_author = $user->id;
|
|
|
- $this->user_valid = '';
|
|
|
- $this->date = $now;
|
|
|
-
|
|
|
- // Set ref
|
|
|
- require_once DOL_DOCUMENT_ROOT."/core/modules/supplier_proposal/".$conf->global->SUPPLIER_PROPOSAL_ADDON.'.php';
|
|
|
- $obj = $conf->global->SUPPLIER_PROPOSAL_ADDON;
|
|
|
- $modSupplierProposal = new $obj;
|
|
|
- $this->ref = $modSupplierProposal->getNextValue($objsoc, $this);
|
|
|
-
|
|
|
- // Create clone
|
|
|
- $this->context['createfromclone'] = 'createfromclone';
|
|
|
- $result = $this->create($user);
|
|
|
- if ($result < 0) $error++;
|
|
|
-
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- // Hook of thirdparty module
|
|
|
- if (is_object($hookmanager))
|
|
|
- {
|
|
|
- $parameters = array('objFrom'=>$objFrom);
|
|
|
- $action = '';
|
|
|
- $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
|
|
|
- if ($reshook < 0) $error++;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- unset($this->context['createfromclone']);
|
|
|
-
|
|
|
- // End
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- $this->db->commit();
|
|
|
- return $this->id;
|
|
|
- } else {
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Load a proposal from database and its ligne array
|
|
|
- *
|
|
|
- * @param int $rowid id of object to load
|
|
|
- * @param string $ref Ref of proposal
|
|
|
- * @return int >0 if OK, <0 if KO
|
|
|
- */
|
|
|
- public function fetch($rowid, $ref = '')
|
|
|
- {
|
|
|
- global $conf;
|
|
|
-
|
|
|
- $sql = "SELECT p.rowid, p.entity, p.ref, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc";
|
|
|
- $sql .= ", p.total, p.tva, p.localtax1, p.localtax2, p.total_ht";
|
|
|
- $sql .= ", p.datec";
|
|
|
- $sql .= ", p.date_valid as datev";
|
|
|
- $sql .= ", p.date_livraison as date_livraison";
|
|
|
- $sql .= ", p.model_pdf, p.extraparams";
|
|
|
- $sql .= ", p.note_private, p.note_public";
|
|
|
- $sql .= ", p.fk_projet as fk_project, p.fk_statut";
|
|
|
- $sql .= ", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
|
|
|
- $sql .= ", p.fk_cond_reglement";
|
|
|
- $sql .= ", p.fk_mode_reglement";
|
|
|
- $sql .= ', p.fk_account';
|
|
|
- $sql .= ", p.fk_shipping_method";
|
|
|
- $sql .= ", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
|
|
|
- $sql .= ", c.label as statut_label";
|
|
|
- $sql .= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc";
|
|
|
- $sql .= ", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
|
|
|
- $sql .= " FROM ".MAIN_DB_PREFIX."c_propalst as c, ".MAIN_DB_PREFIX."supplier_proposal as p";
|
|
|
- $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_mode_reglement = cp.id';
|
|
|
- $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON p.fk_cond_reglement = cr.rowid';
|
|
|
- $sql .= " WHERE p.fk_statut = c.id";
|
|
|
- $sql .= " AND p.entity IN (".getEntity('supplier_proposal').")";
|
|
|
- if ($ref) $sql .= " AND p.ref='".$ref."'";
|
|
|
- else $sql .= " AND p.rowid=".$rowid;
|
|
|
-
|
|
|
- dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if ($resql)
|
|
|
- {
|
|
|
- if ($this->db->num_rows($resql))
|
|
|
- {
|
|
|
- $obj = $this->db->fetch_object($resql);
|
|
|
-
|
|
|
- $this->id = $obj->rowid;
|
|
|
- $this->entity = $obj->entity;
|
|
|
-
|
|
|
- $this->ref = $obj->ref;
|
|
|
- $this->remise = $obj->remise;
|
|
|
- $this->remise_percent = $obj->remise_percent;
|
|
|
- $this->remise_absolue = $obj->remise_absolue;
|
|
|
- $this->total = $obj->total; // TODO deprecated
|
|
|
- $this->total_ht = $obj->total_ht;
|
|
|
- $this->total_tva = $obj->tva;
|
|
|
- $this->total_localtax1 = $obj->localtax1;
|
|
|
- $this->total_localtax2 = $obj->localtax2;
|
|
|
- $this->total_ttc = $obj->total;
|
|
|
- $this->socid = $obj->fk_soc;
|
|
|
- $this->fk_project = $obj->fk_project;
|
|
|
- $this->model_pdf = $obj->model_pdf;
|
|
|
- $this->modelpdf = $obj->model_pdf;
|
|
|
- $this->note = $obj->note_private; // TODO deprecated
|
|
|
- $this->note_private = $obj->note_private;
|
|
|
- $this->note_public = $obj->note_public;
|
|
|
- $this->statut = (int) $obj->fk_statut;
|
|
|
- $this->statut_libelle = $obj->statut_label;
|
|
|
- $this->datec = $this->db->jdate($obj->datec); // TODO deprecated
|
|
|
- $this->datev = $this->db->jdate($obj->datev); // TODO deprecated
|
|
|
- $this->date_creation = $this->db->jdate($obj->datec); //Creation date
|
|
|
- $this->date_validation = $this->db->jdate($obj->datev); //Validation date
|
|
|
- $this->date_livraison = $this->db->jdate($obj->date_livraison);
|
|
|
- $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method : null;
|
|
|
-
|
|
|
- $this->mode_reglement_id = $obj->fk_mode_reglement;
|
|
|
- $this->mode_reglement_code = $obj->mode_reglement_code;
|
|
|
- $this->mode_reglement = $obj->mode_reglement;
|
|
|
- $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account : null;
|
|
|
- $this->cond_reglement_id = $obj->fk_cond_reglement;
|
|
|
- $this->cond_reglement_code = $obj->cond_reglement_code;
|
|
|
- $this->cond_reglement = $obj->cond_reglement;
|
|
|
- $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
|
|
|
-
|
|
|
- $this->extraparams = (array) json_decode($obj->extraparams, true);
|
|
|
-
|
|
|
- $this->user_author_id = $obj->fk_user_author;
|
|
|
- $this->user_valid_id = $obj->fk_user_valid;
|
|
|
- $this->user_close_id = $obj->fk_user_cloture;
|
|
|
-
|
|
|
- // Multicurrency
|
|
|
- $this->fk_multicurrency = $obj->fk_multicurrency;
|
|
|
- $this->multicurrency_code = $obj->multicurrency_code;
|
|
|
- $this->multicurrency_tx = $obj->multicurrency_tx;
|
|
|
- $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
|
|
|
- $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
|
|
|
- $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
|
|
|
-
|
|
|
- if ($obj->fk_statut == 0)
|
|
|
- {
|
|
|
- $this->brouillon = 1;
|
|
|
- }
|
|
|
-
|
|
|
- // Retreive all extrafield
|
|
|
- // fetch optionals attributes and labels
|
|
|
- $this->fetch_optionals();
|
|
|
-
|
|
|
- $this->db->free($resql);
|
|
|
-
|
|
|
- $this->lines = array();
|
|
|
-
|
|
|
- // Lines of supplier proposals
|
|
|
- $sql = "SELECT d.rowid, d.fk_supplier_proposal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,";
|
|
|
- $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,";
|
|
|
- $sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,';
|
|
|
- $sql .= ' d.ref_fourn as ref_produit_fourn,';
|
|
|
- $sql .= ' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc, d.fk_unit';
|
|
|
- $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposaldet as d";
|
|
|
- $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid";
|
|
|
- $sql .= " WHERE d.fk_supplier_proposal = ".$this->id;
|
|
|
- $sql .= " ORDER by d.rang";
|
|
|
-
|
|
|
- $result = $this->db->query($sql);
|
|
|
- if ($result)
|
|
|
- {
|
|
|
- $num = $this->db->num_rows($result);
|
|
|
- $i = 0;
|
|
|
-
|
|
|
- while ($i < $num)
|
|
|
- {
|
|
|
- $objp = $this->db->fetch_object($result);
|
|
|
-
|
|
|
- $line = new SupplierProposalLine($this->db);
|
|
|
-
|
|
|
- $line->rowid = $objp->rowid; // deprecated
|
|
|
- $line->id = $objp->rowid;
|
|
|
- $line->fk_supplier_proposal = $objp->fk_supplier_proposal;
|
|
|
- $line->fk_parent_line = $objp->fk_parent_line;
|
|
|
- $line->product_type = $objp->product_type;
|
|
|
- $line->label = $objp->custom_label;
|
|
|
- $line->desc = $objp->description; // Description ligne
|
|
|
- $line->qty = $objp->qty;
|
|
|
- $line->tva_tx = $objp->tva_tx;
|
|
|
- $line->localtax1_tx = $objp->localtax1_tx;
|
|
|
- $line->localtax2_tx = $objp->localtax2_tx;
|
|
|
- $line->subprice = $objp->subprice;
|
|
|
- $line->fk_remise_except = $objp->fk_remise_except;
|
|
|
- $line->remise_percent = $objp->remise_percent;
|
|
|
-
|
|
|
- $line->info_bits = $objp->info_bits;
|
|
|
- $line->total_ht = $objp->total_ht;
|
|
|
- $line->total_tva = $objp->total_tva;
|
|
|
- $line->total_localtax1 = $objp->total_localtax1;
|
|
|
- $line->total_localtax2 = $objp->total_localtax2;
|
|
|
- $line->total_ttc = $objp->total_ttc;
|
|
|
- $line->fk_fournprice = $objp->fk_fournprice;
|
|
|
- $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
|
|
|
- $line->pa_ht = $marginInfos[0];
|
|
|
- $line->marge_tx = $marginInfos[1];
|
|
|
- $line->marque_tx = $marginInfos[2];
|
|
|
- $line->special_code = $objp->special_code;
|
|
|
- $line->rang = $objp->rang;
|
|
|
-
|
|
|
- $line->fk_product = $objp->fk_product;
|
|
|
-
|
|
|
- $line->ref = $objp->product_ref; // deprecated
|
|
|
- $line->product_ref = $objp->product_ref;
|
|
|
- $line->libelle = $objp->product_label; // deprecated
|
|
|
- $line->product_label = $objp->product_label;
|
|
|
- $line->product_desc = $objp->product_desc; // Description produit
|
|
|
- $line->fk_product_type = $objp->fk_product_type;
|
|
|
-
|
|
|
- $line->ref_fourn = $objp->ref_produit_fourn;
|
|
|
-
|
|
|
- // Multicurrency
|
|
|
- $line->fk_multicurrency = $objp->fk_multicurrency;
|
|
|
- $line->multicurrency_code = $objp->multicurrency_code;
|
|
|
- $line->multicurrency_subprice = $objp->multicurrency_subprice;
|
|
|
- $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
|
|
|
- $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
|
|
|
- $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
|
|
|
- $line->fk_unit = $objp->fk_unit;
|
|
|
-
|
|
|
- $this->lines[$i] = $line;
|
|
|
-
|
|
|
- $i++;
|
|
|
- }
|
|
|
- $this->db->free($result);
|
|
|
- } else {
|
|
|
- $this->error = $this->db->error();
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- // Retreive all extrafield
|
|
|
- // fetch optionals attributes and labels
|
|
|
- $this->fetch_optionals();
|
|
|
-
|
|
|
- return 1;
|
|
|
- }
|
|
|
-
|
|
|
- $this->error = "Record Not Found";
|
|
|
- return 0;
|
|
|
- } else {
|
|
|
- $this->error = $this->db->error();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Set status to validated
|
|
|
- *
|
|
|
- * @param User $user Object user that validate
|
|
|
- * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
|
- * @return int <0 if KO, >=0 if OK
|
|
|
- */
|
|
|
- public function valid($user, $notrigger = 0)
|
|
|
- {
|
|
|
- require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
|
|
-
|
|
|
- global $conf, $langs;
|
|
|
-
|
|
|
- $error = 0;
|
|
|
- $now = dol_now();
|
|
|
-
|
|
|
- if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->supplier_proposal->creer))
|
|
|
- || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->supplier_proposal->validate_advance)))
|
|
|
- {
|
|
|
- $this->db->begin();
|
|
|
-
|
|
|
- // Numbering module definition
|
|
|
- $soc = new Societe($this->db);
|
|
|
- $soc->fetch($this->socid);
|
|
|
-
|
|
|
- // Define new ref
|
|
|
- if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
|
|
|
- {
|
|
|
- $num = $this->getNextNumRef($soc);
|
|
|
- } else {
|
|
|
- $num = $this->ref;
|
|
|
- }
|
|
|
- $this->newref = dol_sanitizeFileName($num);
|
|
|
-
|
|
|
- $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal";
|
|
|
- $sql .= " SET ref = '".$this->db->escape($num)."',";
|
|
|
- $sql .= " fk_statut = 1, date_valid='".$this->db->idate($now)."', fk_user_valid=".$user->id;
|
|
|
- $sql .= " WHERE rowid = ".$this->id." AND fk_statut = 0";
|
|
|
-
|
|
|
- dol_syslog(get_class($this)."::valid", LOG_DEBUG);
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if (!$resql)
|
|
|
- {
|
|
|
- dol_print_error($this->db);
|
|
|
- $error++;
|
|
|
- }
|
|
|
-
|
|
|
- // Trigger calls
|
|
|
- if (!$error && !$notrigger)
|
|
|
- {
|
|
|
- // Call trigger
|
|
|
- $result = $this->call_trigger('PROPOSAL_SUPPLIER_VALIDATE', $user);
|
|
|
- if ($result < 0) { $error++; }
|
|
|
- // End call triggers
|
|
|
- }
|
|
|
-
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- $this->oldref = $this->ref;
|
|
|
-
|
|
|
- // Rename directory if dir was a temporary ref
|
|
|
- if (preg_match('/^[\(]?PROV/i', $this->ref))
|
|
|
- {
|
|
|
- // Now we rename also files into index
|
|
|
- $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'supplier_proposal/".$this->db->escape($this->newref)."'";
|
|
|
- $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'supplier_proposal/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if (!$resql) { $error++; $this->error = $this->db->lasterror(); }
|
|
|
-
|
|
|
- // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
|
|
|
- $oldref = dol_sanitizeFileName($this->ref);
|
|
|
- $newref = dol_sanitizeFileName($num);
|
|
|
- $dirsource = $conf->supplier_proposal->dir_output.'/'.$oldref;
|
|
|
- $dirdest = $conf->supplier_proposal->dir_output.'/'.$newref;
|
|
|
- if (!$error && file_exists($dirsource))
|
|
|
- {
|
|
|
- dol_syslog(get_class($this)."::valid rename dir ".$dirsource." into ".$dirdest);
|
|
|
- if (@rename($dirsource, $dirdest))
|
|
|
- {
|
|
|
- dol_syslog("Rename ok");
|
|
|
- // Rename docs starting with $oldref with $newref
|
|
|
- $listoffiles = dol_dir_list($conf->supplier_proposal->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
|
|
|
- foreach ($listoffiles as $fileentry)
|
|
|
- {
|
|
|
- $dirsource = $fileentry['name'];
|
|
|
- $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
|
|
|
- $dirsource = $fileentry['path'].'/'.$dirsource;
|
|
|
- $dirdest = $fileentry['path'].'/'.$dirdest;
|
|
|
- @rename($dirsource, $dirdest);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- $this->ref = $num;
|
|
|
- $this->brouillon = 0;
|
|
|
- $this->statut = 1;
|
|
|
- $this->user_valid_id = $user->id;
|
|
|
- $this->datev = $now;
|
|
|
-
|
|
|
- $this->db->commit();
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- } else {
|
|
|
- dol_syslog("You don't have permission to validate supplier proposal", LOG_WARNING);
|
|
|
- return -2;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Set delivery date
|
|
|
- *
|
|
|
- * @param User $user Object user that modify
|
|
|
- * @param int $date_livraison Delivery date
|
|
|
- * @return int <0 if ko, >0 if ok
|
|
|
- */
|
|
|
- public function set_date_livraison($user, $date_livraison)
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
- if (!empty($user->rights->supplier_proposal->creer))
|
|
|
- {
|
|
|
- $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal ";
|
|
|
- $sql .= " SET date_livraison = ".($date_livraison != '' ? "'".$this->db->idate($date_livraison)."'" : 'null');
|
|
|
- $sql .= " WHERE rowid = ".$this->id;
|
|
|
-
|
|
|
- if ($this->db->query($sql))
|
|
|
- {
|
|
|
- $this->date_livraison = $date_livraison;
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- $this->error = $this->db->error();
|
|
|
- dol_syslog(get_class($this)."::set_date_livraison Erreur SQL");
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Set an overall discount on the proposal
|
|
|
- *
|
|
|
- * @param User $user Object user that modify
|
|
|
- * @param double $remise Amount discount
|
|
|
- * @return int <0 if ko, >0 if ok
|
|
|
- */
|
|
|
- public function set_remise_percent($user, $remise)
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
- $remise = trim($remise) ?trim($remise) : 0;
|
|
|
-
|
|
|
- if (!empty($user->rights->supplier_proposal->creer))
|
|
|
- {
|
|
|
- $remise = price2num($remise);
|
|
|
-
|
|
|
- $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal SET remise_percent = ".$remise;
|
|
|
- $sql .= " WHERE rowid = ".$this->id." AND fk_statut = 0";
|
|
|
-
|
|
|
- if ($this->db->query($sql))
|
|
|
- {
|
|
|
- $this->remise_percent = $remise;
|
|
|
- $this->update_price(1);
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- $this->error = $this->db->error();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Set an absolute overall discount on the proposal
|
|
|
- *
|
|
|
- * @param User $user Object user that modify
|
|
|
- * @param double $remise Amount discount
|
|
|
- * @return int <0 if ko, >0 if ok
|
|
|
- */
|
|
|
- public function set_remise_absolue($user, $remise)
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
- $remise = trim($remise) ?trim($remise) : 0;
|
|
|
-
|
|
|
- if (!empty($user->rights->supplier_proposal->creer))
|
|
|
- {
|
|
|
- $remise = price2num($remise);
|
|
|
-
|
|
|
- $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal ";
|
|
|
- $sql .= " SET remise_absolue = ".$remise;
|
|
|
- $sql .= " WHERE rowid = ".$this->id." AND fk_statut = 0";
|
|
|
-
|
|
|
- if ($this->db->query($sql))
|
|
|
- {
|
|
|
- $this->remise_absolue = $remise;
|
|
|
- $this->update_price(1);
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- $this->error = $this->db->error();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Reopen the commercial proposal
|
|
|
- *
|
|
|
- * @param User $user Object user that close
|
|
|
- * @param int $statut Statut
|
|
|
- * @param string $note Comment
|
|
|
- * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
|
- * @return int <0 if KO, >0 if OK
|
|
|
- */
|
|
|
- public function reopen($user, $statut, $note = '', $notrigger = 0)
|
|
|
- {
|
|
|
- global $langs, $conf;
|
|
|
-
|
|
|
- $this->statut = $statut;
|
|
|
- $error = 0;
|
|
|
-
|
|
|
- $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal";
|
|
|
- $sql .= " SET fk_statut = ".$this->statut.",";
|
|
|
- if (!empty($note)) $sql .= " note_private = '".$this->db->escape($note)."',";
|
|
|
- $sql .= " date_cloture=NULL, fk_user_cloture=NULL";
|
|
|
- $sql .= " WHERE rowid = ".$this->id;
|
|
|
-
|
|
|
- $this->db->begin();
|
|
|
-
|
|
|
- dol_syslog(get_class($this)."::reopen", LOG_DEBUG);
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if (!$resql) {
|
|
|
- $error++; $this->errors[] = "Error ".$this->db->lasterror();
|
|
|
- }
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- if (!$notrigger)
|
|
|
- {
|
|
|
- // Call trigger
|
|
|
- $result = $this->call_trigger('PROPOSAL_SUPPLIER_REOPEN', $user);
|
|
|
- if ($result < 0) { $error++; }
|
|
|
- // End call triggers
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Commit or rollback
|
|
|
- if ($error)
|
|
|
- {
|
|
|
- if (!empty($this->errors))
|
|
|
- {
|
|
|
- foreach ($this->errors as $errmsg)
|
|
|
- {
|
|
|
- dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
|
|
|
- $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
|
|
|
- }
|
|
|
- }
|
|
|
- $this->db->rollback();
|
|
|
- return -1 * $error;
|
|
|
- } else {
|
|
|
- $this->db->commit();
|
|
|
- return 1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Close the askprice
|
|
|
- *
|
|
|
- * @param User $user Object user that close
|
|
|
- * @param int $status Status
|
|
|
- * @param string $note Comment
|
|
|
- * @return int <0 if KO, >0 if OK
|
|
|
- */
|
|
|
- public function cloture($user, $status, $note)
|
|
|
- {
|
|
|
- global $langs, $conf;
|
|
|
-
|
|
|
- $this->statut = $status;
|
|
|
- $error = 0;
|
|
|
- $now = dol_now();
|
|
|
-
|
|
|
- $this->db->begin();
|
|
|
-
|
|
|
- $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal";
|
|
|
- $sql .= " SET fk_statut = ".$status.", note_private = '".$this->db->escape($note)."', date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id;
|
|
|
- $sql .= " WHERE rowid = ".$this->id;
|
|
|
-
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if ($resql)
|
|
|
- {
|
|
|
- $modelpdf = $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF_ODT_CLOSED ? $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF_ODT_CLOSED : $this->modelpdf;
|
|
|
- $triggerName = 'PROPOSAL_SUPPLIER_CLOSE_REFUSED';
|
|
|
-
|
|
|
- if ($status == 2)
|
|
|
- {
|
|
|
- $triggerName = 'PROPOSAL_SUPPLIER_CLOSE_SIGNED';
|
|
|
- $modelpdf = $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF_ODT_TOBILL ? $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF_ODT_TOBILL : $this->modelpdf;
|
|
|
-
|
|
|
- if (!empty($conf->global->SUPPLIER_PROPOSAL_UPDATE_PRICE_ON_SUPPlIER_PROPOSAL)) // TODO This option was not tested correctly. Error if product ref does not exists
|
|
|
- {
|
|
|
- $result = $this->updateOrCreatePriceFournisseur($user);
|
|
|
- }
|
|
|
- }
|
|
|
- if ($status == 4)
|
|
|
- {
|
|
|
- $triggerName = 'PROPOSAL_SUPPLIER_CLASSIFY_BILLED';
|
|
|
- }
|
|
|
-
|
|
|
- if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
|
|
|
- {
|
|
|
- // Define output language
|
|
|
- $outputlangs = $langs;
|
|
|
- if (!empty($conf->global->MAIN_MULTILANGS)) {
|
|
|
- $outputlangs = new Translate("", $conf);
|
|
|
- $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $this->thirdparty->default_lang);
|
|
|
- $outputlangs->setDefaultLang($newlang);
|
|
|
- }
|
|
|
- //$ret=$object->fetch($id); // Reload to get new records
|
|
|
- $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
|
- }
|
|
|
-
|
|
|
- // Call trigger
|
|
|
- $result = $this->call_trigger($triggerName, $user);
|
|
|
- if ($result < 0) { $error++; }
|
|
|
- // End call triggers
|
|
|
-
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- $this->db->commit();
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- } else {
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- $this->errors[] = $this->db->lasterror();
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Add or update supplier price according to result of proposal
|
|
|
- *
|
|
|
- * @param User $user Object user
|
|
|
- * @return int > 0 if OK
|
|
|
- */
|
|
|
- public function updateOrCreatePriceFournisseur($user)
|
|
|
- {
|
|
|
- global $conf;
|
|
|
-
|
|
|
- dol_syslog(get_class($this)."::updateOrCreatePriceFournisseur", LOG_DEBUG);
|
|
|
- foreach ($this->lines as $product)
|
|
|
- {
|
|
|
- if ($product->subprice <= 0) continue;
|
|
|
- $productsupplier = new ProductFournisseur($this->db);
|
|
|
-
|
|
|
- $multicurrency_tx = 1;
|
|
|
- $fk_multicurrency = 0;
|
|
|
-
|
|
|
- if (empty($this->thirdparty)) $this->fetch_thirdparty();
|
|
|
-
|
|
|
- $ref_fourn = $product->ref_fourn;
|
|
|
- if (empty($ref_fourn)) $ref_fourn = $product->ref_supplier;
|
|
|
- if (!empty($conf->multicurrency->enabled) && !empty($product->multicurrency_code)) list($fk_multicurrency, $multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $product->multicurrency_code);
|
|
|
- $productsupplier->id = $product->fk_product;
|
|
|
-
|
|
|
- $productsupplier->update_buyprice($product->qty, $product->total_ht, $user, 'HT', $this->thirdparty, '', $ref_fourn, $product->tva_tx, 0, 0, 0, $product->info_bits, '', '', array(), '', $product->multicurrency_total_ht, 'HT', $multicurrency_tx, $product->multicurrency_code, '', '', '');
|
|
|
- }
|
|
|
-
|
|
|
- return 1;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Upate ProductFournisseur
|
|
|
- *
|
|
|
- * @param int $idProductFournPrice id of llx_product_fournisseur_price
|
|
|
- * @param Product $product contain informations to update
|
|
|
- * @param User $user Object user
|
|
|
- * @return int <0 if KO, >0 if OK
|
|
|
- */
|
|
|
- public function updatePriceFournisseur($idProductFournPrice, $product, $user)
|
|
|
- {
|
|
|
- $price = price2num($product->subprice * $product->qty, 'MU');
|
|
|
- $unitPrice = price2num($product->subprice, 'MU');
|
|
|
-
|
|
|
- $sql = 'UPDATE '.MAIN_DB_PREFIX.'product_fournisseur_price SET '.(!empty($product->ref_fourn) ? 'ref_fourn = "'.$product->ref_fourn.'", ' : '').' price ='.$price.', unitprice ='.$unitPrice.' WHERE rowid = '.$idProductFournPrice;
|
|
|
-
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if (!$resql) {
|
|
|
- $this->error = $this->db->error();
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Create ProductFournisseur
|
|
|
- *
|
|
|
- * @param Product $product Object Product
|
|
|
- * @param User $user Object user
|
|
|
- * @return int <0 if KO, >0 if OK
|
|
|
- */
|
|
|
- public function createPriceFournisseur($product, $user)
|
|
|
- {
|
|
|
- global $conf;
|
|
|
-
|
|
|
- $price = price2num($product->subprice * $product->qty, 'MU');
|
|
|
- $qty = price2num($product->qty);
|
|
|
- $unitPrice = price2num($product->subprice, 'MU');
|
|
|
-
|
|
|
- $now = dol_now();
|
|
|
-
|
|
|
- $values = array(
|
|
|
- "'".$this->db->idate($now)."'",
|
|
|
- $product->fk_product,
|
|
|
- $this->thirdparty->id,
|
|
|
- "'".$product->ref_fourn."'",
|
|
|
- $price,
|
|
|
- $qty,
|
|
|
- $unitPrice,
|
|
|
- $product->tva_tx,
|
|
|
- $user->id
|
|
|
- );
|
|
|
- if (!empty($conf->multicurrency->enabled)) {
|
|
|
- if (!empty($product->multicurrency_code)) {
|
|
|
+ * @param int $fromid Id of thirdparty
|
|
|
+ * @return int New id of clone
|
|
|
+ */
|
|
|
+ public function createFromClone(User $user, $fromid = 0)
|
|
|
+ {
|
|
|
+ global $conf, $hookmanager;
|
|
|
+
|
|
|
+ $error = 0;
|
|
|
+ $now = dol_now();
|
|
|
+
|
|
|
+ $this->db->begin();
|
|
|
+
|
|
|
+ // get extrafields so they will be clone
|
|
|
+ foreach ($this->lines as $line)
|
|
|
+ $line->fetch_optionals();
|
|
|
+
|
|
|
+ // Load source object
|
|
|
+ $objFrom = clone $this;
|
|
|
+
|
|
|
+ $objsoc = new Societe($this->db);
|
|
|
+
|
|
|
+ // Change socid if needed
|
|
|
+ if (!empty($fromid) && $fromid != $this->socid)
|
|
|
+ {
|
|
|
+ if ($objsoc->fetch($fromid) > 0)
|
|
|
+ {
|
|
|
+ $this->socid = $objsoc->id;
|
|
|
+ $this->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
|
|
|
+ $this->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
|
|
|
+ $this->fk_project = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO Change product price if multi-prices
|
|
|
+ } else {
|
|
|
+ $objsoc->fetch($this->socid);
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->id = 0;
|
|
|
+ $this->statut = 0;
|
|
|
+
|
|
|
+ if (empty($conf->global->SUPPLIER_PROPOSAL_ADDON) || !is_readable(DOL_DOCUMENT_ROOT."/core/modules/supplier_proposal/".$conf->global->SUPPLIER_PROPOSAL_ADDON.".php"))
|
|
|
+ {
|
|
|
+ $this->error = 'ErrorSetupNotComplete';
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Clear fields
|
|
|
+ $this->user_author = $user->id;
|
|
|
+ $this->user_valid = '';
|
|
|
+ $this->date = $now;
|
|
|
+
|
|
|
+ // Set ref
|
|
|
+ require_once DOL_DOCUMENT_ROOT."/core/modules/supplier_proposal/".$conf->global->SUPPLIER_PROPOSAL_ADDON.'.php';
|
|
|
+ $obj = $conf->global->SUPPLIER_PROPOSAL_ADDON;
|
|
|
+ $modSupplierProposal = new $obj;
|
|
|
+ $this->ref = $modSupplierProposal->getNextValue($objsoc, $this);
|
|
|
+
|
|
|
+ // Create clone
|
|
|
+ $this->context['createfromclone'] = 'createfromclone';
|
|
|
+ $result = $this->create($user);
|
|
|
+ if ($result < 0) $error++;
|
|
|
+
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ // Hook of thirdparty module
|
|
|
+ if (is_object($hookmanager))
|
|
|
+ {
|
|
|
+ $parameters = array('objFrom'=>$objFrom);
|
|
|
+ $action = '';
|
|
|
+ $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
|
|
|
+ if ($reshook < 0) $error++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ unset($this->context['createfromclone']);
|
|
|
+
|
|
|
+ // End
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ $this->db->commit();
|
|
|
+ return $this->id;
|
|
|
+ } else {
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Load a proposal from database and its ligne array
|
|
|
+ *
|
|
|
+ * @param int $rowid id of object to load
|
|
|
+ * @param string $ref Ref of proposal
|
|
|
+ * @return int >0 if OK, <0 if KO
|
|
|
+ */
|
|
|
+ public function fetch($rowid, $ref = '')
|
|
|
+ {
|
|
|
+ global $conf;
|
|
|
+
|
|
|
+ $sql = "SELECT p.rowid, p.entity, p.ref, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc";
|
|
|
+ $sql .= ", p.total, p.tva, p.localtax1, p.localtax2, p.total_ht";
|
|
|
+ $sql .= ", p.datec";
|
|
|
+ $sql .= ", p.date_valid as datev";
|
|
|
+ $sql .= ", p.date_livraison as date_livraison";
|
|
|
+ $sql .= ", p.model_pdf, p.extraparams";
|
|
|
+ $sql .= ", p.note_private, p.note_public";
|
|
|
+ $sql .= ", p.fk_projet as fk_project, p.fk_statut";
|
|
|
+ $sql .= ", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
|
|
|
+ $sql .= ", p.fk_cond_reglement";
|
|
|
+ $sql .= ", p.fk_mode_reglement";
|
|
|
+ $sql .= ', p.fk_account';
|
|
|
+ $sql .= ", p.fk_shipping_method";
|
|
|
+ $sql .= ", p.fk_multicurrency, p.multicurrency_code, p.multicurrency_tx, p.multicurrency_total_ht, p.multicurrency_total_tva, p.multicurrency_total_ttc";
|
|
|
+ $sql .= ", c.label as statut_label";
|
|
|
+ $sql .= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc";
|
|
|
+ $sql .= ", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
|
|
|
+ $sql .= " FROM ".MAIN_DB_PREFIX."c_propalst as c, ".MAIN_DB_PREFIX."supplier_proposal as p";
|
|
|
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_mode_reglement = cp.id';
|
|
|
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON p.fk_cond_reglement = cr.rowid';
|
|
|
+ $sql .= " WHERE p.fk_statut = c.id";
|
|
|
+ $sql .= " AND p.entity IN (".getEntity('supplier_proposal').")";
|
|
|
+ if ($ref) $sql .= " AND p.ref='".$ref."'";
|
|
|
+ else $sql .= " AND p.rowid=".$rowid;
|
|
|
+
|
|
|
+ dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if ($resql)
|
|
|
+ {
|
|
|
+ if ($this->db->num_rows($resql))
|
|
|
+ {
|
|
|
+ $obj = $this->db->fetch_object($resql);
|
|
|
+
|
|
|
+ $this->id = $obj->rowid;
|
|
|
+ $this->entity = $obj->entity;
|
|
|
+
|
|
|
+ $this->ref = $obj->ref;
|
|
|
+ $this->remise = $obj->remise;
|
|
|
+ $this->remise_percent = $obj->remise_percent;
|
|
|
+ $this->remise_absolue = $obj->remise_absolue;
|
|
|
+ $this->total = $obj->total; // TODO deprecated
|
|
|
+ $this->total_ht = $obj->total_ht;
|
|
|
+ $this->total_tva = $obj->tva;
|
|
|
+ $this->total_localtax1 = $obj->localtax1;
|
|
|
+ $this->total_localtax2 = $obj->localtax2;
|
|
|
+ $this->total_ttc = $obj->total;
|
|
|
+ $this->socid = $obj->fk_soc;
|
|
|
+ $this->fk_project = $obj->fk_project;
|
|
|
+ $this->model_pdf = $obj->model_pdf;
|
|
|
+ $this->modelpdf = $obj->model_pdf;
|
|
|
+ $this->note = $obj->note_private; // TODO deprecated
|
|
|
+ $this->note_private = $obj->note_private;
|
|
|
+ $this->note_public = $obj->note_public;
|
|
|
+ $this->statut = (int) $obj->fk_statut;
|
|
|
+ $this->statut_libelle = $obj->statut_label;
|
|
|
+ $this->datec = $this->db->jdate($obj->datec); // TODO deprecated
|
|
|
+ $this->datev = $this->db->jdate($obj->datev); // TODO deprecated
|
|
|
+ $this->date_creation = $this->db->jdate($obj->datec); //Creation date
|
|
|
+ $this->date_validation = $this->db->jdate($obj->datev); //Validation date
|
|
|
+ $this->date_livraison = $this->db->jdate($obj->date_livraison);
|
|
|
+ $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method : null;
|
|
|
+
|
|
|
+ $this->mode_reglement_id = $obj->fk_mode_reglement;
|
|
|
+ $this->mode_reglement_code = $obj->mode_reglement_code;
|
|
|
+ $this->mode_reglement = $obj->mode_reglement;
|
|
|
+ $this->fk_account = ($obj->fk_account > 0) ? $obj->fk_account : null;
|
|
|
+ $this->cond_reglement_id = $obj->fk_cond_reglement;
|
|
|
+ $this->cond_reglement_code = $obj->cond_reglement_code;
|
|
|
+ $this->cond_reglement = $obj->cond_reglement;
|
|
|
+ $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
|
|
|
+
|
|
|
+ $this->extraparams = (array) json_decode($obj->extraparams, true);
|
|
|
+
|
|
|
+ $this->user_author_id = $obj->fk_user_author;
|
|
|
+ $this->user_valid_id = $obj->fk_user_valid;
|
|
|
+ $this->user_close_id = $obj->fk_user_cloture;
|
|
|
+
|
|
|
+ // Multicurrency
|
|
|
+ $this->fk_multicurrency = $obj->fk_multicurrency;
|
|
|
+ $this->multicurrency_code = $obj->multicurrency_code;
|
|
|
+ $this->multicurrency_tx = $obj->multicurrency_tx;
|
|
|
+ $this->multicurrency_total_ht = $obj->multicurrency_total_ht;
|
|
|
+ $this->multicurrency_total_tva = $obj->multicurrency_total_tva;
|
|
|
+ $this->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
|
|
|
+
|
|
|
+ if ($obj->fk_statut == 0)
|
|
|
+ {
|
|
|
+ $this->brouillon = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Retreive all extrafield
|
|
|
+ // fetch optionals attributes and labels
|
|
|
+ $this->fetch_optionals();
|
|
|
+
|
|
|
+ $this->db->free($resql);
|
|
|
+
|
|
|
+ $this->lines = array();
|
|
|
+
|
|
|
+ // Lines of supplier proposals
|
|
|
+ $sql = "SELECT d.rowid, d.fk_supplier_proposal, d.fk_parent_line, d.label as custom_label, d.description, d.price, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,";
|
|
|
+ $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,";
|
|
|
+ $sql .= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label,';
|
|
|
+ $sql .= ' d.ref_fourn as ref_produit_fourn,';
|
|
|
+ $sql .= ' d.fk_multicurrency, d.multicurrency_code, d.multicurrency_subprice, d.multicurrency_total_ht, d.multicurrency_total_tva, d.multicurrency_total_ttc, d.fk_unit';
|
|
|
+ $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposaldet as d";
|
|
|
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid";
|
|
|
+ $sql .= " WHERE d.fk_supplier_proposal = ".$this->id;
|
|
|
+ $sql .= " ORDER by d.rang";
|
|
|
+
|
|
|
+ $result = $this->db->query($sql);
|
|
|
+ if ($result)
|
|
|
+ {
|
|
|
+ $num = $this->db->num_rows($result);
|
|
|
+ $i = 0;
|
|
|
+
|
|
|
+ while ($i < $num)
|
|
|
+ {
|
|
|
+ $objp = $this->db->fetch_object($result);
|
|
|
+
|
|
|
+ $line = new SupplierProposalLine($this->db);
|
|
|
+
|
|
|
+ $line->rowid = $objp->rowid; // deprecated
|
|
|
+ $line->id = $objp->rowid;
|
|
|
+ $line->fk_supplier_proposal = $objp->fk_supplier_proposal;
|
|
|
+ $line->fk_parent_line = $objp->fk_parent_line;
|
|
|
+ $line->product_type = $objp->product_type;
|
|
|
+ $line->label = $objp->custom_label;
|
|
|
+ $line->desc = $objp->description; // Description ligne
|
|
|
+ $line->qty = $objp->qty;
|
|
|
+ $line->tva_tx = $objp->tva_tx;
|
|
|
+ $line->localtax1_tx = $objp->localtax1_tx;
|
|
|
+ $line->localtax2_tx = $objp->localtax2_tx;
|
|
|
+ $line->subprice = $objp->subprice;
|
|
|
+ $line->fk_remise_except = $objp->fk_remise_except;
|
|
|
+ $line->remise_percent = $objp->remise_percent;
|
|
|
+
|
|
|
+ $line->info_bits = $objp->info_bits;
|
|
|
+ $line->total_ht = $objp->total_ht;
|
|
|
+ $line->total_tva = $objp->total_tva;
|
|
|
+ $line->total_localtax1 = $objp->total_localtax1;
|
|
|
+ $line->total_localtax2 = $objp->total_localtax2;
|
|
|
+ $line->total_ttc = $objp->total_ttc;
|
|
|
+ $line->fk_fournprice = $objp->fk_fournprice;
|
|
|
+ $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
|
|
|
+ $line->pa_ht = $marginInfos[0];
|
|
|
+ $line->marge_tx = $marginInfos[1];
|
|
|
+ $line->marque_tx = $marginInfos[2];
|
|
|
+ $line->special_code = $objp->special_code;
|
|
|
+ $line->rang = $objp->rang;
|
|
|
+
|
|
|
+ $line->fk_product = $objp->fk_product;
|
|
|
+
|
|
|
+ $line->ref = $objp->product_ref; // deprecated
|
|
|
+ $line->product_ref = $objp->product_ref;
|
|
|
+ $line->libelle = $objp->product_label; // deprecated
|
|
|
+ $line->product_label = $objp->product_label;
|
|
|
+ $line->product_desc = $objp->product_desc; // Description produit
|
|
|
+ $line->fk_product_type = $objp->fk_product_type;
|
|
|
+
|
|
|
+ $line->ref_fourn = $objp->ref_produit_fourn;
|
|
|
+
|
|
|
+ // Multicurrency
|
|
|
+ $line->fk_multicurrency = $objp->fk_multicurrency;
|
|
|
+ $line->multicurrency_code = $objp->multicurrency_code;
|
|
|
+ $line->multicurrency_subprice = $objp->multicurrency_subprice;
|
|
|
+ $line->multicurrency_total_ht = $objp->multicurrency_total_ht;
|
|
|
+ $line->multicurrency_total_tva = $objp->multicurrency_total_tva;
|
|
|
+ $line->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
|
|
|
+ $line->fk_unit = $objp->fk_unit;
|
|
|
+
|
|
|
+ $this->lines[$i] = $line;
|
|
|
+
|
|
|
+ $i++;
|
|
|
+ }
|
|
|
+ $this->db->free($result);
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Retreive all extrafield
|
|
|
+ // fetch optionals attributes and labels
|
|
|
+ $this->fetch_optionals();
|
|
|
+
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->error = "Record Not Found";
|
|
|
+ return 0;
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Set status to validated
|
|
|
+ *
|
|
|
+ * @param User $user Object user that validate
|
|
|
+ * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
|
+ * @return int <0 if KO, >=0 if OK
|
|
|
+ */
|
|
|
+ public function valid($user, $notrigger = 0)
|
|
|
+ {
|
|
|
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
|
|
+
|
|
|
+ global $conf, $langs;
|
|
|
+
|
|
|
+ $error = 0;
|
|
|
+ $now = dol_now();
|
|
|
+
|
|
|
+ if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->supplier_proposal->creer))
|
|
|
+ || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->supplier_proposal->validate_advance)))
|
|
|
+ {
|
|
|
+ $this->db->begin();
|
|
|
+
|
|
|
+ // Numbering module definition
|
|
|
+ $soc = new Societe($this->db);
|
|
|
+ $soc->fetch($this->socid);
|
|
|
+
|
|
|
+ // Define new ref
|
|
|
+ if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life
|
|
|
+ {
|
|
|
+ $num = $this->getNextNumRef($soc);
|
|
|
+ } else {
|
|
|
+ $num = $this->ref;
|
|
|
+ }
|
|
|
+ $this->newref = dol_sanitizeFileName($num);
|
|
|
+
|
|
|
+ $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal";
|
|
|
+ $sql .= " SET ref = '".$this->db->escape($num)."',";
|
|
|
+ $sql .= " fk_statut = 1, date_valid='".$this->db->idate($now)."', fk_user_valid=".$user->id;
|
|
|
+ $sql .= " WHERE rowid = ".$this->id." AND fk_statut = 0";
|
|
|
+
|
|
|
+ dol_syslog(get_class($this)."::valid", LOG_DEBUG);
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if (!$resql)
|
|
|
+ {
|
|
|
+ dol_print_error($this->db);
|
|
|
+ $error++;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Trigger calls
|
|
|
+ if (!$error && !$notrigger)
|
|
|
+ {
|
|
|
+ // Call trigger
|
|
|
+ $result = $this->call_trigger('PROPOSAL_SUPPLIER_VALIDATE', $user);
|
|
|
+ if ($result < 0) { $error++; }
|
|
|
+ // End call triggers
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ $this->oldref = $this->ref;
|
|
|
+
|
|
|
+ // Rename directory if dir was a temporary ref
|
|
|
+ if (preg_match('/^[\(]?PROV/i', $this->ref))
|
|
|
+ {
|
|
|
+ // Now we rename also files into index
|
|
|
+ $sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filename = CONCAT('".$this->db->escape($this->newref)."', SUBSTR(filename, ".(strlen($this->ref) + 1).")), filepath = 'supplier_proposal/".$this->db->escape($this->newref)."'";
|
|
|
+ $sql .= " WHERE filename LIKE '".$this->db->escape($this->ref)."%' AND filepath = 'supplier_proposal/".$this->db->escape($this->ref)."' and entity = ".$conf->entity;
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if (!$resql) { $error++; $this->error = $this->db->lasterror(); }
|
|
|
+
|
|
|
+ // We rename directory ($this->ref = old ref, $num = new ref) in order not to lose the attachments
|
|
|
+ $oldref = dol_sanitizeFileName($this->ref);
|
|
|
+ $newref = dol_sanitizeFileName($num);
|
|
|
+ $dirsource = $conf->supplier_proposal->dir_output.'/'.$oldref;
|
|
|
+ $dirdest = $conf->supplier_proposal->dir_output.'/'.$newref;
|
|
|
+ if (!$error && file_exists($dirsource))
|
|
|
+ {
|
|
|
+ dol_syslog(get_class($this)."::valid rename dir ".$dirsource." into ".$dirdest);
|
|
|
+ if (@rename($dirsource, $dirdest))
|
|
|
+ {
|
|
|
+ dol_syslog("Rename ok");
|
|
|
+ // Rename docs starting with $oldref with $newref
|
|
|
+ $listoffiles = dol_dir_list($conf->supplier_proposal->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref, '/'));
|
|
|
+ foreach ($listoffiles as $fileentry)
|
|
|
+ {
|
|
|
+ $dirsource = $fileentry['name'];
|
|
|
+ $dirdest = preg_replace('/^'.preg_quote($oldref, '/').'/', $newref, $dirsource);
|
|
|
+ $dirsource = $fileentry['path'].'/'.$dirsource;
|
|
|
+ $dirdest = $fileentry['path'].'/'.$dirdest;
|
|
|
+ @rename($dirsource, $dirdest);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->ref = $num;
|
|
|
+ $this->brouillon = 0;
|
|
|
+ $this->statut = 1;
|
|
|
+ $this->user_valid_id = $user->id;
|
|
|
+ $this->datev = $now;
|
|
|
+
|
|
|
+ $this->db->commit();
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ dol_syslog("You don't have permission to validate supplier proposal", LOG_WARNING);
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Set delivery date
|
|
|
+ *
|
|
|
+ * @param User $user Object user that modify
|
|
|
+ * @param int $date_livraison Delivery date
|
|
|
+ * @return int <0 if ko, >0 if ok
|
|
|
+ */
|
|
|
+ public function set_date_livraison($user, $date_livraison)
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+ if (!empty($user->rights->supplier_proposal->creer))
|
|
|
+ {
|
|
|
+ $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal ";
|
|
|
+ $sql .= " SET date_livraison = ".($date_livraison != '' ? "'".$this->db->idate($date_livraison)."'" : 'null');
|
|
|
+ $sql .= " WHERE rowid = ".$this->id;
|
|
|
+
|
|
|
+ if ($this->db->query($sql))
|
|
|
+ {
|
|
|
+ $this->date_livraison = $date_livraison;
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ dol_syslog(get_class($this)."::set_date_livraison Erreur SQL");
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Set an overall discount on the proposal
|
|
|
+ *
|
|
|
+ * @param User $user Object user that modify
|
|
|
+ * @param double $remise Amount discount
|
|
|
+ * @return int <0 if ko, >0 if ok
|
|
|
+ */
|
|
|
+ public function set_remise_percent($user, $remise)
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+ $remise = trim($remise) ?trim($remise) : 0;
|
|
|
+
|
|
|
+ if (!empty($user->rights->supplier_proposal->creer))
|
|
|
+ {
|
|
|
+ $remise = price2num($remise);
|
|
|
+
|
|
|
+ $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal SET remise_percent = ".$remise;
|
|
|
+ $sql .= " WHERE rowid = ".$this->id." AND fk_statut = 0";
|
|
|
+
|
|
|
+ if ($this->db->query($sql))
|
|
|
+ {
|
|
|
+ $this->remise_percent = $remise;
|
|
|
+ $this->update_price(1);
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Set an absolute overall discount on the proposal
|
|
|
+ *
|
|
|
+ * @param User $user Object user that modify
|
|
|
+ * @param double $remise Amount discount
|
|
|
+ * @return int <0 if ko, >0 if ok
|
|
|
+ */
|
|
|
+ public function set_remise_absolue($user, $remise)
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+ $remise = trim($remise) ?trim($remise) : 0;
|
|
|
+
|
|
|
+ if (!empty($user->rights->supplier_proposal->creer))
|
|
|
+ {
|
|
|
+ $remise = price2num($remise);
|
|
|
+
|
|
|
+ $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal ";
|
|
|
+ $sql .= " SET remise_absolue = ".$remise;
|
|
|
+ $sql .= " WHERE rowid = ".$this->id." AND fk_statut = 0";
|
|
|
+
|
|
|
+ if ($this->db->query($sql))
|
|
|
+ {
|
|
|
+ $this->remise_absolue = $remise;
|
|
|
+ $this->update_price(1);
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Reopen the commercial proposal
|
|
|
+ *
|
|
|
+ * @param User $user Object user that close
|
|
|
+ * @param int $statut Statut
|
|
|
+ * @param string $note Comment
|
|
|
+ * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
|
+ * @return int <0 if KO, >0 if OK
|
|
|
+ */
|
|
|
+ public function reopen($user, $statut, $note = '', $notrigger = 0)
|
|
|
+ {
|
|
|
+ global $langs, $conf;
|
|
|
+
|
|
|
+ $this->statut = $statut;
|
|
|
+ $error = 0;
|
|
|
+
|
|
|
+ $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal";
|
|
|
+ $sql .= " SET fk_statut = ".$this->statut.",";
|
|
|
+ if (!empty($note)) $sql .= " note_private = '".$this->db->escape($note)."',";
|
|
|
+ $sql .= " date_cloture=NULL, fk_user_cloture=NULL";
|
|
|
+ $sql .= " WHERE rowid = ".$this->id;
|
|
|
+
|
|
|
+ $this->db->begin();
|
|
|
+
|
|
|
+ dol_syslog(get_class($this)."::reopen", LOG_DEBUG);
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if (!$resql) {
|
|
|
+ $error++; $this->errors[] = "Error ".$this->db->lasterror();
|
|
|
+ }
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ if (!$notrigger)
|
|
|
+ {
|
|
|
+ // Call trigger
|
|
|
+ $result = $this->call_trigger('PROPOSAL_SUPPLIER_REOPEN', $user);
|
|
|
+ if ($result < 0) { $error++; }
|
|
|
+ // End call triggers
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Commit or rollback
|
|
|
+ if ($error)
|
|
|
+ {
|
|
|
+ if (!empty($this->errors))
|
|
|
+ {
|
|
|
+ foreach ($this->errors as $errmsg)
|
|
|
+ {
|
|
|
+ dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
|
|
|
+ $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1 * $error;
|
|
|
+ } else {
|
|
|
+ $this->db->commit();
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Close the askprice
|
|
|
+ *
|
|
|
+ * @param User $user Object user that close
|
|
|
+ * @param int $status Status
|
|
|
+ * @param string $note Comment
|
|
|
+ * @return int <0 if KO, >0 if OK
|
|
|
+ */
|
|
|
+ public function cloture($user, $status, $note)
|
|
|
+ {
|
|
|
+ global $langs, $conf;
|
|
|
+
|
|
|
+ $this->statut = $status;
|
|
|
+ $error = 0;
|
|
|
+ $now = dol_now();
|
|
|
+
|
|
|
+ $this->db->begin();
|
|
|
+
|
|
|
+ $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal";
|
|
|
+ $sql .= " SET fk_statut = ".$status.", note_private = '".$this->db->escape($note)."', date_cloture='".$this->db->idate($now)."', fk_user_cloture=".$user->id;
|
|
|
+ $sql .= " WHERE rowid = ".$this->id;
|
|
|
+
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if ($resql)
|
|
|
+ {
|
|
|
+ $modelpdf = $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF_ODT_CLOSED ? $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF_ODT_CLOSED : $this->modelpdf;
|
|
|
+ $triggerName = 'PROPOSAL_SUPPLIER_CLOSE_REFUSED';
|
|
|
+
|
|
|
+ if ($status == 2)
|
|
|
+ {
|
|
|
+ $triggerName = 'PROPOSAL_SUPPLIER_CLOSE_SIGNED';
|
|
|
+ $modelpdf = $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF_ODT_TOBILL ? $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF_ODT_TOBILL : $this->modelpdf;
|
|
|
+
|
|
|
+ if (!empty($conf->global->SUPPLIER_PROPOSAL_UPDATE_PRICE_ON_SUPPlIER_PROPOSAL)) // TODO This option was not tested correctly. Error if product ref does not exists
|
|
|
+ {
|
|
|
+ $result = $this->updateOrCreatePriceFournisseur($user);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ($status == 4)
|
|
|
+ {
|
|
|
+ $triggerName = 'PROPOSAL_SUPPLIER_CLASSIFY_BILLED';
|
|
|
+ }
|
|
|
+
|
|
|
+ if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
|
|
|
+ {
|
|
|
+ // Define output language
|
|
|
+ $outputlangs = $langs;
|
|
|
+ if (!empty($conf->global->MAIN_MULTILANGS)) {
|
|
|
+ $outputlangs = new Translate("", $conf);
|
|
|
+ $newlang = (GETPOST('lang_id', 'aZ09') ? GETPOST('lang_id', 'aZ09') : $this->thirdparty->default_lang);
|
|
|
+ $outputlangs->setDefaultLang($newlang);
|
|
|
+ }
|
|
|
+ //$ret=$object->fetch($id); // Reload to get new records
|
|
|
+ $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Call trigger
|
|
|
+ $result = $this->call_trigger($triggerName, $user);
|
|
|
+ if ($result < 0) { $error++; }
|
|
|
+ // End call triggers
|
|
|
+
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ $this->db->commit();
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ $this->errors[] = $this->db->lasterror();
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Add or update supplier price according to result of proposal
|
|
|
+ *
|
|
|
+ * @param User $user Object user
|
|
|
+ * @return int > 0 if OK
|
|
|
+ */
|
|
|
+ public function updateOrCreatePriceFournisseur($user)
|
|
|
+ {
|
|
|
+ global $conf;
|
|
|
+
|
|
|
+ dol_syslog(get_class($this)."::updateOrCreatePriceFournisseur", LOG_DEBUG);
|
|
|
+ foreach ($this->lines as $product)
|
|
|
+ {
|
|
|
+ if ($product->subprice <= 0) continue;
|
|
|
+ $productsupplier = new ProductFournisseur($this->db);
|
|
|
+
|
|
|
+ $multicurrency_tx = 1;
|
|
|
+ $fk_multicurrency = 0;
|
|
|
+
|
|
|
+ if (empty($this->thirdparty)) $this->fetch_thirdparty();
|
|
|
+
|
|
|
+ $ref_fourn = $product->ref_fourn;
|
|
|
+ if (empty($ref_fourn)) $ref_fourn = $product->ref_supplier;
|
|
|
+ if (!empty($conf->multicurrency->enabled) && !empty($product->multicurrency_code)) list($fk_multicurrency, $multicurrency_tx) = MultiCurrency::getIdAndTxFromCode($this->db, $product->multicurrency_code);
|
|
|
+ $productsupplier->id = $product->fk_product;
|
|
|
+
|
|
|
+ $productsupplier->update_buyprice($product->qty, $product->total_ht, $user, 'HT', $this->thirdparty, '', $ref_fourn, $product->tva_tx, 0, 0, 0, $product->info_bits, '', '', array(), '', $product->multicurrency_total_ht, 'HT', $multicurrency_tx, $product->multicurrency_code, '', '', '');
|
|
|
+ }
|
|
|
+
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Upate ProductFournisseur
|
|
|
+ *
|
|
|
+ * @param int $idProductFournPrice id of llx_product_fournisseur_price
|
|
|
+ * @param Product $product contain informations to update
|
|
|
+ * @param User $user Object user
|
|
|
+ * @return int <0 if KO, >0 if OK
|
|
|
+ */
|
|
|
+ public function updatePriceFournisseur($idProductFournPrice, $product, $user)
|
|
|
+ {
|
|
|
+ $price = price2num($product->subprice * $product->qty, 'MU');
|
|
|
+ $unitPrice = price2num($product->subprice, 'MU');
|
|
|
+
|
|
|
+ $sql = 'UPDATE '.MAIN_DB_PREFIX.'product_fournisseur_price SET '.(!empty($product->ref_fourn) ? 'ref_fourn = "'.$product->ref_fourn.'", ' : '').' price ='.$price.', unitprice ='.$unitPrice.' WHERE rowid = '.$idProductFournPrice;
|
|
|
+
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if (!$resql) {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create ProductFournisseur
|
|
|
+ *
|
|
|
+ * @param Product $product Object Product
|
|
|
+ * @param User $user Object user
|
|
|
+ * @return int <0 if KO, >0 if OK
|
|
|
+ */
|
|
|
+ public function createPriceFournisseur($product, $user)
|
|
|
+ {
|
|
|
+ global $conf;
|
|
|
+
|
|
|
+ $price = price2num($product->subprice * $product->qty, 'MU');
|
|
|
+ $qty = price2num($product->qty);
|
|
|
+ $unitPrice = price2num($product->subprice, 'MU');
|
|
|
+
|
|
|
+ $now = dol_now();
|
|
|
+
|
|
|
+ $values = array(
|
|
|
+ "'".$this->db->idate($now)."'",
|
|
|
+ $product->fk_product,
|
|
|
+ $this->thirdparty->id,
|
|
|
+ "'".$product->ref_fourn."'",
|
|
|
+ $price,
|
|
|
+ $qty,
|
|
|
+ $unitPrice,
|
|
|
+ $product->tva_tx,
|
|
|
+ $user->id
|
|
|
+ );
|
|
|
+ if (!empty($conf->multicurrency->enabled)) {
|
|
|
+ if (!empty($product->multicurrency_code)) {
|
|
|
include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
|
|
|
- $multicurrency = new MultiCurrency($this->db); //need to fetch because empty fk_multicurrency and rate
|
|
|
- $multicurrency->fetch(0, $product->multicurrency_code);
|
|
|
- if (!empty($multicurrency->id)) {
|
|
|
- $values[] = $multicurrency->id;
|
|
|
- $values[] = "'".$product->multicurrency_code."'";
|
|
|
- $values[] = $product->multicurrency_subprice;
|
|
|
- $values[] = $product->multicurrency_total_ht;
|
|
|
- $values[] = $multicurrency->rate->rate;
|
|
|
- } else {
|
|
|
- for ($i = 0; $i < 5; $i++) $values[] = 'NULL';
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_fournisseur_price ';
|
|
|
- $sql .= '(datec, fk_product, fk_soc, ref_fourn, price, quantity, unitprice, tva_tx, fk_user';
|
|
|
- if (!empty($conf->multicurrency->enabled) && !empty($product->multicurrency_code)) $sql .= ',fk_multicurrency, multicurrency_code, multicurrency_unitprice, multicurrency_price, multicurrency_tx';
|
|
|
- $sql .= ') VALUES ('.implode(',', $values).')';
|
|
|
-
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if (!$resql) {
|
|
|
- $this->error = $this->db->error();
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Set draft status
|
|
|
- *
|
|
|
- * @param User $user Object user that modify
|
|
|
- * @return int <0 if KO, >0 if OK
|
|
|
- */
|
|
|
- public function setDraft($user)
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
- global $conf, $langs;
|
|
|
-
|
|
|
- $error = 0;
|
|
|
-
|
|
|
- if ($this->statut == self::STATUS_DRAFT)
|
|
|
- {
|
|
|
- dol_syslog(get_class($this)."::setDraft already draft status", LOG_WARNING);
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal";
|
|
|
- $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
|
|
|
- $sql .= " WHERE rowid = ".$this->id;
|
|
|
-
|
|
|
- if ($this->db->query($sql))
|
|
|
- {
|
|
|
- if (!$error) {
|
|
|
- $this->oldcopy = clone $this;
|
|
|
- }
|
|
|
-
|
|
|
- if (!$error) {
|
|
|
- // Call trigger
|
|
|
- $result = $this->call_trigger('PROPOSAL_SUPPLIER_UNVALIDATE', $user);
|
|
|
- if ($result < 0) $error++;
|
|
|
- }
|
|
|
-
|
|
|
- if (!$error) {
|
|
|
- $this->statut = self::STATUS_DRAFT;
|
|
|
- $this->brouillon = 1;
|
|
|
- $this->db->commit();
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- } else {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Return list of askprice (eventually filtered on user) into an array
|
|
|
- *
|
|
|
- * @param int $shortlist 0=Return array[id]=ref, 1=Return array[](id=>id,ref=>ref,name=>name)
|
|
|
- * @param int $draft 0=not draft, 1=draft
|
|
|
- * @param int $notcurrentuser 0=all user, 1=not current user
|
|
|
- * @param int $socid Id third pary
|
|
|
- * @param int $limit For pagination
|
|
|
- * @param int $offset For pagination
|
|
|
- * @param string $sortfield Sort criteria
|
|
|
- * @param string $sortorder Sort order
|
|
|
- * @return int -1 if KO, array with result if OK
|
|
|
- */
|
|
|
- public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield = 'p.datec', $sortorder = 'DESC')
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
- global $conf, $user;
|
|
|
-
|
|
|
- $ga = array();
|
|
|
-
|
|
|
- $sql = "SELECT s.rowid, s.nom as name, s.client,";
|
|
|
- $sql .= " p.rowid as supplier_proposalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
|
|
|
- $sql .= " p.datep as dp, p.fin_validite as datelimite";
|
|
|
- if (!$user->rights->societe->client->voir && !$socid) $sql .= ", sc.fk_soc, sc.fk_user";
|
|
|
- $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as p, ".MAIN_DB_PREFIX."c_propalst as c";
|
|
|
- if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
|
|
|
- $sql .= " WHERE p.entity IN (".getEntity('supplier_proposal').")";
|
|
|
- $sql .= " AND p.fk_soc = s.rowid";
|
|
|
- $sql .= " AND p.fk_statut = c.id";
|
|
|
- if (!$user->rights->societe->client->voir && !$socid) //restriction
|
|
|
- {
|
|
|
- $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
|
|
|
- }
|
|
|
- if ($socid) $sql .= " AND s.rowid = ".$socid;
|
|
|
- if ($draft) $sql .= " AND p.fk_statut = 0";
|
|
|
- if ($notcurrentuser > 0) $sql .= " AND p.fk_user_author <> ".$user->id;
|
|
|
- $sql .= $this->db->order($sortfield, $sortorder);
|
|
|
- $sql .= $this->db->plimit($limit, $offset);
|
|
|
-
|
|
|
- $result = $this->db->query($sql);
|
|
|
- if ($result)
|
|
|
- {
|
|
|
- $num = $this->db->num_rows($result);
|
|
|
- if ($num)
|
|
|
- {
|
|
|
- $i = 0;
|
|
|
- while ($i < $num)
|
|
|
- {
|
|
|
- $obj = $this->db->fetch_object($result);
|
|
|
-
|
|
|
- if ($shortlist == 1)
|
|
|
- {
|
|
|
- $ga[$obj->supplier_proposalid] = $obj->ref;
|
|
|
- } elseif ($shortlist == 2)
|
|
|
- {
|
|
|
- $ga[$obj->supplier_proposalid] = $obj->ref.' ('.$obj->name.')';
|
|
|
- } else {
|
|
|
- $ga[$i]['id'] = $obj->supplier_proposalid;
|
|
|
- $ga[$i]['ref'] = $obj->ref;
|
|
|
- $ga[$i]['name'] = $obj->name;
|
|
|
- }
|
|
|
-
|
|
|
- $i++;
|
|
|
- }
|
|
|
- }
|
|
|
- return $ga;
|
|
|
- } else {
|
|
|
- dol_print_error($this->db);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Delete askprice
|
|
|
- *
|
|
|
- * @param User $user Object user that delete
|
|
|
- * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
|
- * @return int 1 if ok, otherwise if error
|
|
|
- */
|
|
|
- public function delete($user, $notrigger = 0)
|
|
|
- {
|
|
|
- global $conf, $langs;
|
|
|
- require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
|
|
-
|
|
|
- $error = 0;
|
|
|
-
|
|
|
- $this->db->begin();
|
|
|
-
|
|
|
- if (!$notrigger)
|
|
|
- {
|
|
|
- // Call trigger
|
|
|
- $result = $this->call_trigger('PROPOSAL_SUPPLIER_DELETE', $user);
|
|
|
- if ($result < 0) { $error++; }
|
|
|
- // End call triggers
|
|
|
- }
|
|
|
-
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- $main = MAIN_DB_PREFIX.'supplier_proposaldet';
|
|
|
- $ef = $main."_extrafields";
|
|
|
- $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_supplier_proposal = ".$this->id.")";
|
|
|
- $sql = "DELETE FROM ".MAIN_DB_PREFIX."supplier_proposaldet WHERE fk_supplier_proposal = ".$this->id;
|
|
|
- if ($this->db->query($sql))
|
|
|
- {
|
|
|
- $sql = "DELETE FROM ".MAIN_DB_PREFIX."supplier_proposal WHERE rowid = ".$this->id;
|
|
|
- if ($this->db->query($sqlef) && $this->db->query($sql))
|
|
|
- {
|
|
|
- // Delete linked object
|
|
|
- $res = $this->deleteObjectLinked();
|
|
|
- if ($res < 0) $error++;
|
|
|
-
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- // We remove directory
|
|
|
- $ref = dol_sanitizeFileName($this->ref);
|
|
|
- if ($conf->supplier_proposal->dir_output && !empty($this->ref))
|
|
|
- {
|
|
|
- $dir = $conf->supplier_proposal->dir_output."/".$ref;
|
|
|
- $file = $dir."/".$ref.".pdf";
|
|
|
- if (file_exists($file))
|
|
|
- {
|
|
|
- dol_delete_preview($this);
|
|
|
-
|
|
|
- if (!dol_delete_file($file, 0, 0, 0, $this)) // For triggers
|
|
|
- {
|
|
|
- $this->error = 'ErrorFailToDeleteFile';
|
|
|
- $this->errors = array('ErrorFailToDeleteFile');
|
|
|
- $this->db->rollback();
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
- if (file_exists($dir))
|
|
|
- {
|
|
|
- $res = @dol_delete_dir_recursive($dir);
|
|
|
- if (!$res)
|
|
|
- {
|
|
|
- $this->error = 'ErrorFailToDeleteDir';
|
|
|
- $this->errors = array('ErrorFailToDeleteDir');
|
|
|
- $this->db->rollback();
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Removed extrafields
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- $result = $this->deleteExtraFields();
|
|
|
- if ($result < 0)
|
|
|
- {
|
|
|
- $error++;
|
|
|
- $errorflag = -4;
|
|
|
- dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!$error)
|
|
|
- {
|
|
|
- dol_syslog(get_class($this)."::delete ".$this->id." by ".$user->id, LOG_DEBUG);
|
|
|
- $this->db->commit();
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- $this->db->rollback();
|
|
|
- return 0;
|
|
|
- }
|
|
|
- } else {
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- $this->db->rollback();
|
|
|
- return -3;
|
|
|
- }
|
|
|
- } else {
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- $this->db->rollback();
|
|
|
- return -2;
|
|
|
- }
|
|
|
- } else {
|
|
|
- $this->db->rollback();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Object SupplierProposal Information
|
|
|
- *
|
|
|
- * @param int $id Proposal id
|
|
|
- * @return void
|
|
|
- */
|
|
|
- public function info($id)
|
|
|
- {
|
|
|
- $sql = "SELECT c.rowid, ";
|
|
|
- $sql .= " c.datec, c.date_valid as datev, c.date_cloture as dateo,";
|
|
|
- $sql .= " c.fk_user_author, c.fk_user_valid, c.fk_user_cloture";
|
|
|
- $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as c";
|
|
|
- $sql .= " WHERE c.rowid = ".$id;
|
|
|
-
|
|
|
- $result = $this->db->query($sql);
|
|
|
-
|
|
|
- if ($result)
|
|
|
- {
|
|
|
- if ($this->db->num_rows($result))
|
|
|
- {
|
|
|
- $obj = $this->db->fetch_object($result);
|
|
|
-
|
|
|
- $this->id = $obj->rowid;
|
|
|
-
|
|
|
- $this->date_creation = $this->db->jdate($obj->datec);
|
|
|
- $this->date_validation = $this->db->jdate($obj->datev);
|
|
|
- $this->date_cloture = $this->db->jdate($obj->dateo);
|
|
|
-
|
|
|
- $cuser = new User($this->db);
|
|
|
- $cuser->fetch($obj->fk_user_author);
|
|
|
- $this->user_creation = $cuser;
|
|
|
-
|
|
|
- if ($obj->fk_user_valid)
|
|
|
- {
|
|
|
- $vuser = new User($this->db);
|
|
|
- $vuser->fetch($obj->fk_user_valid);
|
|
|
- $this->user_validation = $vuser;
|
|
|
- }
|
|
|
-
|
|
|
- if ($obj->fk_user_cloture)
|
|
|
- {
|
|
|
- $cluser = new User($this->db);
|
|
|
- $cluser->fetch($obj->fk_user_cloture);
|
|
|
- $this->user_cloture = $cluser;
|
|
|
- }
|
|
|
- }
|
|
|
- $this->db->free($result);
|
|
|
- } else {
|
|
|
- dol_print_error($this->db);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Return label of status of proposal (draft, validated, ...)
|
|
|
- *
|
|
|
- * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
|
|
|
- * @return string Label
|
|
|
- */
|
|
|
- public function getLibStatut($mode = 0)
|
|
|
- {
|
|
|
- return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
|
|
|
- }
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Return label of a status (draft, validated, ...)
|
|
|
- *
|
|
|
- * @param int $status Id status
|
|
|
+ $multicurrency = new MultiCurrency($this->db); //need to fetch because empty fk_multicurrency and rate
|
|
|
+ $multicurrency->fetch(0, $product->multicurrency_code);
|
|
|
+ if (!empty($multicurrency->id)) {
|
|
|
+ $values[] = $multicurrency->id;
|
|
|
+ $values[] = "'".$product->multicurrency_code."'";
|
|
|
+ $values[] = $product->multicurrency_subprice;
|
|
|
+ $values[] = $product->multicurrency_total_ht;
|
|
|
+ $values[] = $multicurrency->rate->rate;
|
|
|
+ } else {
|
|
|
+ for ($i = 0; $i < 5; $i++) $values[] = 'NULL';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'product_fournisseur_price ';
|
|
|
+ $sql .= '(datec, fk_product, fk_soc, ref_fourn, price, quantity, unitprice, tva_tx, fk_user';
|
|
|
+ if (!empty($conf->multicurrency->enabled) && !empty($product->multicurrency_code)) $sql .= ',fk_multicurrency, multicurrency_code, multicurrency_unitprice, multicurrency_price, multicurrency_tx';
|
|
|
+ $sql .= ') VALUES ('.implode(',', $values).')';
|
|
|
+
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if (!$resql) {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Set draft status
|
|
|
+ *
|
|
|
+ * @param User $user Object user that modify
|
|
|
+ * @return int <0 if KO, >0 if OK
|
|
|
+ */
|
|
|
+ public function setDraft($user)
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+ global $conf, $langs;
|
|
|
+
|
|
|
+ $error = 0;
|
|
|
+
|
|
|
+ if ($this->statut == self::STATUS_DRAFT)
|
|
|
+ {
|
|
|
+ dol_syslog(get_class($this)."::setDraft already draft status", LOG_WARNING);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ $sql = "UPDATE ".MAIN_DB_PREFIX."supplier_proposal";
|
|
|
+ $sql .= " SET fk_statut = ".self::STATUS_DRAFT;
|
|
|
+ $sql .= " WHERE rowid = ".$this->id;
|
|
|
+
|
|
|
+ if ($this->db->query($sql))
|
|
|
+ {
|
|
|
+ if (!$error) {
|
|
|
+ $this->oldcopy = clone $this;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$error) {
|
|
|
+ // Call trigger
|
|
|
+ $result = $this->call_trigger('PROPOSAL_SUPPLIER_UNVALIDATE', $user);
|
|
|
+ if ($result < 0) $error++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$error) {
|
|
|
+ $this->statut = self::STATUS_DRAFT;
|
|
|
+ $this->brouillon = 1;
|
|
|
+ $this->db->commit();
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Return list of askprice (eventually filtered on user) into an array
|
|
|
+ *
|
|
|
+ * @param int $shortlist 0=Return array[id]=ref, 1=Return array[](id=>id,ref=>ref,name=>name)
|
|
|
+ * @param int $draft 0=not draft, 1=draft
|
|
|
+ * @param int $notcurrentuser 0=all user, 1=not current user
|
|
|
+ * @param int $socid Id third pary
|
|
|
+ * @param int $limit For pagination
|
|
|
+ * @param int $offset For pagination
|
|
|
+ * @param string $sortfield Sort criteria
|
|
|
+ * @param string $sortorder Sort order
|
|
|
+ * @return int -1 if KO, array with result if OK
|
|
|
+ */
|
|
|
+ public function liste_array($shortlist = 0, $draft = 0, $notcurrentuser = 0, $socid = 0, $limit = 0, $offset = 0, $sortfield = 'p.datec', $sortorder = 'DESC')
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+ global $conf, $user;
|
|
|
+
|
|
|
+ $ga = array();
|
|
|
+
|
|
|
+ $sql = "SELECT s.rowid, s.nom as name, s.client,";
|
|
|
+ $sql .= " p.rowid as supplier_proposalid, p.fk_statut, p.total_ht, p.ref, p.remise, ";
|
|
|
+ $sql .= " p.datep as dp, p.fin_validite as datelimite";
|
|
|
+ if (!$user->rights->societe->client->voir && !$socid) $sql .= ", sc.fk_soc, sc.fk_user";
|
|
|
+ $sql .= " FROM ".MAIN_DB_PREFIX."societe as s, ".MAIN_DB_PREFIX."supplier_proposal as p, ".MAIN_DB_PREFIX."c_propalst as c";
|
|
|
+ if (!$user->rights->societe->client->voir && !$socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
|
|
|
+ $sql .= " WHERE p.entity IN (".getEntity('supplier_proposal').")";
|
|
|
+ $sql .= " AND p.fk_soc = s.rowid";
|
|
|
+ $sql .= " AND p.fk_statut = c.id";
|
|
|
+ if (!$user->rights->societe->client->voir && !$socid) //restriction
|
|
|
+ {
|
|
|
+ $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
|
|
|
+ }
|
|
|
+ if ($socid) $sql .= " AND s.rowid = ".$socid;
|
|
|
+ if ($draft) $sql .= " AND p.fk_statut = 0";
|
|
|
+ if ($notcurrentuser > 0) $sql .= " AND p.fk_user_author <> ".$user->id;
|
|
|
+ $sql .= $this->db->order($sortfield, $sortorder);
|
|
|
+ $sql .= $this->db->plimit($limit, $offset);
|
|
|
+
|
|
|
+ $result = $this->db->query($sql);
|
|
|
+ if ($result)
|
|
|
+ {
|
|
|
+ $num = $this->db->num_rows($result);
|
|
|
+ if ($num)
|
|
|
+ {
|
|
|
+ $i = 0;
|
|
|
+ while ($i < $num)
|
|
|
+ {
|
|
|
+ $obj = $this->db->fetch_object($result);
|
|
|
+
|
|
|
+ if ($shortlist == 1)
|
|
|
+ {
|
|
|
+ $ga[$obj->supplier_proposalid] = $obj->ref;
|
|
|
+ } elseif ($shortlist == 2)
|
|
|
+ {
|
|
|
+ $ga[$obj->supplier_proposalid] = $obj->ref.' ('.$obj->name.')';
|
|
|
+ } else {
|
|
|
+ $ga[$i]['id'] = $obj->supplier_proposalid;
|
|
|
+ $ga[$i]['ref'] = $obj->ref;
|
|
|
+ $ga[$i]['name'] = $obj->name;
|
|
|
+ }
|
|
|
+
|
|
|
+ $i++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $ga;
|
|
|
+ } else {
|
|
|
+ dol_print_error($this->db);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Delete askprice
|
|
|
+ *
|
|
|
+ * @param User $user Object user that delete
|
|
|
+ * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
|
|
|
+ * @return int 1 if ok, otherwise if error
|
|
|
+ */
|
|
|
+ public function delete($user, $notrigger = 0)
|
|
|
+ {
|
|
|
+ global $conf, $langs;
|
|
|
+ require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
|
|
+
|
|
|
+ $error = 0;
|
|
|
+
|
|
|
+ $this->db->begin();
|
|
|
+
|
|
|
+ if (!$notrigger)
|
|
|
+ {
|
|
|
+ // Call trigger
|
|
|
+ $result = $this->call_trigger('PROPOSAL_SUPPLIER_DELETE', $user);
|
|
|
+ if ($result < 0) { $error++; }
|
|
|
+ // End call triggers
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ $main = MAIN_DB_PREFIX.'supplier_proposaldet';
|
|
|
+ $ef = $main."_extrafields";
|
|
|
+ $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_supplier_proposal = ".$this->id.")";
|
|
|
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."supplier_proposaldet WHERE fk_supplier_proposal = ".$this->id;
|
|
|
+ if ($this->db->query($sql))
|
|
|
+ {
|
|
|
+ $sql = "DELETE FROM ".MAIN_DB_PREFIX."supplier_proposal WHERE rowid = ".$this->id;
|
|
|
+ if ($this->db->query($sqlef) && $this->db->query($sql))
|
|
|
+ {
|
|
|
+ // Delete linked object
|
|
|
+ $res = $this->deleteObjectLinked();
|
|
|
+ if ($res < 0) $error++;
|
|
|
+
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ // We remove directory
|
|
|
+ $ref = dol_sanitizeFileName($this->ref);
|
|
|
+ if ($conf->supplier_proposal->dir_output && !empty($this->ref))
|
|
|
+ {
|
|
|
+ $dir = $conf->supplier_proposal->dir_output."/".$ref;
|
|
|
+ $file = $dir."/".$ref.".pdf";
|
|
|
+ if (file_exists($file))
|
|
|
+ {
|
|
|
+ dol_delete_preview($this);
|
|
|
+
|
|
|
+ if (!dol_delete_file($file, 0, 0, 0, $this)) // For triggers
|
|
|
+ {
|
|
|
+ $this->error = 'ErrorFailToDeleteFile';
|
|
|
+ $this->errors = array('ErrorFailToDeleteFile');
|
|
|
+ $this->db->rollback();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (file_exists($dir))
|
|
|
+ {
|
|
|
+ $res = @dol_delete_dir_recursive($dir);
|
|
|
+ if (!$res)
|
|
|
+ {
|
|
|
+ $this->error = 'ErrorFailToDeleteDir';
|
|
|
+ $this->errors = array('ErrorFailToDeleteDir');
|
|
|
+ $this->db->rollback();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Removed extrafields
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ $result = $this->deleteExtraFields();
|
|
|
+ if ($result < 0)
|
|
|
+ {
|
|
|
+ $error++;
|
|
|
+ $errorflag = -4;
|
|
|
+ dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$error)
|
|
|
+ {
|
|
|
+ dol_syslog(get_class($this)."::delete ".$this->id." by ".$user->id, LOG_DEBUG);
|
|
|
+ $this->db->commit();
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ $this->db->rollback();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ $this->db->rollback();
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ $this->db->rollback();
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $this->db->rollback();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Object SupplierProposal Information
|
|
|
+ *
|
|
|
+ * @param int $id Proposal id
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function info($id)
|
|
|
+ {
|
|
|
+ $sql = "SELECT c.rowid, ";
|
|
|
+ $sql .= " c.datec, c.date_valid as datev, c.date_cloture as dateo,";
|
|
|
+ $sql .= " c.fk_user_author, c.fk_user_valid, c.fk_user_cloture";
|
|
|
+ $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as c";
|
|
|
+ $sql .= " WHERE c.rowid = ".$id;
|
|
|
+
|
|
|
+ $result = $this->db->query($sql);
|
|
|
+
|
|
|
+ if ($result)
|
|
|
+ {
|
|
|
+ if ($this->db->num_rows($result))
|
|
|
+ {
|
|
|
+ $obj = $this->db->fetch_object($result);
|
|
|
+
|
|
|
+ $this->id = $obj->rowid;
|
|
|
+
|
|
|
+ $this->date_creation = $this->db->jdate($obj->datec);
|
|
|
+ $this->date_validation = $this->db->jdate($obj->datev);
|
|
|
+ $this->date_cloture = $this->db->jdate($obj->dateo);
|
|
|
+
|
|
|
+ $cuser = new User($this->db);
|
|
|
+ $cuser->fetch($obj->fk_user_author);
|
|
|
+ $this->user_creation = $cuser;
|
|
|
+
|
|
|
+ if ($obj->fk_user_valid)
|
|
|
+ {
|
|
|
+ $vuser = new User($this->db);
|
|
|
+ $vuser->fetch($obj->fk_user_valid);
|
|
|
+ $this->user_validation = $vuser;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($obj->fk_user_cloture)
|
|
|
+ {
|
|
|
+ $cluser = new User($this->db);
|
|
|
+ $cluser->fetch($obj->fk_user_cloture);
|
|
|
+ $this->user_cloture = $cluser;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $this->db->free($result);
|
|
|
+ } else {
|
|
|
+ dol_print_error($this->db);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Return label of status of proposal (draft, validated, ...)
|
|
|
+ *
|
|
|
+ * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
|
|
|
+ * @return string Label
|
|
|
+ */
|
|
|
+ public function getLibStatut($mode = 0)
|
|
|
+ {
|
|
|
+ return $this->LibStatut((isset($this->statut) ? $this->statut : $this->status), $mode);
|
|
|
+ }
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Return label of a status (draft, validated, ...)
|
|
|
+ *
|
|
|
+ * @param int $status Id status
|
|
|
* @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto
|
|
|
- * @return string Label
|
|
|
- */
|
|
|
- public function LibStatut($status, $mode = 1)
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
-
|
|
|
- // Init/load array of translation of status
|
|
|
- if (empty($this->labelStatus) || empty($this->labelStatusShort))
|
|
|
- {
|
|
|
- global $langs;
|
|
|
- $langs->load("supplier_proposal");
|
|
|
- $this->labelStatus[self::STATUS_DRAFT] = $langs->trans("SupplierProposalStatusDraft");
|
|
|
- $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans("SupplierProposalStatusValidated");
|
|
|
- $this->labelStatus[self::STATUS_SIGNED] = $langs->trans("SupplierProposalStatusSigned");
|
|
|
- $this->labelStatus[self::STATUS_NOTSIGNED] = $langs->trans("SupplierProposalStatusNotSigned");
|
|
|
- $this->labelStatus[self::STATUS_CLOSE] = $langs->trans("SupplierProposalStatusClosed");
|
|
|
- $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans("SupplierProposalStatusDraftShort");
|
|
|
- $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans("Opened");
|
|
|
- $this->labelStatusShort[self::STATUS_SIGNED] = $langs->trans("SupplierProposalStatusSignedShort");
|
|
|
- $this->labelStatusShort[self::STATUS_NOTSIGNED] = $langs->trans("SupplierProposalStatusNotSignedShort");
|
|
|
- $this->labelStatusShort[self::STATUS_CLOSE] = $langs->trans("SupplierProposalStatusClosedShort");
|
|
|
- }
|
|
|
-
|
|
|
- $statusnew = '';
|
|
|
- if ($status == self::STATUS_DRAFT) $statusnew = 'status0';
|
|
|
- elseif ($status == self::STATUS_VALIDATED) $statusnew = 'status1';
|
|
|
- elseif ($status == self::STATUS_SIGNED) $statusnew = 'status4';
|
|
|
- elseif ($status == self::STATUS_NOTSIGNED) $statusnew = 'status9';
|
|
|
- elseif ($status == self::STATUS_CLOSE) $statusnew = 'status6';
|
|
|
-
|
|
|
- return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusnew, $mode);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
|
|
|
- *
|
|
|
- * @param User $user Object user
|
|
|
- * @param int $mode "opened" for askprice to close, "signed" for proposal to invoice
|
|
|
- * @return int <0 if KO, >0 if OK
|
|
|
- */
|
|
|
- public function load_board($user, $mode)
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
- global $conf, $user, $langs;
|
|
|
-
|
|
|
- $now = dol_now();
|
|
|
-
|
|
|
- $this->nbtodo = $this->nbtodolate = 0;
|
|
|
- $clause = " WHERE";
|
|
|
-
|
|
|
- $sql = "SELECT p.rowid, p.ref, p.datec as datec";
|
|
|
- $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p";
|
|
|
- if (!$user->rights->societe->client->voir && !$user->socid)
|
|
|
- {
|
|
|
- $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
|
|
|
- $sql .= " WHERE sc.fk_user = ".$user->id;
|
|
|
- $clause = " AND";
|
|
|
- }
|
|
|
- $sql .= $clause." p.entity IN (".getEntity('supplier_proposal').")";
|
|
|
- if ($mode == 'opened') $sql .= " AND p.fk_statut = 1";
|
|
|
- if ($mode == 'signed') $sql .= " AND p.fk_statut = 2";
|
|
|
- if ($user->socid) $sql .= " AND p.fk_soc = ".$user->socid;
|
|
|
-
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if ($resql)
|
|
|
- {
|
|
|
+ * @return string Label
|
|
|
+ */
|
|
|
+ public function LibStatut($status, $mode = 1)
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+
|
|
|
+ // Init/load array of translation of status
|
|
|
+ if (empty($this->labelStatus) || empty($this->labelStatusShort))
|
|
|
+ {
|
|
|
+ global $langs;
|
|
|
+ $langs->load("supplier_proposal");
|
|
|
+ $this->labelStatus[self::STATUS_DRAFT] = $langs->trans("SupplierProposalStatusDraft");
|
|
|
+ $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans("SupplierProposalStatusValidated");
|
|
|
+ $this->labelStatus[self::STATUS_SIGNED] = $langs->trans("SupplierProposalStatusSigned");
|
|
|
+ $this->labelStatus[self::STATUS_NOTSIGNED] = $langs->trans("SupplierProposalStatusNotSigned");
|
|
|
+ $this->labelStatus[self::STATUS_CLOSE] = $langs->trans("SupplierProposalStatusClosed");
|
|
|
+ $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans("SupplierProposalStatusDraftShort");
|
|
|
+ $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans("Opened");
|
|
|
+ $this->labelStatusShort[self::STATUS_SIGNED] = $langs->trans("SupplierProposalStatusSignedShort");
|
|
|
+ $this->labelStatusShort[self::STATUS_NOTSIGNED] = $langs->trans("SupplierProposalStatusNotSignedShort");
|
|
|
+ $this->labelStatusShort[self::STATUS_CLOSE] = $langs->trans("SupplierProposalStatusClosedShort");
|
|
|
+ }
|
|
|
+
|
|
|
+ $statusnew = '';
|
|
|
+ if ($status == self::STATUS_DRAFT) $statusnew = 'status0';
|
|
|
+ elseif ($status == self::STATUS_VALIDATED) $statusnew = 'status1';
|
|
|
+ elseif ($status == self::STATUS_SIGNED) $statusnew = 'status4';
|
|
|
+ elseif ($status == self::STATUS_NOTSIGNED) $statusnew = 'status9';
|
|
|
+ elseif ($status == self::STATUS_CLOSE) $statusnew = 'status6';
|
|
|
+
|
|
|
+ return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusnew, $mode);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
|
|
|
+ *
|
|
|
+ * @param User $user Object user
|
|
|
+ * @param int $mode "opened" for askprice to close, "signed" for proposal to invoice
|
|
|
+ * @return int <0 if KO, >0 if OK
|
|
|
+ */
|
|
|
+ public function load_board($user, $mode)
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+ global $conf, $user, $langs;
|
|
|
+
|
|
|
+ $now = dol_now();
|
|
|
+
|
|
|
+ $this->nbtodo = $this->nbtodolate = 0;
|
|
|
+ $clause = " WHERE";
|
|
|
+
|
|
|
+ $sql = "SELECT p.rowid, p.ref, p.datec as datec";
|
|
|
+ $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p";
|
|
|
+ if (!$user->rights->societe->client->voir && !$user->socid)
|
|
|
+ {
|
|
|
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
|
|
|
+ $sql .= " WHERE sc.fk_user = ".$user->id;
|
|
|
+ $clause = " AND";
|
|
|
+ }
|
|
|
+ $sql .= $clause." p.entity IN (".getEntity('supplier_proposal').")";
|
|
|
+ if ($mode == 'opened') $sql .= " AND p.fk_statut = 1";
|
|
|
+ if ($mode == 'signed') $sql .= " AND p.fk_statut = 2";
|
|
|
+ if ($user->socid) $sql .= " AND p.fk_soc = ".$user->socid;
|
|
|
+
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if ($resql)
|
|
|
+ {
|
|
|
$label = $labelShort = '';
|
|
|
$status = '';
|
|
|
- if ($mode == 'opened') {
|
|
|
- $delay_warning = $conf->supplier_proposal->cloture->warning_delay;
|
|
|
- $status = self::STATUS_VALIDATED;
|
|
|
- $label = $langs->trans("SupplierProposalsToClose");
|
|
|
- $labelShort = $langs->trans("ToAcceptRefuse");
|
|
|
- }
|
|
|
- if ($mode == 'signed') {
|
|
|
- $delay_warning = $conf->supplier_proposal->facturation->warning_delay;
|
|
|
- $status = self::STATUS_SIGNED;
|
|
|
- $label = $langs->trans("SupplierProposalsToProcess"); // May be billed or ordered
|
|
|
+ if ($mode == 'opened') {
|
|
|
+ $delay_warning = $conf->supplier_proposal->cloture->warning_delay;
|
|
|
+ $status = self::STATUS_VALIDATED;
|
|
|
+ $label = $langs->trans("SupplierProposalsToClose");
|
|
|
+ $labelShort = $langs->trans("ToAcceptRefuse");
|
|
|
+ }
|
|
|
+ if ($mode == 'signed') {
|
|
|
+ $delay_warning = $conf->supplier_proposal->facturation->warning_delay;
|
|
|
+ $status = self::STATUS_SIGNED;
|
|
|
+ $label = $langs->trans("SupplierProposalsToProcess"); // May be billed or ordered
|
|
|
$labelShort = $langs->trans("ToClose");
|
|
|
- }
|
|
|
-
|
|
|
- $response = new WorkboardResponse();
|
|
|
- $response->warning_delay = $delay_warning / 60 / 60 / 24;
|
|
|
- $response->label = $label;
|
|
|
- $response->labelShort = $labelShort;
|
|
|
- $response->url = DOL_URL_ROOT.'/supplier_proposal/list.php?search_status='.$status;
|
|
|
- $response->img = img_object('', "propal");
|
|
|
-
|
|
|
- // This assignment in condition is not a bug. It allows walking the results.
|
|
|
- while ($obj = $this->db->fetch_object($resql))
|
|
|
- {
|
|
|
- $response->nbtodo++;
|
|
|
- if ($mode == 'opened')
|
|
|
- {
|
|
|
- $datelimit = $this->db->jdate($obj->datefin);
|
|
|
- if ($datelimit < ($now - $delay_warning))
|
|
|
- {
|
|
|
- $response->nbtodolate++;
|
|
|
- }
|
|
|
- }
|
|
|
- // TODO Definir regle des propales a facturer en retard
|
|
|
- // if ($mode == 'signed' && ! count($this->FactureListeArray($obj->rowid))) $this->nbtodolate++;
|
|
|
- }
|
|
|
- return $response;
|
|
|
- } else {
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Initialise an instance with random values.
|
|
|
- * Used to build previews or test instances.
|
|
|
- * id must be 0 if object instance is a specimen.
|
|
|
- *
|
|
|
- * @return void
|
|
|
- */
|
|
|
- public function initAsSpecimen()
|
|
|
- {
|
|
|
- global $user, $langs, $conf;
|
|
|
-
|
|
|
- // Load array of products prodids
|
|
|
- $num_prods = 0;
|
|
|
- $prodids = array();
|
|
|
- $sql = "SELECT rowid";
|
|
|
- $sql .= " FROM ".MAIN_DB_PREFIX."product";
|
|
|
- $sql .= " WHERE entity IN (".getEntity('product').")";
|
|
|
- $sql .= $this->db->plimit(100);
|
|
|
-
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if ($resql)
|
|
|
- {
|
|
|
- $num_prods = $this->db->num_rows($resql);
|
|
|
- $i = 0;
|
|
|
- while ($i < $num_prods)
|
|
|
- {
|
|
|
- $i++;
|
|
|
- $row = $this->db->fetch_row($resql);
|
|
|
- $prodids[$i] = $row[0];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Initialise parametres
|
|
|
- $this->id = 0;
|
|
|
- $this->ref = 'SPECIMEN';
|
|
|
- $this->specimen = 1;
|
|
|
- $this->socid = 1;
|
|
|
- $this->date = time();
|
|
|
- $this->cond_reglement_id = 1;
|
|
|
- $this->cond_reglement_code = 'RECEP';
|
|
|
- $this->mode_reglement_id = 7;
|
|
|
- $this->mode_reglement_code = 'CHQ';
|
|
|
- $this->note_public = 'This is a comment (public)';
|
|
|
- $this->note_private = 'This is a comment (private)';
|
|
|
- // Lines
|
|
|
- $nbp = 5;
|
|
|
- $xnbp = 0;
|
|
|
- while ($xnbp < $nbp)
|
|
|
- {
|
|
|
- $line = new SupplierProposalLine($this->db);
|
|
|
- $line->desc = $langs->trans("Description")." ".$xnbp;
|
|
|
- $line->qty = 1;
|
|
|
- $line->subprice = 100;
|
|
|
- $line->tva_tx = 19.6;
|
|
|
- $line->localtax1_tx = 0;
|
|
|
- $line->localtax2_tx = 0;
|
|
|
- if ($xnbp == 2)
|
|
|
- {
|
|
|
- $line->total_ht = 50;
|
|
|
- $line->total_ttc = 59.8;
|
|
|
- $line->total_tva = 9.8;
|
|
|
- $line->remise_percent = 50;
|
|
|
- } else {
|
|
|
- $line->total_ht = 100;
|
|
|
- $line->total_ttc = 119.6;
|
|
|
- $line->total_tva = 19.6;
|
|
|
- $line->remise_percent = 00;
|
|
|
- }
|
|
|
-
|
|
|
- if ($num_prods > 0)
|
|
|
- {
|
|
|
- $prodid = mt_rand(1, $num_prods);
|
|
|
- $line->fk_product = $prodids[$prodid];
|
|
|
- }
|
|
|
-
|
|
|
- $this->lines[$xnbp] = $line;
|
|
|
-
|
|
|
- $this->total_ht += $line->total_ht;
|
|
|
- $this->total_tva += $line->total_tva;
|
|
|
- $this->total_ttc += $line->total_ttc;
|
|
|
-
|
|
|
- $xnbp++;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
- /**
|
|
|
- * Load indicator this->nb of global stats widget
|
|
|
- *
|
|
|
- * @return int <0 if ko, >0 if ok
|
|
|
- */
|
|
|
- public function load_state_board()
|
|
|
- {
|
|
|
- // phpcs:enable
|
|
|
- global $conf, $user;
|
|
|
-
|
|
|
- $this->nb = array();
|
|
|
- $clause = "WHERE";
|
|
|
-
|
|
|
- $sql = "SELECT count(p.rowid) as nb";
|
|
|
- $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p";
|
|
|
- $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid";
|
|
|
- if (!$user->rights->societe->client->voir && !$user->socid)
|
|
|
- {
|
|
|
- $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
|
|
|
- $sql .= " WHERE sc.fk_user = ".$user->id;
|
|
|
- $clause = "AND";
|
|
|
- }
|
|
|
- $sql .= " ".$clause." p.entity IN (".getEntity('supplier_proposal').")";
|
|
|
-
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if ($resql)
|
|
|
- {
|
|
|
- // This assignment in condition is not a bug. It allows walking the results.
|
|
|
- while ($obj = $this->db->fetch_object($resql))
|
|
|
- {
|
|
|
- $this->nb["supplier_proposals"] = $obj->nb;
|
|
|
- }
|
|
|
- $this->db->free($resql);
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- dol_print_error($this->db);
|
|
|
- $this->error = $this->db->lasterror();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the reference to the following non used Proposal used depending on the active numbering module
|
|
|
- * defined into SUPPLIER_PROPOSAL_ADDON
|
|
|
- *
|
|
|
- * @param Societe $soc Object thirdparty
|
|
|
- * @return string Reference libre pour la propale
|
|
|
- */
|
|
|
- public function getNextNumRef($soc)
|
|
|
- {
|
|
|
- global $conf, $db, $langs;
|
|
|
- $langs->load("supplier_proposal");
|
|
|
-
|
|
|
- if (!empty($conf->global->SUPPLIER_PROPOSAL_ADDON))
|
|
|
- {
|
|
|
- $mybool = false;
|
|
|
-
|
|
|
- $file = $conf->global->SUPPLIER_PROPOSAL_ADDON.".php";
|
|
|
- $classname = $conf->global->SUPPLIER_PROPOSAL_ADDON;
|
|
|
-
|
|
|
- // Include file with class
|
|
|
- $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
|
|
|
- foreach ($dirmodels as $reldir) {
|
|
|
- $dir = dol_buildpath($reldir."core/modules/supplier_proposal/");
|
|
|
-
|
|
|
- // Load file with numbering class (if found)
|
|
|
- $mybool |= @include_once $dir.$file;
|
|
|
- }
|
|
|
-
|
|
|
- if (!$mybool)
|
|
|
- {
|
|
|
- dol_print_error('', "Failed to include file ".$file);
|
|
|
- return '';
|
|
|
- }
|
|
|
-
|
|
|
- $obj = new $classname();
|
|
|
- $numref = "";
|
|
|
- $numref = $obj->getNextValue($soc, $this);
|
|
|
-
|
|
|
- if ($numref != "")
|
|
|
- {
|
|
|
- return $numref;
|
|
|
- } else {
|
|
|
- $this->error = $obj->error;
|
|
|
- return "";
|
|
|
- }
|
|
|
- } else {
|
|
|
- $langs->load("errors");
|
|
|
- print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("SupplierProposal"));
|
|
|
- return "";
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Return clicable link of object (with eventually picto)
|
|
|
- *
|
|
|
- * @param int $withpicto Add picto into link
|
|
|
- * @param string $option Where point the link ('compta', 'expedition', 'document', ...)
|
|
|
- * @param string $get_params Parametres added to url
|
|
|
- * @param int $notooltip 1=Disable tooltip
|
|
|
- * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
|
|
|
- * @param int $addlinktonotes Add link to show notes
|
|
|
- * @return string String with URL
|
|
|
- */
|
|
|
- public function getNomUrl($withpicto = 0, $option = '', $get_params = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0)
|
|
|
- {
|
|
|
- global $langs, $conf, $user;
|
|
|
-
|
|
|
- if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
|
|
|
-
|
|
|
- $url = '';
|
|
|
- $result = '';
|
|
|
-
|
|
|
- $label = '<u>'.$langs->trans("SupplierProposal").'</u>';
|
|
|
- if (!empty($this->ref)) $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
|
|
|
- if (!empty($this->ref_fourn)) $label .= '<br><b>'.$langs->trans('RefSupplier').':</b> '.$this->ref_fourn;
|
|
|
- if (!empty($this->total_ht)) $label .= '<br><b>'.$langs->trans('AmountHT').':</b> '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
|
|
|
- if (!empty($this->total_tva)) $label .= '<br><b>'.$langs->trans('VAT').':</b> '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
|
|
|
- if (!empty($this->total_ttc)) $label .= '<br><b>'.$langs->trans('AmountTTC').':</b> '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
|
|
|
- if (isset($this->status)) {
|
|
|
- $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
|
|
|
- }
|
|
|
-
|
|
|
- if ($option == '') {
|
|
|
- $url = DOL_URL_ROOT.'/supplier_proposal/card.php?id='.$this->id.$get_params;
|
|
|
- }
|
|
|
- if ($option == 'document') {
|
|
|
- $url = DOL_URL_ROOT.'/supplier_proposal/document.php?id='.$this->id.$get_params;
|
|
|
- }
|
|
|
-
|
|
|
- if ($option !== 'nolink')
|
|
|
- {
|
|
|
- // Add param to save lastsearch_values or not
|
|
|
- $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
|
|
|
- if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
|
|
|
- if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
|
|
|
- }
|
|
|
-
|
|
|
- $linkclose = '';
|
|
|
- if (empty($notooltip) && $user->rights->propal->lire)
|
|
|
- {
|
|
|
- if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
|
|
|
- {
|
|
|
- $label = $langs->trans("ShowSupplierProposal");
|
|
|
- $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
|
|
|
- }
|
|
|
- $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
|
|
|
- $linkclose .= ' class="classfortooltip"';
|
|
|
- }
|
|
|
-
|
|
|
- $linkstart = '<a href="'.$url.'"';
|
|
|
- $linkstart .= $linkclose.'>';
|
|
|
- $linkend = '</a>';
|
|
|
-
|
|
|
- $result .= $linkstart;
|
|
|
- if ($withpicto) $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
|
|
|
- if ($withpicto != 2) $result .= $this->ref;
|
|
|
- $result .= $linkend;
|
|
|
-
|
|
|
- if ($addlinktonotes)
|
|
|
- {
|
|
|
- $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
|
|
|
- if ($txttoshow)
|
|
|
- {
|
|
|
- $notetoshow = $langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($txttoshow, 1);
|
|
|
- $result .= ' <span class="note inline-block">';
|
|
|
- $result .= '<a href="'.DOL_URL_ROOT.'/supplier_proposal/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
|
|
|
- $result .= img_picto('', 'note');
|
|
|
- $result .= '</a>';
|
|
|
- //$result.=img_picto($langs->trans("ViewNote"),'object_generic');
|
|
|
- //$result.='</a>';
|
|
|
- $result .= '</span>';
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return $result;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Retrieve an array of supplier proposal lines
|
|
|
- *
|
|
|
- * @return int >0 if OK, <0 if KO
|
|
|
- */
|
|
|
- public function getLinesArray()
|
|
|
- {
|
|
|
- // For other object, here we call fetch_lines. But fetch_lines does not exists on supplier proposal
|
|
|
-
|
|
|
- $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,';
|
|
|
- $sql .= ' pt.qty, pt.tva_tx, pt.remise_percent, pt.subprice, pt.info_bits,';
|
|
|
- $sql .= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,';
|
|
|
- $sql .= ' pt.product_type, pt.rang, pt.fk_parent_line,';
|
|
|
- $sql .= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,';
|
|
|
- $sql .= ' p.description as product_desc, pt.ref_fourn as ref_supplier,';
|
|
|
- $sql .= ' pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc, pt.fk_unit';
|
|
|
- $sql .= ' FROM '.MAIN_DB_PREFIX.'supplier_proposaldet as pt';
|
|
|
- $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pt.fk_product=p.rowid';
|
|
|
- $sql .= ' WHERE pt.fk_supplier_proposal = '.$this->id;
|
|
|
- $sql .= ' ORDER BY pt.rang ASC, pt.rowid';
|
|
|
-
|
|
|
- dol_syslog(get_class($this).'::getLinesArray', LOG_DEBUG);
|
|
|
- $resql = $this->db->query($sql);
|
|
|
- if ($resql)
|
|
|
- {
|
|
|
- $num = $this->db->num_rows($resql);
|
|
|
- $i = 0;
|
|
|
-
|
|
|
- while ($i < $num)
|
|
|
- {
|
|
|
- $obj = $this->db->fetch_object($resql);
|
|
|
-
|
|
|
- $this->lines[$i] = new SupplierProposalLine($this->db);
|
|
|
- $this->lines[$i]->id = $obj->rowid; // for backward compatibility
|
|
|
- $this->lines[$i]->rowid = $obj->rowid;
|
|
|
- $this->lines[$i]->label = $obj->custom_label;
|
|
|
- $this->lines[$i]->description = $obj->description;
|
|
|
- $this->lines[$i]->fk_product = $obj->fk_product;
|
|
|
- $this->lines[$i]->ref = $obj->ref;
|
|
|
- $this->lines[$i]->product_label = $obj->product_label;
|
|
|
- $this->lines[$i]->product_desc = $obj->product_desc;
|
|
|
- $this->lines[$i]->fk_product_type = $obj->fk_product_type; // deprecated
|
|
|
- $this->lines[$i]->product_type = $obj->product_type;
|
|
|
- $this->lines[$i]->qty = $obj->qty;
|
|
|
- $this->lines[$i]->subprice = $obj->subprice;
|
|
|
- $this->lines[$i]->fk_remise_except = $obj->fk_remise_except;
|
|
|
- $this->lines[$i]->remise_percent = $obj->remise_percent;
|
|
|
- $this->lines[$i]->tva_tx = $obj->tva_tx;
|
|
|
- $this->lines[$i]->info_bits = $obj->info_bits;
|
|
|
- $this->lines[$i]->total_ht = $obj->total_ht;
|
|
|
- $this->lines[$i]->total_tva = $obj->total_tva;
|
|
|
- $this->lines[$i]->total_ttc = $obj->total_ttc;
|
|
|
- $this->lines[$i]->fk_fournprice = $obj->fk_fournprice;
|
|
|
- $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht);
|
|
|
- $this->lines[$i]->pa_ht = $marginInfos[0];
|
|
|
- $this->lines[$i]->marge_tx = $marginInfos[1];
|
|
|
- $this->lines[$i]->marque_tx = $marginInfos[2];
|
|
|
- $this->lines[$i]->fk_parent_line = $obj->fk_parent_line;
|
|
|
- $this->lines[$i]->special_code = $obj->special_code;
|
|
|
- $this->lines[$i]->rang = $obj->rang;
|
|
|
-
|
|
|
- $this->lines[$i]->ref_fourn = $obj->ref_supplier; // deprecated
|
|
|
- $this->lines[$i]->ref_supplier = $obj->ref_supplier;
|
|
|
-
|
|
|
- // Multicurrency
|
|
|
- $this->lines[$i]->fk_multicurrency = $obj->fk_multicurrency;
|
|
|
- $this->lines[$i]->multicurrency_code = $obj->multicurrency_code;
|
|
|
- $this->lines[$i]->multicurrency_subprice = $obj->multicurrency_subprice;
|
|
|
- $this->lines[$i]->multicurrency_total_ht = $obj->multicurrency_total_ht;
|
|
|
- $this->lines[$i]->multicurrency_total_tva = $obj->multicurrency_total_tva;
|
|
|
- $this->lines[$i]->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
|
|
|
- $this->lines[$i]->fk_unit = $obj->fk_unit;
|
|
|
-
|
|
|
- $i++;
|
|
|
- }
|
|
|
- $this->db->free($resql);
|
|
|
-
|
|
|
- return 1;
|
|
|
- } else {
|
|
|
- $this->error = $this->db->error();
|
|
|
- return -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Create a document onto disk according to template module.
|
|
|
- *
|
|
|
- * @param string $modele Force model to use ('' to not force)
|
|
|
- * @param Translate $outputlangs Object langs to use for output
|
|
|
- * @param int $hidedetails Hide details of lines
|
|
|
- * @param int $hidedesc Hide description
|
|
|
- * @param int $hideref Hide ref
|
|
|
- * @param null|array $moreparams Array to provide more information
|
|
|
- * @return int 0 if KO, 1 if OK
|
|
|
- */
|
|
|
- public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
|
|
|
- {
|
|
|
- global $conf, $langs;
|
|
|
-
|
|
|
- $langs->load("supplier_proposal");
|
|
|
+ }
|
|
|
+
|
|
|
+ $response = new WorkboardResponse();
|
|
|
+ $response->warning_delay = $delay_warning / 60 / 60 / 24;
|
|
|
+ $response->label = $label;
|
|
|
+ $response->labelShort = $labelShort;
|
|
|
+ $response->url = DOL_URL_ROOT.'/supplier_proposal/list.php?search_status='.$status;
|
|
|
+ $response->img = img_object('', "propal");
|
|
|
+
|
|
|
+ // This assignment in condition is not a bug. It allows walking the results.
|
|
|
+ while ($obj = $this->db->fetch_object($resql))
|
|
|
+ {
|
|
|
+ $response->nbtodo++;
|
|
|
+ if ($mode == 'opened')
|
|
|
+ {
|
|
|
+ $datelimit = $this->db->jdate($obj->datefin);
|
|
|
+ if ($datelimit < ($now - $delay_warning))
|
|
|
+ {
|
|
|
+ $response->nbtodolate++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // TODO Definir regle des propales a facturer en retard
|
|
|
+ // if ($mode == 'signed' && ! count($this->FactureListeArray($obj->rowid))) $this->nbtodolate++;
|
|
|
+ }
|
|
|
+ return $response;
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Initialise an instance with random values.
|
|
|
+ * Used to build previews or test instances.
|
|
|
+ * id must be 0 if object instance is a specimen.
|
|
|
+ *
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ public function initAsSpecimen()
|
|
|
+ {
|
|
|
+ global $user, $langs, $conf;
|
|
|
+
|
|
|
+ // Load array of products prodids
|
|
|
+ $num_prods = 0;
|
|
|
+ $prodids = array();
|
|
|
+ $sql = "SELECT rowid";
|
|
|
+ $sql .= " FROM ".MAIN_DB_PREFIX."product";
|
|
|
+ $sql .= " WHERE entity IN (".getEntity('product').")";
|
|
|
+ $sql .= $this->db->plimit(100);
|
|
|
+
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if ($resql)
|
|
|
+ {
|
|
|
+ $num_prods = $this->db->num_rows($resql);
|
|
|
+ $i = 0;
|
|
|
+ while ($i < $num_prods)
|
|
|
+ {
|
|
|
+ $i++;
|
|
|
+ $row = $this->db->fetch_row($resql);
|
|
|
+ $prodids[$i] = $row[0];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Initialise parametres
|
|
|
+ $this->id = 0;
|
|
|
+ $this->ref = 'SPECIMEN';
|
|
|
+ $this->specimen = 1;
|
|
|
+ $this->socid = 1;
|
|
|
+ $this->date = time();
|
|
|
+ $this->cond_reglement_id = 1;
|
|
|
+ $this->cond_reglement_code = 'RECEP';
|
|
|
+ $this->mode_reglement_id = 7;
|
|
|
+ $this->mode_reglement_code = 'CHQ';
|
|
|
+ $this->note_public = 'This is a comment (public)';
|
|
|
+ $this->note_private = 'This is a comment (private)';
|
|
|
+ // Lines
|
|
|
+ $nbp = 5;
|
|
|
+ $xnbp = 0;
|
|
|
+ while ($xnbp < $nbp)
|
|
|
+ {
|
|
|
+ $line = new SupplierProposalLine($this->db);
|
|
|
+ $line->desc = $langs->trans("Description")." ".$xnbp;
|
|
|
+ $line->qty = 1;
|
|
|
+ $line->subprice = 100;
|
|
|
+ $line->tva_tx = 19.6;
|
|
|
+ $line->localtax1_tx = 0;
|
|
|
+ $line->localtax2_tx = 0;
|
|
|
+ if ($xnbp == 2)
|
|
|
+ {
|
|
|
+ $line->total_ht = 50;
|
|
|
+ $line->total_ttc = 59.8;
|
|
|
+ $line->total_tva = 9.8;
|
|
|
+ $line->remise_percent = 50;
|
|
|
+ } else {
|
|
|
+ $line->total_ht = 100;
|
|
|
+ $line->total_ttc = 119.6;
|
|
|
+ $line->total_tva = 19.6;
|
|
|
+ $line->remise_percent = 00;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($num_prods > 0)
|
|
|
+ {
|
|
|
+ $prodid = mt_rand(1, $num_prods);
|
|
|
+ $line->fk_product = $prodids[$prodid];
|
|
|
+ }
|
|
|
+
|
|
|
+ $this->lines[$xnbp] = $line;
|
|
|
+
|
|
|
+ $this->total_ht += $line->total_ht;
|
|
|
+ $this->total_tva += $line->total_tva;
|
|
|
+ $this->total_ttc += $line->total_ttc;
|
|
|
+
|
|
|
+ $xnbp++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
|
|
+ /**
|
|
|
+ * Load indicator this->nb of global stats widget
|
|
|
+ *
|
|
|
+ * @return int <0 if ko, >0 if ok
|
|
|
+ */
|
|
|
+ public function load_state_board()
|
|
|
+ {
|
|
|
+ // phpcs:enable
|
|
|
+ global $conf, $user;
|
|
|
+
|
|
|
+ $this->nb = array();
|
|
|
+ $clause = "WHERE";
|
|
|
+
|
|
|
+ $sql = "SELECT count(p.rowid) as nb";
|
|
|
+ $sql .= " FROM ".MAIN_DB_PREFIX."supplier_proposal as p";
|
|
|
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON p.fk_soc = s.rowid";
|
|
|
+ if (!$user->rights->societe->client->voir && !$user->socid)
|
|
|
+ {
|
|
|
+ $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON s.rowid = sc.fk_soc";
|
|
|
+ $sql .= " WHERE sc.fk_user = ".$user->id;
|
|
|
+ $clause = "AND";
|
|
|
+ }
|
|
|
+ $sql .= " ".$clause." p.entity IN (".getEntity('supplier_proposal').")";
|
|
|
+
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if ($resql)
|
|
|
+ {
|
|
|
+ // This assignment in condition is not a bug. It allows walking the results.
|
|
|
+ while ($obj = $this->db->fetch_object($resql))
|
|
|
+ {
|
|
|
+ $this->nb["supplier_proposals"] = $obj->nb;
|
|
|
+ }
|
|
|
+ $this->db->free($resql);
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ dol_print_error($this->db);
|
|
|
+ $this->error = $this->db->lasterror();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Returns the reference to the following non used Proposal used depending on the active numbering module
|
|
|
+ * defined into SUPPLIER_PROPOSAL_ADDON
|
|
|
+ *
|
|
|
+ * @param Societe $soc Object thirdparty
|
|
|
+ * @return string Reference libre pour la propale
|
|
|
+ */
|
|
|
+ public function getNextNumRef($soc)
|
|
|
+ {
|
|
|
+ global $conf, $db, $langs;
|
|
|
+ $langs->load("supplier_proposal");
|
|
|
+
|
|
|
+ if (!empty($conf->global->SUPPLIER_PROPOSAL_ADDON))
|
|
|
+ {
|
|
|
+ $mybool = false;
|
|
|
+
|
|
|
+ $file = $conf->global->SUPPLIER_PROPOSAL_ADDON.".php";
|
|
|
+ $classname = $conf->global->SUPPLIER_PROPOSAL_ADDON;
|
|
|
+
|
|
|
+ // Include file with class
|
|
|
+ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
|
|
|
+ foreach ($dirmodels as $reldir) {
|
|
|
+ $dir = dol_buildpath($reldir."core/modules/supplier_proposal/");
|
|
|
+
|
|
|
+ // Load file with numbering class (if found)
|
|
|
+ $mybool |= @include_once $dir.$file;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!$mybool)
|
|
|
+ {
|
|
|
+ dol_print_error('', "Failed to include file ".$file);
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+
|
|
|
+ $obj = new $classname();
|
|
|
+ $numref = "";
|
|
|
+ $numref = $obj->getNextValue($soc, $this);
|
|
|
+
|
|
|
+ if ($numref != "")
|
|
|
+ {
|
|
|
+ return $numref;
|
|
|
+ } else {
|
|
|
+ $this->error = $obj->error;
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $langs->load("errors");
|
|
|
+ print $langs->trans("Error")." ".$langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("SupplierProposal"));
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Return clicable link of object (with eventually picto)
|
|
|
+ *
|
|
|
+ * @param int $withpicto Add picto into link
|
|
|
+ * @param string $option Where point the link ('compta', 'expedition', 'document', ...)
|
|
|
+ * @param string $get_params Parametres added to url
|
|
|
+ * @param int $notooltip 1=Disable tooltip
|
|
|
+ * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
|
|
|
+ * @param int $addlinktonotes Add link to show notes
|
|
|
+ * @return string String with URL
|
|
|
+ */
|
|
|
+ public function getNomUrl($withpicto = 0, $option = '', $get_params = '', $notooltip = 0, $save_lastsearch_value = -1, $addlinktonotes = 0)
|
|
|
+ {
|
|
|
+ global $langs, $conf, $user;
|
|
|
+
|
|
|
+ if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips
|
|
|
+
|
|
|
+ $url = '';
|
|
|
+ $result = '';
|
|
|
+
|
|
|
+ $label = '<u>'.$langs->trans("SupplierProposal").'</u>';
|
|
|
+ if (!empty($this->ref)) $label .= '<br><b>'.$langs->trans('Ref').':</b> '.$this->ref;
|
|
|
+ if (!empty($this->ref_fourn)) $label .= '<br><b>'.$langs->trans('RefSupplier').':</b> '.$this->ref_fourn;
|
|
|
+ if (!empty($this->total_ht)) $label .= '<br><b>'.$langs->trans('AmountHT').':</b> '.price($this->total_ht, 0, $langs, 0, -1, -1, $conf->currency);
|
|
|
+ if (!empty($this->total_tva)) $label .= '<br><b>'.$langs->trans('VAT').':</b> '.price($this->total_tva, 0, $langs, 0, -1, -1, $conf->currency);
|
|
|
+ if (!empty($this->total_ttc)) $label .= '<br><b>'.$langs->trans('AmountTTC').':</b> '.price($this->total_ttc, 0, $langs, 0, -1, -1, $conf->currency);
|
|
|
+ if (isset($this->status)) {
|
|
|
+ $label .= '<br><b>'.$langs->trans("Status").":</b> ".$this->getLibStatut(5);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($option == '') {
|
|
|
+ $url = DOL_URL_ROOT.'/supplier_proposal/card.php?id='.$this->id.$get_params;
|
|
|
+ }
|
|
|
+ if ($option == 'document') {
|
|
|
+ $url = DOL_URL_ROOT.'/supplier_proposal/document.php?id='.$this->id.$get_params;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($option !== 'nolink')
|
|
|
+ {
|
|
|
+ // Add param to save lastsearch_values or not
|
|
|
+ $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
|
|
|
+ if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) $add_save_lastsearch_values = 1;
|
|
|
+ if ($add_save_lastsearch_values) $url .= '&save_lastsearch_values=1';
|
|
|
+ }
|
|
|
+
|
|
|
+ $linkclose = '';
|
|
|
+ if (empty($notooltip) && $user->rights->propal->lire)
|
|
|
+ {
|
|
|
+ if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
|
|
|
+ {
|
|
|
+ $label = $langs->trans("ShowSupplierProposal");
|
|
|
+ $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"';
|
|
|
+ }
|
|
|
+ $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"';
|
|
|
+ $linkclose .= ' class="classfortooltip"';
|
|
|
+ }
|
|
|
+
|
|
|
+ $linkstart = '<a href="'.$url.'"';
|
|
|
+ $linkstart .= $linkclose.'>';
|
|
|
+ $linkend = '</a>';
|
|
|
+
|
|
|
+ $result .= $linkstart;
|
|
|
+ if ($withpicto) $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1);
|
|
|
+ if ($withpicto != 2) $result .= $this->ref;
|
|
|
+ $result .= $linkend;
|
|
|
+
|
|
|
+ if ($addlinktonotes)
|
|
|
+ {
|
|
|
+ $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private);
|
|
|
+ if ($txttoshow)
|
|
|
+ {
|
|
|
+ $notetoshow = $langs->trans("ViewPrivateNote").':<br>'.dol_string_nohtmltag($txttoshow, 1);
|
|
|
+ $result .= ' <span class="note inline-block">';
|
|
|
+ $result .= '<a href="'.DOL_URL_ROOT.'/supplier_proposal/note.php?id='.$this->id.'" class="classfortooltip" title="'.dol_escape_htmltag($notetoshow).'">';
|
|
|
+ $result .= img_picto('', 'note');
|
|
|
+ $result .= '</a>';
|
|
|
+ //$result.=img_picto($langs->trans("ViewNote"),'object_generic');
|
|
|
+ //$result.='</a>';
|
|
|
+ $result .= '</span>';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Retrieve an array of supplier proposal lines
|
|
|
+ *
|
|
|
+ * @return int >0 if OK, <0 if KO
|
|
|
+ */
|
|
|
+ public function getLinesArray()
|
|
|
+ {
|
|
|
+ // For other object, here we call fetch_lines. But fetch_lines does not exists on supplier proposal
|
|
|
+
|
|
|
+ $sql = 'SELECT pt.rowid, pt.label as custom_label, pt.description, pt.fk_product, pt.fk_remise_except,';
|
|
|
+ $sql .= ' pt.qty, pt.tva_tx, pt.remise_percent, pt.subprice, pt.info_bits,';
|
|
|
+ $sql .= ' pt.total_ht, pt.total_tva, pt.total_ttc, pt.fk_product_fournisseur_price as fk_fournprice, pt.buy_price_ht as pa_ht, pt.special_code, pt.localtax1_tx, pt.localtax2_tx,';
|
|
|
+ $sql .= ' pt.product_type, pt.rang, pt.fk_parent_line,';
|
|
|
+ $sql .= ' p.label as product_label, p.ref, p.fk_product_type, p.rowid as prodid,';
|
|
|
+ $sql .= ' p.description as product_desc, pt.ref_fourn as ref_supplier,';
|
|
|
+ $sql .= ' pt.fk_multicurrency, pt.multicurrency_code, pt.multicurrency_subprice, pt.multicurrency_total_ht, pt.multicurrency_total_tva, pt.multicurrency_total_ttc, pt.fk_unit';
|
|
|
+ $sql .= ' FROM '.MAIN_DB_PREFIX.'supplier_proposaldet as pt';
|
|
|
+ $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON pt.fk_product=p.rowid';
|
|
|
+ $sql .= ' WHERE pt.fk_supplier_proposal = '.$this->id;
|
|
|
+ $sql .= ' ORDER BY pt.rang ASC, pt.rowid';
|
|
|
+
|
|
|
+ dol_syslog(get_class($this).'::getLinesArray', LOG_DEBUG);
|
|
|
+ $resql = $this->db->query($sql);
|
|
|
+ if ($resql)
|
|
|
+ {
|
|
|
+ $num = $this->db->num_rows($resql);
|
|
|
+ $i = 0;
|
|
|
+
|
|
|
+ while ($i < $num)
|
|
|
+ {
|
|
|
+ $obj = $this->db->fetch_object($resql);
|
|
|
+
|
|
|
+ $this->lines[$i] = new SupplierProposalLine($this->db);
|
|
|
+ $this->lines[$i]->id = $obj->rowid; // for backward compatibility
|
|
|
+ $this->lines[$i]->rowid = $obj->rowid;
|
|
|
+ $this->lines[$i]->label = $obj->custom_label;
|
|
|
+ $this->lines[$i]->description = $obj->description;
|
|
|
+ $this->lines[$i]->fk_product = $obj->fk_product;
|
|
|
+ $this->lines[$i]->ref = $obj->ref;
|
|
|
+ $this->lines[$i]->product_label = $obj->product_label;
|
|
|
+ $this->lines[$i]->product_desc = $obj->product_desc;
|
|
|
+ $this->lines[$i]->fk_product_type = $obj->fk_product_type; // deprecated
|
|
|
+ $this->lines[$i]->product_type = $obj->product_type;
|
|
|
+ $this->lines[$i]->qty = $obj->qty;
|
|
|
+ $this->lines[$i]->subprice = $obj->subprice;
|
|
|
+ $this->lines[$i]->fk_remise_except = $obj->fk_remise_except;
|
|
|
+ $this->lines[$i]->remise_percent = $obj->remise_percent;
|
|
|
+ $this->lines[$i]->tva_tx = $obj->tva_tx;
|
|
|
+ $this->lines[$i]->info_bits = $obj->info_bits;
|
|
|
+ $this->lines[$i]->total_ht = $obj->total_ht;
|
|
|
+ $this->lines[$i]->total_tva = $obj->total_tva;
|
|
|
+ $this->lines[$i]->total_ttc = $obj->total_ttc;
|
|
|
+ $this->lines[$i]->fk_fournprice = $obj->fk_fournprice;
|
|
|
+ $marginInfos = getMarginInfos($obj->subprice, $obj->remise_percent, $obj->tva_tx, $obj->localtax1_tx, $obj->localtax2_tx, $this->lines[$i]->fk_fournprice, $obj->pa_ht);
|
|
|
+ $this->lines[$i]->pa_ht = $marginInfos[0];
|
|
|
+ $this->lines[$i]->marge_tx = $marginInfos[1];
|
|
|
+ $this->lines[$i]->marque_tx = $marginInfos[2];
|
|
|
+ $this->lines[$i]->fk_parent_line = $obj->fk_parent_line;
|
|
|
+ $this->lines[$i]->special_code = $obj->special_code;
|
|
|
+ $this->lines[$i]->rang = $obj->rang;
|
|
|
+
|
|
|
+ $this->lines[$i]->ref_fourn = $obj->ref_supplier; // deprecated
|
|
|
+ $this->lines[$i]->ref_supplier = $obj->ref_supplier;
|
|
|
+
|
|
|
+ // Multicurrency
|
|
|
+ $this->lines[$i]->fk_multicurrency = $obj->fk_multicurrency;
|
|
|
+ $this->lines[$i]->multicurrency_code = $obj->multicurrency_code;
|
|
|
+ $this->lines[$i]->multicurrency_subprice = $obj->multicurrency_subprice;
|
|
|
+ $this->lines[$i]->multicurrency_total_ht = $obj->multicurrency_total_ht;
|
|
|
+ $this->lines[$i]->multicurrency_total_tva = $obj->multicurrency_total_tva;
|
|
|
+ $this->lines[$i]->multicurrency_total_ttc = $obj->multicurrency_total_ttc;
|
|
|
+ $this->lines[$i]->fk_unit = $obj->fk_unit;
|
|
|
+
|
|
|
+ $i++;
|
|
|
+ }
|
|
|
+ $this->db->free($resql);
|
|
|
+
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ $this->error = $this->db->error();
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Create a document onto disk according to template module.
|
|
|
+ *
|
|
|
+ * @param string $modele Force model to use ('' to not force)
|
|
|
+ * @param Translate $outputlangs Object langs to use for output
|
|
|
+ * @param int $hidedetails Hide details of lines
|
|
|
+ * @param int $hidedesc Hide description
|
|
|
+ * @param int $hideref Hide ref
|
|
|
+ * @param null|array $moreparams Array to provide more information
|
|
|
+ * @return int 0 if KO, 1 if OK
|
|
|
+ */
|
|
|
+ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
|
|
|
+ {
|
|
|
+ global $conf, $langs;
|
|
|
+
|
|
|
+ $langs->load("supplier_proposal");
|
|
|
$outputlangs->load("products");
|
|
|
|
|
|
- if (!dol_strlen($modele)) {
|
|
|
- $modele = 'aurore';
|
|
|
-
|
|
|
- if ($this->modelpdf) {
|
|
|
- $modele = $this->modelpdf;
|
|
|
- } elseif (!empty($conf->global->SUPPLIER_PROPOSAL_ADDON_PDF)) {
|
|
|
- $modele = $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- $modelpath = "core/modules/supplier_proposal/doc/";
|
|
|
-
|
|
|
- return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * Function used to replace a thirdparty id with another one.
|
|
|
- *
|
|
|
- * @param DoliDB $db Database handler
|
|
|
- * @param int $origin_id Old thirdparty id
|
|
|
- * @param int $dest_id New thirdparty id
|
|
|
- * @return bool
|
|
|
- */
|
|
|
- public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
|
|
|
- {
|
|
|
- $tables = array(
|
|
|
- 'supplier_proposal'
|
|
|
- );
|
|
|
-
|
|
|
- return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
|
|
|
- }
|
|
|
+ if (!dol_strlen($modele)) {
|
|
|
+ $modele = 'aurore';
|
|
|
+
|
|
|
+ if ($this->modelpdf) {
|
|
|
+ $modele = $this->modelpdf;
|
|
|
+ } elseif (!empty($conf->global->SUPPLIER_PROPOSAL_ADDON_PDF)) {
|
|
|
+ $modele = $conf->global->SUPPLIER_PROPOSAL_ADDON_PDF;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $modelpath = "core/modules/supplier_proposal/doc/";
|
|
|
+
|
|
|
+ return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Function used to replace a thirdparty id with another one.
|
|
|
+ *
|
|
|
+ * @param DoliDB $db Database handler
|
|
|
+ * @param int $origin_id Old thirdparty id
|
|
|
+ * @param int $dest_id New thirdparty id
|
|
|
+ * @return bool
|
|
|
+ */
|
|
|
+ public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
|
|
|
+ {
|
|
|
+ $tables = array(
|
|
|
+ 'supplier_proposal'
|
|
|
+ );
|
|
|
+
|
|
|
+ return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|