diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index 10cf7b624fc..39f43a1a681 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -2505,12 +2505,12 @@ if (empty($reshook)) {
// Check price is not lower than minimum (check is done only for standard or replacement invoices)
if ($usermustrespectpricemin && ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT)) {
- if ($pu_ht && $price_min && ((price2num($pu_ht) * (1 - $remise_percent / 100)) < price2num($price_min))) {
+ if ($pu_ht && $price_min && (((float) price2num($pu_ht) * (1 - (float) $remise_percent / 100)) < (float) price2num($price_min))) {
$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
setEventMessages($mesg, null, 'errors');
$error++;
$action = 'editline';
- } elseif ($pu_ttc && $price_min_ttc && ((price2num($pu_ttc) * (1 - $remise_percent / 100)) < price2num($price_min_ttc))) {
+ } elseif ($pu_ttc && $price_min_ttc && ((price2num($pu_ttc) * (1 - (float) $remise_percent / 100)) < price2num($price_min_ttc))) {
$mesg = $langs->trans("CantBeLessThanMinPrice", price(price2num($price_min_ttc, 'MU'), 0, $langs, 0, 0, -1, $conf->currency));
setEventMessages($mesg, null, 'errors');
$error++;
diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php
index 9bd14d120fe..3f53c3c4e94 100644
--- a/htdocs/core/class/commoninvoice.class.php
+++ b/htdocs/core/class/commoninvoice.class.php
@@ -1761,6 +1761,7 @@ abstract class CommonInvoice extends CommonObject
}
// Header
+ $s = '';
$s .= "SPC\n";
$s .= "0200\n";
$s .= "1\n";
diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php
index 194dd7c7925..cc871de9709 100644
--- a/htdocs/core/lib/ajax.lib.php
+++ b/htdocs/core/lib/ajax.lib.php
@@ -165,7 +165,9 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
price_unit_ht_locale: item.price_unit_ht_locale,
description : item.description,
ref_customer: item.ref_customer,
- tva_tx: item.tva_tx }
+ tva_tx: item.tva_tx,
+ default_vat_code: item.default_vat_code
+ }
}));
} else {
console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array.");
@@ -178,7 +180,8 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
console.log("We will trigger change on input '.$htmlname.' because of the select definition of autocomplete code for input#search_'.$htmlname.'");
console.log("Selected id = "+ui.item.id+" - If this value is null, it means you select a record with key that is null so selection is not effective");
- console.log("Propagate before some properties retrieved by ajax into data-xxx properties");
+ console.log("Propagate before some properties retrieved by ajax into data-xxx properties of #'.$htmlnamejquery.' component");
+ //console.log(ui.item);
// For supplier price and customer when price by quantity is off
$("#'.$htmlnamejquery.'").attr("data-up", ui.item.price_ht);
@@ -189,6 +192,7 @@ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLen
$("#'.$htmlnamejquery.'").attr("data-description", ui.item.description);
$("#'.$htmlnamejquery.'").attr("data-ref-customer", ui.item.ref_customer);
$("#'.$htmlnamejquery.'").attr("data-tvatx", ui.item.tva_tx);
+ $("#'.$htmlnamejquery.'").attr("data-default-vat-code", ui.item.default_vat_code);
';
if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) {
$script .= '
diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
index 654f804b0d8..ee4cc9b5d0d 100644
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -752,10 +752,18 @@ class pdf_crabe extends ModelePDFFactures
// retrieve global local tax
if ($localtax1_type && $localtax1ligne != 0) {
- $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
+ if (empty($this->localtax1[$localtax1_type][$localtax1_rate])) {
+ $this->localtax1[$localtax1_type][$localtax1_rate] = $localtax1ligne;
+ } else {
+ $this->localtax1[$localtax1_type][$localtax1_rate] += $localtax1ligne;
+ }
}
if ($localtax2_type && $localtax2ligne != 0) {
- $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
+ if (empty($this->localtax2[$localtax2_type][$localtax2_rate])) {
+ $this->localtax2[$localtax2_type][$localtax2_rate] = $localtax2ligne;
+ } else {
+ $this->localtax2[$localtax2_type][$localtax2_rate] += $localtax2ligne;
+ }
}
if (($object->lines[$i]->info_bits & 0x01) == 0x01) {
diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php
index 05b98f2907b..c0979a2b480 100644
--- a/htdocs/core/tpl/objectline_create.tpl.php
+++ b/htdocs/core/tpl/objectline_create.tpl.php
@@ -971,7 +971,15 @@ if (!empty($usemargins) && $user->rights->margins->creer) {
var tva_tx = parseFloat($('option:selected', this).attr('data-tvatx')); // When select is done from HTML select
if (isNaN(tva_tx)) { tva_tx = parseFloat(jQuery('#idprodfournprice').attr('data-tvatx'));} // When select is done from HTML input with ajax autocomplete
- console.log("objectline_create.tpl We find supplier price : up = "+up+", up_locale = "+up_locale+", qty = "+qty+", tva_tx = "+tva_tx+", discount = "+discount+" for product "+jQuery('#idprodfournprice').val());
+ var default_vat_code = $('option:selected', this).attr('data-default-vat-code'); // When select is done from HTML select
+ if (typeof default_vat_code === 'undefined') { default_vat_code = jQuery('#idprodfournprice').attr('data-default-vat-code');} // When select is done from HTML input with ajax autocomplete
+
+ var stringforvatrateselection = tva_tx;
+ if (typeof default_vat_code != 'undefined') {
+ stringforvatrateselection = stringforvatrateselection+' ('+default_vat_code+')';
+ }
+
+ console.log("objectline_create.tpl We find supplier price : up = "+up+", up_locale = "+up_locale+", qty = "+qty+", tva_tx = "+tva_tx+", default_vat_code = "+default_vat_code+", stringforvatrateselection="+stringforvatrateselection+", discount = "+discount+" for product supplier ref id = "+jQuery('#idprodfournprice').val());
if (typeof up_locale === 'undefined') {
jQuery("#price_ht").val(up);
@@ -979,8 +987,13 @@ if (!empty($usemargins) && $user->rights->margins->creer) {
jQuery("#price_ht").val(up_locale);
}
- /* $('#tva_tx option').removeAttr('selected').filter('[value='+tva_tx+']').prop('selected', true); */
- $('#tva_tx option').val(tva_tx);
+ // Set vat rate if field is an input box
+ $('#tva_tx').val(tva_tx);
+ // Set vat rate by selecting the combo
+ //$('#tva_tx option').val(tva_tx); // This is bugged, it replaces the vat key of all options
+ $('#tva_tx option').removeAttr('selected');
+ console.log("stringforvatrateselection="+stringforvatrateselection+" -> value of option for this selection="+$('#tva_tx option[value="'+stringforvatrateselection+'"]').val());
+ $('#tva_tx option[value="'+stringforvatrateselection+'"]').prop('selected', true);
if (jQuery("#qty").val() < qty) {
jQuery("#qty").val(qty);
diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php
index c0a542479c6..98726638bec 100644
--- a/htdocs/core/tpl/objectline_view.tpl.php
+++ b/htdocs/core/tpl/objectline_view.tpl.php
@@ -353,19 +353,27 @@ if ($line->special_code == 3) { ?>
if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
$tooltiponprice = $langs->transcountry("TotalHT", $mysoc->country_code).'='.price($line->total_ht);
$tooltiponprice .= '
'.$langs->transcountry("TotalVAT", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.price($line->total_tva);
- if (!$senderissupplier && is_object($object->thirdparty)) {
+ if (is_object($object->thirdparty)) {
+ if ($senderissupplier) {
+ $seller = $object->thirdparty;
+ $buyer = $mysoc;
+ } else {
+ $seller = $mysoc;
+ $buyer = $object->thirdparty;
+ }
+
if ($mysoc->useLocalTax(1)) {
- if (($mysoc->country_code == $object->thirdparty->country_code) || $object->thirdparty->useLocalTax(1)) {
- $tooltiponprice .= '
'.$langs->transcountry("TotalLT1", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.price($line->total_localtax1);
+ if (($seller->country_code == $buyer->country_code) || $line->total_localtax1 || $seller->useLocalTax(1)) {
+ $tooltiponprice .= '
'.$langs->transcountry("TotalLT1", $seller->country_code).'='.price($line->total_localtax1);
} else {
- $tooltiponprice .= '
'.$langs->transcountry("TotalLT1", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.$langs->trans("NotUsedForThisCustomer").'';
+ $tooltiponprice .= '
'.$langs->transcountry("TotalLT1", $seller->country_code).'='.$langs->trans($senderissupplier ? "NotUsedForThisSupplier" : "NotUsedForThisCustomer").'';
}
}
if ($mysoc->useLocalTax(2)) {
- if (($mysoc->country_code == $object->thirdparty->country_code) || $object->thirdparty->useLocalTax(2)) {
- $tooltiponprice .= '
'.$langs->transcountry("TotalLT2", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.price($line->total_localtax2);
+ if (($seller->country_code == $buyer->thirdparty->country_code) || $line->total_localtax2 || $seller->useLocalTax(2)) {
+ $tooltiponprice .= '
'.$langs->transcountry("TotalLT2", $seller->country_code).'='.price($line->total_localtax2);
} else {
- $tooltiponprice .= '
'.$langs->transcountry("TotalLT2", ($senderissupplier ? $object->thirdparty->country_code : $mysoc->country_code)).'='.$langs->trans("NotUsedForThisCustomer").'';
+ $tooltiponprice .= '
'.$langs->transcountry("TotalLT2", $seller->country_code).'='.$langs->trans($senderissupplier ? "NotUsedForThisSupplier" : "NotUsedForThisCustomer").'';
}
}
}
diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php
index 240ac03f82f..b846e3da9b1 100644
--- a/htdocs/fourn/facture/card.php
+++ b/htdocs/fourn/facture/card.php
@@ -1299,10 +1299,13 @@ if (empty($reshook)) {
// Edit line
$db->begin();
- if (! $object->fetch($id) > 0) dol_print_error($db);
+ if (! $object->fetch($id) > 0) {
+ dol_print_error($db);
+ }
$object->fetch_thirdparty();
$tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0);
+ $tva_tx = str_replace('*', '', $tva_tx);
if (GETPOST('price_ht') != '' || GETPOST('multicurrency_subprice') != '') {
$up = price2num(GETPOST('price_ht'), '', 2);
@@ -1360,7 +1363,27 @@ if (empty($reshook)) {
}
}
- $result = $object->updateline(GETPOST('lineid', 'int'), $label, $up, $tva_tx, $localtax1_tx, $localtax2_tx, price2num(GETPOST('qty'), 'MS'), GETPOST('productid', 'int'), $price_base_type, $info_bits, $type, $remise_percent, 0, $date_start, $date_end, $array_options, GETPOST('units'), $pu_devise, GETPOST('fourn_ref', 'alpha'));
+ $result = $object->updateline(
+ GETPOST('lineid', 'int'),
+ $label,
+ $up,
+ $tva_tx,
+ $localtax1_tx,
+ $localtax2_tx,
+ price2num(GETPOST('qty'), 'MS'),
+ GETPOST('productid', 'int'),
+ $price_base_type,
+ $info_bits,
+ $type,
+ $remise_percent,
+ 0,
+ $date_start,
+ $date_end,
+ $array_options,
+ GETPOST('units', 'alpha'),
+ $pu_devise,
+ GETPOST('fourn_ref', 'alpha')
+ );
if ($result >= 0) {
unset($_POST['label']);
unset($_POST['fourn_ref']);
@@ -2588,7 +2611,6 @@ if ($action == 'create') {
//
// View or edit mode
//
-
$now = dol_now();
$productstatic = new Product($db);
@@ -2918,15 +2940,15 @@ if ($action == 'create') {
if ($object->type == FactureFournisseur::TYPE_REPLACEMENT) {
$facreplaced = new FactureFournisseur($db);
$facreplaced->fetch($object->fk_facture_source);
- print ' '.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1));
+ print ' '.$langs->transnoentities("ReplaceInvoice", $facreplaced->getNomUrl(1)).'';
}
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
$facusing = new FactureFournisseur($db);
if ($object->fk_facture_source > 0) {
$facusing->fetch($object->fk_facture_source);
- print ' '.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1));
+ print ' '.$langs->transnoentities("CorrectInvoice", $facusing->getNomUrl(1)).'';
} else {
- print ' '.$langs->transnoentities("CorrectedInvoiceNotFound");
+ print ' '.$langs->transnoentities("CorrectedInvoiceNotFound").'';
}
}
@@ -2938,12 +2960,13 @@ if ($action == 'create') {
$facavoir->fetch($id);
$invoicecredits[] = $facavoir->getNomUrl(1);
}
- print ' ('.$langs->transnoentities("InvoiceHasAvoir") . (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits) . ')';
+ print ' '.$langs->transnoentities("InvoiceHasAvoir") . (count($invoicecredits) ? ' ' : '') . implode(',', $invoicecredits);
+ print '';
}
if (isset($objectidnext) && $objectidnext > 0) {
$facthatreplace = new FactureFournisseur($db);
$facthatreplace->fetch($facidnext);
- print ' ('.$langs->transnoentities("ReplacedByInvoice", $facthatreplace->getNomUrl(1)).')';
+ print ' '.str_replace('{s1}', $facthatreplace->getNomUrl(1), $langs->transnoentities("ReplacedByInvoice", '{s1}')).'';
}
if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT) {
$discount = new DiscountAbsolute($db);
diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php
index ffb72bfca78..bebe5d5a98d 100644
--- a/htdocs/product/class/product.class.php
+++ b/htdocs/product/class/product.class.php
@@ -2159,7 +2159,7 @@ class Product extends CommonObject
}
} else {
$price = price2num($newprice, 'MU');
- $price_ttc = ($newnpr != 1) ? price2num($newprice) * (1 + ($newvat / 100)) : $price;
+ $price_ttc = ($newnpr != 1) ? (float) price2num($newprice) * (1 + ($newvat / 100)) : $price;
$price_ttc = price2num($price_ttc, 'MU');
if ($newminprice !== '' || $newminprice === 0) {
@@ -2179,12 +2179,34 @@ class Product extends CommonObject
$localtax1 = $localtaxes_array['1'];
$localtaxtype2 = $localtaxes_array['2'];
$localtax2 = $localtaxes_array['3'];
- } else // old method. deprecated because ot can't retrieve type
- {
- $localtaxtype1 = '0';
- $localtax1 = get_localtax($newvat, 1);
- $localtaxtype2 = '0';
- $localtax2 = get_localtax($newvat, 2);
+ } else {
+ // if array empty, we try to use the vat code
+ if (!empty($newdefaultvatcode)) {
+ global $mysoc;
+ // Get record from code
+ $sql = "SELECT t.rowid, t.code, t.recuperableonly, t.localtax1, t.localtax2, t.localtax1_type, t.localtax2_type";
+ $sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
+ $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$this->db->escape($mysoc->country_code)."'";
+ $sql .= " AND t.taux = ".((float) $newdefaultvatcode)." AND t.active = 1";
+ $sql .= " AND t.code = '".$this->db->escape($newdefaultvatcode)."'";
+ $resql = $this->db->query($sql);
+ if ($resql) {
+ $obj = $this->db->fetch_object($resql);
+ if ($obj) {
+ $npr = $obj->recuperableonly;
+ $localtax1 = $obj->localtax1;
+ $localtax2 = $obj->localtax2;
+ $localtaxtype1 = $obj->localtax1_type;
+ $localtaxtype2 = $obj->localtax2_type;
+ }
+ }
+ } else {
+ // old method. deprecated because we can't retrieve type
+ $localtaxtype1 = '0';
+ $localtax1 = get_localtax($newvat, 1);
+ $localtaxtype2 = '0';
+ $localtax2 = get_localtax($newvat, 2);
+ }
}
if (empty($localtax1)) {
$localtax1 = 0; // If = '' then = 0
diff --git a/htdocs/product/price.php b/htdocs/product/price.php
index ca69f12170d..cde676c9732 100644
--- a/htdocs/product/price.php
+++ b/htdocs/product/price.php
@@ -136,6 +136,7 @@ if (empty($reshook)) {
$npr = preg_match('/\*/', $tva_tx_txt) ? 1 : 0;
$localtax1 = 0; $localtax2 = 0; $localtax1_type = '0'; $localtax2_type = '0';
// If value contains the unique code of vat line (new recommanded method), we use it to find npr and local taxes
+
if (preg_match('/\((.*)\)/', $tva_tx_txt, $reg)) {
// We look into database using code (we can't use get_localtax() because it depends on buyer that is not known). Same in create product.
$vatratecode = $reg[1];
@@ -229,7 +230,7 @@ if (empty($reshook)) {
$oldnpr = $object->tva_npr;
//$localtaxarray=array('0'=>$localtax1_type,'1'=>$localtax1,'2'=>$localtax2_type,'3'=>$localtax2);
- $localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them.
+ $localtaxarray = array(); // We do not store localtaxes into product, we will use instead the "vat code" to retrieve them when required.
$level = 0;
$ret = $object->updatePrice($oldprice, $oldpricebasetype, $user, $tva_tx, $oldminprice, $level, $oldnpr, 0, 0, $localtaxarray, $vatratecode);
@@ -877,7 +878,7 @@ dol_banner_tab($object, 'ref', $linkback, $shownav, 'ref');
print '
| '.$langs->trans("DefaultTaxRate").' | ';
+ // TODO We show localtax from $object, but this properties may not be correct. Only value $object->default_vat_code is guaranted.
$positiverates = '';
if (price2num($object->tva_tx)) {
$positiverates .= ($positiverates ? '/' : '').price2num($object->tva_tx);
@@ -1013,6 +1015,7 @@ if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_
if (empty($positiverates)) {
$positiverates = '0';
}
+
print vatrate($positiverates.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), true, $object->tva_npr, 1);
/*
if ($object->default_vat_code)
@@ -1026,7 +1029,7 @@ if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_
print ' '; - print '
|