/** * Add order line * * @param string $desc Description * @param float $pu_ht Unit price * @param float $qty Quantity * @param float $txtva Taux tva * @param float $txlocaltax1 Localtax1 tax * @param float $txlocaltax2 Localtax2 tax * @param int $fk_product Id produit * @param int $fk_prod_fourn_price Id supplier price * @param string $fourn_ref Supplier reference * @param float $remise_percent Remise * @param string $price_base_type HT or TTC * @param float $pu_ttc Unit price TTC * @param int $type Type of line (0=product, 1=service) * @param int $info_bits More information * @param bool $notrigger Disable triggers * @param int $date_start Date start of service * @param int $date_end Date end of service * @param array $array_options extrafields array * @param string $fk_unit Code of the unit to use. Null to use the default one * @return int <=0 if KO, >0 if OK */ function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $fk_prod_fourn_price = 0, $fourn_ref = '', $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $type = 0, $info_bits = 0, $notrigger = false, $date_start = null, $date_end = null, $array_options = 0, $fk_unit = null) { global $langs, $mysoc, $conf; $error = 0; dol_syslog(get_class($this) . "::addline {$desc}, {$pu_ht}, {$qty}, {$txtva}, {$txlocaltax1}, {$txlocaltax2}. {$fk_product}, {$fk_prod_fourn_price}, {$fourn_ref}, {$remise_percent}, {$price_base_type}, {$pu_ttc}, {$type}, {$fk_unit}"); include_once DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php'; // Clean parameters if (!$qty) { $qty = 1; } if (!$info_bits) { $info_bits = 0; } if (empty($txtva)) { $txtva = 0; } if (empty($txlocaltax1)) { $txlocaltax1 = 0; } if (empty($txlocaltax2)) { $txlocaltax2 = 0; } if (empty($remise_percent)) { $remise_percent = 0; } $remise_percent = price2num($remise_percent); $qty = price2num($qty); $pu_ht = price2num($pu_ht); $pu_ttc = price2num($pu_ttc); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); if ($price_base_type == 'HT') { $pu = $pu_ht; } else { $pu = $pu_ttc; } $desc = trim($desc); // Check parameters if ($qty < 1 && !$fk_product) { $this->error = $langs->trans("ErrorFieldRequired", $langs->trans("Product")); return -1; } if ($type < 0) { return -1; } if ($this->statut == 0) { $this->db->begin(); if ($fk_product > 0) { $prod = new Product($this->db, $fk_product); if ($prod->fetch($fk_product) > 0) { $result = $prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, $fourn_ref); if ($result > 0) { $label = $prod->libelle; $pu = $prod->fourn_pu; $ref = $prod->ref_fourn; $product_type = $prod->type; } if ($result == 0 || $result == -1) { $langs->load("errors"); $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); $this->db->rollback(); dol_syslog(get_class($this) . "::addline result=" . $result . " - " . $this->error, LOG_DEBUG); return -1; } if ($result < -1) { $this->error = $prod->error; $this->db->rollback(); dol_syslog(get_class($this) . "::addline result=" . $result . " - " . $this->error, LOG_ERR); return -1; } } else { $this->error = $prod->error; return -1; } } else { $product_type = $type; } // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $localtaxes_type = getLocalTaxesFromRate($txtva, 0, $mysoc, $this->thirdparty); $txtva = preg_replace('/\\s*\\(.*\\)/', '', $txtva); // Remove code into vatrate. $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits, $product_type, $this->thirdparty, $localtaxes_type); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; $localtax1_type = $localtaxes_type[0]; $localtax2_type = $localtaxes_type[2]; $subprice = price2num($pu, 'MU'); $sql = "INSERT INTO " . MAIN_DB_PREFIX . "commande_fournisseurdet"; $sql .= " (fk_commande, label, description, date_start, date_end,"; $sql .= " fk_product, product_type,"; $sql .= " qty, tva_tx, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, remise_percent, subprice, ref,"; $sql .= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc, fk_unit"; $sql .= ")"; $sql .= " VALUES (" . $this->id . ", '" . $this->db->escape($label) . "','" . $this->db->escape($desc) . "',"; $sql .= " " . ($date_start ? "'" . $this->db->idate($date_start) . "'" : "null") . ","; $sql .= " " . ($date_end ? "'" . $this->db->idate($date_end) . "'" : "null") . ","; if ($fk_product) { $sql .= $fk_product . ","; } else { $sql .= "null,"; } $sql .= "'" . $product_type . "',"; $sql .= "'" . $qty . "', " . $txtva . ", " . $txlocaltax1 . ", " . $txlocaltax2; $sql .= ", '" . $localtax1_type . "',"; $sql .= " '" . $localtax2_type . "'"; $sql .= ", " . $remise_percent . ",'" . price2num($subprice, 'MU') . "','" . $ref . "',"; $sql .= "'" . price2num($total_ht) . "',"; $sql .= "'" . price2num($total_tva) . "',"; $sql .= "'" . price2num($total_localtax1) . "',"; $sql .= "'" . price2num($total_localtax2) . "',"; $sql .= "'" . price2num($total_ttc) . "',"; $sql .= $fk_unit ? "'" . $this->db->escape($fk_unit) . "'" : "null"; $sql .= ")"; dol_syslog(get_class($this) . "::addline", LOG_DEBUG); $resql = $this->db->query($sql); //print $sql; if ($resql) { $this->rowid = $this->db->last_insert_id(MAIN_DB_PREFIX . 'commande_fournisseurdet'); if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { $linetmp = new CommandeFournisseurLigne($this->db); $linetmp->id = $this->rowid; $linetmp->array_options = $array_options; $result = $linetmp->insertExtraFields(); if ($result < 0) { $error++; } } if (!$error && !$notrigger) { global $conf, $langs, $user; // Call trigger $result = $this->call_trigger('LINEORDER_SUPPLIER_CREATE', $user); if ($result < 0) { $this->db->rollback(); return -1; } // End call triggers } $this->update_price('', 'auto'); $this->db->commit(); return 1; } else { $this->error = $this->db->error(); $this->db->rollback(); return -1; } } }
/** * Add order line * @param desc Description * @param pu_ht Unit price * @param qty Quantity * @param txtva Taux tva * @param txlocaltax1 Localtax1 tax * @param txlocaltax2 Localtax2 tax * @param fk_product Id produit * @param fk_prod_fourn_price Id supplier price * @param fourn_ref Supplier reference * @param remise_percent Remise * @param price_base_type HT or TTC * @param pu_ttc Unit price TTC * @param type Type of line (0=product, 1=service) * @return int <=0 if KO, >0 if OK */ function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $fk_prod_fourn_price=0, $fourn_ref='', $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $type=0) { global $langs,$mysoc; dol_syslog("FournisseurCommande::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2. $fk_product, $fk_prod_fourn_price, $fourn_ref, $remise_percent, $price_base_type, $pu_ttc, $type"); include_once(DOL_DOCUMENT_ROOT.'/lib/price.lib.php'); // Clean parameters if (! $qty) $qty=1; if (! $info_bits) $info_bits=0; if (empty($txtva)) $txtva=0; if (empty($txlocaltax1)) $txlocaltax1=0; if (empty($txlocaltax2)) $txlocaltax2=0; $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu_ht=price2num($pu_ht); $pu_ttc=price2num($pu_ttc); $txtva = price2num($txtva); $txlocaltax1 = price2num($txlocaltax1); $txlocaltax2 = price2num($txlocaltax2); if ($price_base_type=='HT') { $pu=$pu_ht; } else { $pu=$pu_ttc; } $desc=trim($desc); // Check parameters if ($qty < 1 && ! $fk_product) { $this->error=$langs->trans("ErrorFieldRequired",$langs->trans("Product")); return -1; } if ($type < 0) return -1; if ($this->statut == 0) { $this->db->begin(); if ($fk_product > 0) { $prod = new Product($this->db, $fk_product); if ($prod->fetch($fk_product) > 0) { $result=$prod->get_buyprice($fk_prod_fourn_price,$qty,$fk_product,$fourn_ref); if ($result > 0) { $label = $prod->libelle; $pu = $prod->fourn_pu; $ref = $prod->ref_fourn; $product_type = $prod->type; } if ($result == 0 || $result == -1) { $this->error="No price found for this quantity. Quantity may be too low ?"; $this->db->rollback(); dol_syslog("FournisseurCommande::addline result=".$result." - ".$this->error, LOG_DEBUG); return -1; } if ($result < -1) { $this->error=$prod->error; $this->db->rollback(); dol_syslog("Fournisseur.commande::addline result=".$result." - ".$this->error, LOG_ERR); return -1; } } else { $this->error=$this->db->error(); return -1; } } else { $product_type = $type; } // Calcul du total TTC et de la TVA pour la ligne a partir de // qty, pu, remise_percent et txtva // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva. $tabprice = calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits); $total_ht = $tabprice[0]; $total_tva = $tabprice[1]; $total_ttc = $tabprice[2]; $total_localtax1 = $tabprice[9]; $total_localtax2 = $tabprice[10]; $subprice = price2num($pu,'MU'); // TODO A virer // Anciens indicateurs: $price, $remise (a ne plus utiliser) $remise = 0; if ($remise_percent > 0) { $remise = round(($pu * $remise_percent / 100), 2); } $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseurdet"; $sql.= " (fk_commande,label, description,"; $sql.= " fk_product, product_type,"; $sql.= " qty, tva_tx, localtax1_tx, localtax2_tx, remise_percent, subprice, remise, ref,"; $sql.= " total_ht, total_tva, total_localtax1, total_localtax2, total_ttc"; $sql.= ")"; $sql.= " VALUES (".$this->id.", '" . $this->db->escape($label) . "','" . $this->db->escape($desc) . "',"; if ($fk_product) { $sql.= $fk_product.","; } else { $sql.= "null,"; } $sql.= "'".$product_type."',"; $sql.= "'".$qty."', ".$txtva.", ".$txlocaltax1.", ".$txlocaltax2.", ".$remise_percent.",'".price2num($subprice,'MU')."','".price2num($remise)."','".$ref."',"; $sql.= "'".price2num($total_ht)."',"; $sql.= "'".price2num($total_tva)."',"; $sql.= "'".price2num($total_localtax1)."',"; $sql.= "'".price2num($total_localtax2)."',"; $sql.= "'".price2num($total_ttc)."'"; $sql.= ")"; dol_syslog('FournisseurCommande::addline sql='.$sql); $resql=$this->db->query($sql); //print $sql; if ($resql) { $this->update_price(); $this->db->commit(); return 1; } else { $this->error=$this->db->error(); $this->db->rollback(); dol_syslog('FournisseurCommande::addline '.$this->error, LOG_ERR); return -1; } } }
/** * Return vat rate of a product in a particular selling country or default country vat if product is unknown * * @param int $idprod Id of product or 0 if not a predefined product * @param Societe $thirdparty_seller Thirdparty with a ->country_code defined (FR, US, IT, ...) * @param int $idprodfournprice Id product_fournisseur_price (for "supplier" order/invoice) * @return int <0 if KO, Vat rate if OK * @see get_product_localtax_for_country */ function get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice = 0) { global $db, $conf, $mysoc; require_once DOL_DOCUMENT_ROOT . '/product/class/product.class.php'; $ret = 0; $found = 0; if ($idprod > 0) { // Load product $product = new Product($db); $result = $product->fetch($idprod); if ($mysoc->country_code == $thirdparty_seller->country_code) { if ($idprodfournprice > 0) { $product->get_buyprice($idprodfournprice, 0, 0, 0); $ret = $product->vatrate_supplier; } else { $ret = $product->tva_tx; // Default vat of product we defined } $found = 1; } else { // TODO Read default product vat according to countrycode and product } } if (!$found) { if (empty($conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS)) { // If vat of product for the country not found or not defined, we return higher vat of country. $sql = "SELECT taux as vat_rate"; $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c"; $sql .= " WHERE t.active=1 AND t.fk_pays = c.rowid AND c.code='" . $thirdparty_seller->country_code . "'"; $sql .= " ORDER BY t.taux DESC, t.recuperableonly ASC"; $sql .= $db->plimit(1); $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); if ($obj) { $ret = $obj->vat_rate; } $db->free($sql); } else { dol_print_error($db); } } else { $ret = $conf->global->MAIN_VAT_DEFAULT_IF_AUTODETECT_FAILS; } } dol_syslog("get_product_vat_for_country: ret=" . $ret); return $ret; }
} } elseif ($action == 'addline') { $ret = $object->fetch($id); if ($ret < 0) { dol_print_error($db, $object->error); exit; } $ret = $object->fetch_thirdparty(); if (GETPOST('search_idprodfournprice') || GETPOST('idprodfournprice')) { $idprod = 0; $product = new Product($db); if (GETPOST('idprodfournprice') == '') { $idprod = -1; } if (GETPOST('idprodfournprice') > 0) { $idprod = $product->get_buyprice(GETPOST('idprodfournprice'), $_POST['qty']); // Just to see if a price exists for the quantity. Not used to found vat } if ($idprod > 0) { $result = $product->fetch($idprod); // cas special pour lequel on a les meme reference que le fournisseur // $label = '['.$product->ref.'] - '. $product->libelle; $label = $product->description; $label .= $product->description && $_POST['np_desc'] ? "\n" : ""; $label .= $_POST['np_desc']; $tvatx = get_default_tva($object->thirdparty, $mysoc, $product->id, $_POST['idprodfournprice']); $npr = get_default_npr($object->thirdparty, $mysoc, $product->id, $_POST['idprodfournprice']); $localtax1tx = get_localtax($tvatx, 1, $mysoc, $object->thirdparty); $localtax2tx = get_localtax($tvatx, 2, $mysoc, $object->thirdparty); $remise_percent = GETPOST('remise_percent'); $type = $product->type;
$localtax2tx = get_localtax($_POST['tauxtva'], 2, $object->thirdparty); $result = $object->updateline(GETPOST('lineid'), $label, $pu, GETPOST('tauxtva'), $localtax1tx, $localtax2tx, GETPOST('qty'), GETPOST('idprod'), $price_base_type, 0, $type); if ($result >= 0) { unset($_POST['label']); } } } elseif ($action == 'addline') { $ret = $object->fetch($id); if ($ret < 0) { dol_print_error($db, $object->error); exit; } $ret = $object->fetch_thirdparty(); if ($_POST['idprodfournprice']) { $product = new Product($db); $idprod = $product->get_buyprice($_POST['idprodfournprice'], $_POST['qty']); // Just to see if a price exists for the quantity. Not used to found vat if ($idprod > 0) { $result = $product->fetch($idprod); // cas special pour lequel on a les meme reference que le fournisseur // $label = '['.$product->ref.'] - '. $product->libelle; $label = $product->description; $tvatx = get_default_tva($object->thirdparty, $mysoc, $product->id, $_POST['idprodfournprice']); $localtax1tx = get_localtax($tvatx, 1, $object->thirdparty); $localtax2tx = get_localtax($tvatx, 2, $object->thirdparty); $type = $product->type; $result = $object->addline($label, $product->fourn_pu, $tvatx, $localtax1tx, $localtax2tx, $_POST['qty'], $idprod); } if ($idprod == -1) { // Quantity too low $langs->load("errors");
/** * Return vat rate of a product in a particular selling country or default country * vat if product is unknown * * @param int $idprod Id of product or 0 if not a predefined product * @param Societe $thirdparty_seller Thirdparty with a ->country_code defined (FR, US, IT, ...) * @param int $idprodfournprice Id product_fournisseur_price (for supplier order/invoice) * @return int <0 if KO, Vat rate if OK * TODO May be this should be better as a method of product class */ function get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournprice = 0) { global $db, $mysoc; $ret = 0; $found = 0; if ($idprod > 0) { // Load product $product = new Product($db); $result = $product->fetch($idprod); if ($mysoc->pays_code == $thirdparty_seller->country_code) { // If selling country is ours if ($idprodfournprice > 0) { // We want vat for product for a supplier order or invoice $product->get_buyprice($idprodfournprice, 0, 0, 0); $ret = $product->vatrate_supplier; } else { $ret = $product->tva_tx; // Default vat of product we defined } $found = 1; } else { // TODO Read default product vat according to countrycode and product } } if (!$found) { // If vat of product for the country not found or not defined, we return higher vat of country. $sql .= "SELECT taux as vat_rate"; $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_pays as p"; $sql .= " WHERE t.active=1 AND t.fk_pays = p.rowid AND p.code='" . $thirdparty_seller->country_code . "'"; $sql .= " ORDER BY t.taux DESC, t.recuperableonly ASC"; $sql .= $db->plimit(1); $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); if ($obj) { $ret = $obj->vat_rate; } } else { dol_print_error($db); } } dol_syslog("get_product_vat_for_country: ret=" . $ret); return $ret; }