mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-25 16:04:46 +00:00
refactor: depracate old method and handle inclusive tax
This commit is contained in:
@@ -8,6 +8,7 @@ import frappe
|
|||||||
from frappe import _, scrub
|
from frappe import _, scrub
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction
|
from frappe.utils import cint, flt, round_based_on_smallest_currency_fraction
|
||||||
|
from frappe.utils.deprecations import deprecated
|
||||||
|
|
||||||
import erpnext
|
import erpnext
|
||||||
from erpnext.accounts.doctype.journal_entry.journal_entry import get_exchange_rate
|
from erpnext.accounts.doctype.journal_entry.journal_entry import get_exchange_rate
|
||||||
@@ -74,7 +75,7 @@ class calculate_taxes_and_totals:
|
|||||||
self.calculate_net_total()
|
self.calculate_net_total()
|
||||||
self.calculate_tax_withholding_net_total()
|
self.calculate_tax_withholding_net_total()
|
||||||
self.calculate_taxes()
|
self.calculate_taxes()
|
||||||
self.manipulate_grand_total_for_inclusive_tax()
|
self.adjust_grand_total_for_inclusive_tax()
|
||||||
self.calculate_totals()
|
self.calculate_totals()
|
||||||
self._cleanup()
|
self._cleanup()
|
||||||
self.calculate_total_net_weight()
|
self.calculate_total_net_weight()
|
||||||
@@ -286,7 +287,7 @@ class calculate_taxes_and_totals:
|
|||||||
):
|
):
|
||||||
amount = flt(item.amount) - total_inclusive_tax_amount_per_qty
|
amount = flt(item.amount) - total_inclusive_tax_amount_per_qty
|
||||||
|
|
||||||
item.net_amount = flt(amount / (1 + cumulated_tax_fraction))
|
item.net_amount = flt(amount / (1 + cumulated_tax_fraction), item.precision("net_amount"))
|
||||||
item.net_rate = flt(item.net_amount / item.qty, item.precision("net_rate"))
|
item.net_rate = flt(item.net_amount / item.qty, item.precision("net_rate"))
|
||||||
item.discount_percentage = flt(
|
item.discount_percentage = flt(
|
||||||
item.discount_percentage, item.precision("discount_percentage")
|
item.discount_percentage, item.precision("discount_percentage")
|
||||||
@@ -531,7 +532,12 @@ class calculate_taxes_and_totals:
|
|||||||
tax.base_tax_amount = round(tax.base_tax_amount, 0)
|
tax.base_tax_amount = round(tax.base_tax_amount, 0)
|
||||||
tax.base_tax_amount_after_discount_amount = round(tax.base_tax_amount_after_discount_amount, 0)
|
tax.base_tax_amount_after_discount_amount = round(tax.base_tax_amount_after_discount_amount, 0)
|
||||||
|
|
||||||
|
@deprecated
|
||||||
def manipulate_grand_total_for_inclusive_tax(self):
|
def manipulate_grand_total_for_inclusive_tax(self):
|
||||||
|
# for backward compatablility - if in case used by an external application
|
||||||
|
return self.adjust_grand_total_for_inclusive_tax()
|
||||||
|
|
||||||
|
def adjust_grand_total_for_inclusive_tax(self):
|
||||||
# if fully inclusive taxes and diff
|
# if fully inclusive taxes and diff
|
||||||
if self.doc.get("taxes") and any(cint(t.included_in_print_rate) for t in self.doc.get("taxes")):
|
if self.doc.get("taxes") and any(cint(t.included_in_print_rate) for t in self.doc.get("taxes")):
|
||||||
last_tax = self.doc.get("taxes")[-1]
|
last_tax = self.doc.get("taxes")[-1]
|
||||||
@@ -553,17 +559,21 @@ class calculate_taxes_and_totals:
|
|||||||
diff = flt(diff, self.doc.precision("rounding_adjustment"))
|
diff = flt(diff, self.doc.precision("rounding_adjustment"))
|
||||||
|
|
||||||
if diff and abs(diff) <= (5.0 / 10 ** last_tax.precision("tax_amount")):
|
if diff and abs(diff) <= (5.0 / 10 ** last_tax.precision("tax_amount")):
|
||||||
self.doc.rounding_adjustment = diff
|
self.doc.grand_total_diff = diff
|
||||||
|
else:
|
||||||
|
self.doc.grand_total_diff = 0
|
||||||
|
|
||||||
def calculate_totals(self):
|
def calculate_totals(self):
|
||||||
if self.doc.get("taxes"):
|
if self.doc.get("taxes"):
|
||||||
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(self.doc.rounding_adjustment)
|
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(
|
||||||
|
self.doc.get("grand_total_diff")
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.doc.grand_total = flt(self.doc.net_total)
|
self.doc.grand_total = flt(self.doc.net_total)
|
||||||
|
|
||||||
if self.doc.get("taxes"):
|
if self.doc.get("taxes"):
|
||||||
self.doc.total_taxes_and_charges = flt(
|
self.doc.total_taxes_and_charges = flt(
|
||||||
self.doc.grand_total - self.doc.net_total - flt(self.doc.rounding_adjustment),
|
self.doc.grand_total - self.doc.net_total - flt(self.doc.get("grand_total_diff")),
|
||||||
self.doc.precision("total_taxes_and_charges"),
|
self.doc.precision("total_taxes_and_charges"),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@@ -626,8 +636,8 @@ class calculate_taxes_and_totals:
|
|||||||
self.doc.grand_total, self.doc.currency, self.doc.precision("rounded_total")
|
self.doc.grand_total, self.doc.currency, self.doc.precision("rounded_total")
|
||||||
)
|
)
|
||||||
|
|
||||||
# if print_in_rate is set, we would have already calculated rounding adjustment
|
# rounding adjustment should always be the difference vetween grand and rounded total
|
||||||
self.doc.rounding_adjustment += flt(
|
self.doc.rounding_adjustment = flt(
|
||||||
self.doc.rounded_total - self.doc.grand_total, self.doc.precision("rounding_adjustment")
|
self.doc.rounded_total - self.doc.grand_total, self.doc.precision("rounding_adjustment")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ erpnext.accounts.taxes = {
|
|||||||
let tax = frappe.get_doc(cdt, cdn);
|
let tax = frappe.get_doc(cdt, cdn);
|
||||||
try {
|
try {
|
||||||
me.validate_taxes_and_charges(cdt, cdn);
|
me.validate_taxes_and_charges(cdt, cdn);
|
||||||
me.validate_inclusive_tax(tax);
|
me.validate_inclusive_tax(tax, frm);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
tax.included_in_print_rate = 0;
|
tax.included_in_print_rate = 0;
|
||||||
refresh_field("included_in_print_rate", tax.name, tax.parentfield);
|
refresh_field("included_in_print_rate", tax.name, tax.parentfield);
|
||||||
@@ -170,7 +170,8 @@ erpnext.accounts.taxes = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
validate_inclusive_tax: function(tax) {
|
validate_inclusive_tax: function(tax, frm) {
|
||||||
|
this.frm = this.frm || frm;
|
||||||
let actual_type_error = function() {
|
let actual_type_error = function() {
|
||||||
var msg = __("Actual type tax cannot be included in Item rate in row {0}", [tax.idx])
|
var msg = __("Actual type tax cannot be included in Item rate in row {0}", [tax.idx])
|
||||||
frappe.throw(msg);
|
frappe.throw(msg);
|
||||||
@@ -186,12 +187,12 @@ erpnext.accounts.taxes = {
|
|||||||
if(tax.charge_type == "Actual") {
|
if(tax.charge_type == "Actual") {
|
||||||
// inclusive tax cannot be of type Actual
|
// inclusive tax cannot be of type Actual
|
||||||
actual_type_error();
|
actual_type_error();
|
||||||
} else if(tax.charge_type == "On Previous Row Amount" &&
|
} else if(tax.charge_type == "On Previous Row Amount" && this.frm &&
|
||||||
!cint(this.frm.doc["taxes"][tax.row_id - 1].included_in_print_rate)
|
!cint(this.frm.doc["taxes"][tax.row_id - 1].included_in_print_rate)
|
||||||
) {
|
) {
|
||||||
// referred row should also be an inclusive tax
|
// referred row should also be an inclusive tax
|
||||||
on_previous_row_error(tax.row_id);
|
on_previous_row_error(tax.row_id);
|
||||||
} else if(tax.charge_type == "On Previous Row Total") {
|
} else if(tax.charge_type == "On Previous Row Total" && this.frm) {
|
||||||
var taxes_not_included = $.map(this.frm.doc["taxes"].slice(0, tax.row_id),
|
var taxes_not_included = $.map(this.frm.doc["taxes"].slice(0, tax.row_id),
|
||||||
function(t) { return cint(t.included_in_print_rate) ? null : t; });
|
function(t) { return cint(t.included_in_print_rate) ? null : t; });
|
||||||
if(taxes_not_included.length > 0) {
|
if(taxes_not_included.length > 0) {
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
this.determine_exclusive_rate();
|
this.determine_exclusive_rate();
|
||||||
this.calculate_net_total();
|
this.calculate_net_total();
|
||||||
this.calculate_taxes();
|
this.calculate_taxes();
|
||||||
this.manipulate_grand_total_for_inclusive_tax();
|
this.adjust_grand_total_for_inclusive_tax();
|
||||||
this.calculate_totals();
|
this.calculate_totals();
|
||||||
this._cleanup();
|
this._cleanup();
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
|
|
||||||
if (!this.discount_amount_applied) {
|
if (!this.discount_amount_applied) {
|
||||||
erpnext.accounts.taxes.validate_taxes_and_charges(tax.doctype, tax.name);
|
erpnext.accounts.taxes.validate_taxes_and_charges(tax.doctype, tax.name);
|
||||||
erpnext.accounts.taxes.validate_inclusive_tax(tax);
|
erpnext.accounts.taxes.validate_inclusive_tax(tax, this.frm);
|
||||||
}
|
}
|
||||||
frappe.model.round_floats_in(tax);
|
frappe.model.round_floats_in(tax);
|
||||||
});
|
});
|
||||||
@@ -250,7 +250,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
|
|
||||||
if(!me.discount_amount_applied && item.qty && (total_inclusive_tax_amount_per_qty || cumulated_tax_fraction)) {
|
if(!me.discount_amount_applied && item.qty && (total_inclusive_tax_amount_per_qty || cumulated_tax_fraction)) {
|
||||||
var amount = flt(item.amount) - total_inclusive_tax_amount_per_qty;
|
var amount = flt(item.amount) - total_inclusive_tax_amount_per_qty;
|
||||||
item.net_amount = flt(amount / (1 + cumulated_tax_fraction));
|
item.net_amount = flt(amount / (1 + cumulated_tax_fraction), precision("net_amount", item));
|
||||||
item.net_rate = item.qty ? flt(item.net_amount / item.qty, precision("net_rate", item)) : 0;
|
item.net_rate = item.qty ? flt(item.net_amount / item.qty, precision("net_rate", item)) : 0;
|
||||||
|
|
||||||
me.set_in_company_currency(item, ["net_rate", "net_amount"]);
|
me.set_in_company_currency(item, ["net_rate", "net_amount"]);
|
||||||
@@ -305,6 +305,8 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
me.frm.doc.net_total += item.net_amount;
|
me.frm.doc.net_total += item.net_amount;
|
||||||
me.frm.doc.base_net_total += item.base_net_amount;
|
me.frm.doc.base_net_total += item.base_net_amount;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
frappe.model.round_floats_in(this.frm.doc, ["total", "base_total", "net_total", "base_net_total"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
calculate_shipping_charges() {
|
calculate_shipping_charges() {
|
||||||
@@ -523,7 +525,15 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use adjust_grand_total_for_inclusive_tax instead.
|
||||||
|
*/
|
||||||
manipulate_grand_total_for_inclusive_tax() {
|
manipulate_grand_total_for_inclusive_tax() {
|
||||||
|
// for backward compatablility - if in case used by an external application
|
||||||
|
this.adjust_grand_total_for_inclusive_tax()
|
||||||
|
}
|
||||||
|
|
||||||
|
adjust_grand_total_for_inclusive_tax() {
|
||||||
var me = this;
|
var me = this;
|
||||||
// if fully inclusive taxes and diff
|
// if fully inclusive taxes and diff
|
||||||
if (this.frm.doc["taxes"] && this.frm.doc["taxes"].length) {
|
if (this.frm.doc["taxes"] && this.frm.doc["taxes"].length) {
|
||||||
@@ -550,7 +560,9 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
diff = flt(diff, precision("rounding_adjustment"));
|
diff = flt(diff, precision("rounding_adjustment"));
|
||||||
|
|
||||||
if ( diff && Math.abs(diff) <= (5.0 / Math.pow(10, precision("tax_amount", last_tax))) ) {
|
if ( diff && Math.abs(diff) <= (5.0 / Math.pow(10, precision("tax_amount", last_tax))) ) {
|
||||||
me.frm.doc.rounding_adjustment = diff;
|
me.frm.doc.grand_total_diff = diff;
|
||||||
|
} else {
|
||||||
|
me.frm.doc.grand_total_diff = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -561,7 +573,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
var me = this;
|
var me = this;
|
||||||
var tax_count = this.frm.doc["taxes"] ? this.frm.doc["taxes"].length : 0;
|
var tax_count = this.frm.doc["taxes"] ? this.frm.doc["taxes"].length : 0;
|
||||||
this.frm.doc.grand_total = flt(tax_count
|
this.frm.doc.grand_total = flt(tax_count
|
||||||
? this.frm.doc["taxes"][tax_count - 1].total + flt(this.frm.doc.rounding_adjustment)
|
? this.frm.doc["taxes"][tax_count - 1].total + flt(this.frm.doc.grand_total_diff)
|
||||||
: this.frm.doc.net_total);
|
: this.frm.doc.net_total);
|
||||||
|
|
||||||
if(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "POS Invoice"].includes(this.frm.doc.doctype)) {
|
if(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "POS Invoice"].includes(this.frm.doc.doctype)) {
|
||||||
@@ -621,7 +633,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
if(frappe.meta.get_docfield(this.frm.doc.doctype, "rounded_total", this.frm.doc.name)) {
|
if(frappe.meta.get_docfield(this.frm.doc.doctype, "rounded_total", this.frm.doc.name)) {
|
||||||
this.frm.doc.rounded_total = round_based_on_smallest_currency_fraction(this.frm.doc.grand_total,
|
this.frm.doc.rounded_total = round_based_on_smallest_currency_fraction(this.frm.doc.grand_total,
|
||||||
this.frm.doc.currency, precision("rounded_total"));
|
this.frm.doc.currency, precision("rounded_total"));
|
||||||
this.frm.doc.rounding_adjustment += flt(this.frm.doc.rounded_total - this.frm.doc.grand_total,
|
this.frm.doc.rounding_adjustment = flt(this.frm.doc.rounded_total - this.frm.doc.grand_total,
|
||||||
precision("rounding_adjustment"));
|
precision("rounding_adjustment"));
|
||||||
|
|
||||||
this.set_in_company_currency(this.frm.doc, ["rounding_adjustment", "rounded_total"]);
|
this.set_in_company_currency(this.frm.doc, ["rounding_adjustment", "rounded_total"]);
|
||||||
@@ -689,8 +701,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
|
|||||||
if (total_for_discount_amount) {
|
if (total_for_discount_amount) {
|
||||||
$.each(this.frm._items || [], function(i, item) {
|
$.each(this.frm._items || [], function(i, item) {
|
||||||
distributed_amount = flt(me.frm.doc.discount_amount) * item.net_amount / total_for_discount_amount;
|
distributed_amount = flt(me.frm.doc.discount_amount) * item.net_amount / total_for_discount_amount;
|
||||||
item.net_amount = flt(item.net_amount - distributed_amount,
|
item.net_amount = flt(item.net_amount - distributed_amount, precision("net_amount", item));
|
||||||
precision("base_amount", item));
|
|
||||||
net_total += item.net_amount;
|
net_total += item.net_amount;
|
||||||
|
|
||||||
// discount amount rounding loss adjustment if no taxes
|
// discount amount rounding loss adjustment if no taxes
|
||||||
|
|||||||
Reference in New Issue
Block a user