Taxes and totals calculation in party currency
This commit is contained in:
parent
81d96fdb60
commit
e7679703cf
@ -81,6 +81,15 @@
|
|||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Amount",
|
"label": "Amount",
|
||||||
|
"options": "currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "base_tax_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Amount (Company Currency)",
|
||||||
"oldfieldname": "tax_amount",
|
"oldfieldname": "tax_amount",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
@ -92,6 +101,15 @@
|
|||||||
"fieldname": "total",
|
"fieldname": "total",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"label": "Total",
|
"label": "Total",
|
||||||
|
"options": "currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "base_total",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Total (Company Currency)",
|
||||||
"oldfieldname": "total",
|
"oldfieldname": "total",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
@ -112,11 +130,20 @@
|
|||||||
"width": "150px"
|
"width": "150px"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"depends_on": "eval:parent.discount_amount",
|
|
||||||
"fieldname": "tax_amount_after_discount_amount",
|
"fieldname": "tax_amount_after_discount_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"hidden": 0,
|
|
||||||
"label": "Tax Amount After Discount Amount",
|
"label": "Tax Amount After Discount Amount",
|
||||||
|
"options": "currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:parent.discount_amount",
|
||||||
|
"fieldname": "base_tax_amount_after_discount_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Tax Amount After Discount Amount (Company Currency)",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
@ -147,7 +174,7 @@
|
|||||||
"hide_heading": 1,
|
"hide_heading": 1,
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2015-02-19 01:07:02.165094",
|
"modified": "2015-02-19 17:00:07.949352",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Accounts",
|
"module": "Accounts",
|
||||||
"name": "Sales Taxes and Charges",
|
"name": "Sales Taxes and Charges",
|
||||||
|
@ -165,10 +165,10 @@ cur_frm.cscript.tax_amount = function(doc, cdt, cdn) {
|
|||||||
msgprint(__("Please select Charge Type first"));
|
msgprint(__("Please select Charge Type first"));
|
||||||
d.tax_amount = '';
|
d.tax_amount = '';
|
||||||
}
|
}
|
||||||
else if(d.charge_type && d.tax_amount) {
|
// else if(d.charge_type && d.tax_amount) {
|
||||||
msgprint(__("Cannot directly set amount. For 'Actual' charge type, use the rate field"));
|
// msgprint(__("Cannot directly set amount. For 'Actual' charge type, use the rate field"));
|
||||||
d.tax_amount = '';
|
// d.tax_amount = '';
|
||||||
}
|
// }
|
||||||
validated = false;
|
validated = false;
|
||||||
refresh_field('tax_amount', d.name, 'taxes');
|
refresh_field('tax_amount', d.name, 'taxes');
|
||||||
};
|
};
|
||||||
|
@ -414,7 +414,8 @@
|
|||||||
"label": "Total Taxes and Charges",
|
"label": "Total Taxes and Charges",
|
||||||
"options": "currency",
|
"options": "currency",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"precision": ""
|
"precision": "",
|
||||||
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "grand_total",
|
"fieldname": "grand_total",
|
||||||
@ -673,7 +674,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"read_only_onload": 1,
|
"read_only_onload": 1,
|
||||||
"search_fields": "status, transaction_date, supplier,base_grand_total",
|
"search_fields": "status, transaction_date, supplier,grand_total",
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "supplier_name"
|
"title_field": "supplier_name"
|
||||||
|
@ -11,7 +11,6 @@ from erpnext.controllers.accounts_controller import validate_conversion_rate
|
|||||||
class calculate_taxes_and_totals(object):
|
class calculate_taxes_and_totals(object):
|
||||||
def __init__(self, doc):
|
def __init__(self, doc):
|
||||||
self.doc = doc
|
self.doc = doc
|
||||||
|
|
||||||
self.calculate()
|
self.calculate()
|
||||||
|
|
||||||
def calculate(self):
|
def calculate(self):
|
||||||
@ -25,6 +24,15 @@ class calculate_taxes_and_totals(object):
|
|||||||
self.calculate_total_advance()
|
self.calculate_total_advance()
|
||||||
|
|
||||||
def _calculate(self):
|
def _calculate(self):
|
||||||
|
self.calculate_item_values()
|
||||||
|
self.initialize_taxes()
|
||||||
|
self.determine_exclusive_rate()
|
||||||
|
self.calculate_net_total()
|
||||||
|
self.calculate_taxes()
|
||||||
|
self.calculate_totals()
|
||||||
|
self._cleanup()
|
||||||
|
|
||||||
|
def validate_conversion_rate(self):
|
||||||
# validate conversion rate
|
# validate conversion rate
|
||||||
company_currency = get_company_currency(self.doc.company)
|
company_currency = get_company_currency(self.doc.company)
|
||||||
if not self.doc.currency or self.doc.currency == company_currency:
|
if not self.doc.currency or self.doc.currency == company_currency:
|
||||||
@ -36,17 +44,6 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
self.doc.conversion_rate = flt(self.doc.conversion_rate)
|
self.doc.conversion_rate = flt(self.doc.conversion_rate)
|
||||||
|
|
||||||
self.calculate_item_values()
|
|
||||||
self.initialize_taxes()
|
|
||||||
|
|
||||||
if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
|
|
||||||
self.determine_exclusive_rate()
|
|
||||||
|
|
||||||
self.calculate_net_total()
|
|
||||||
self.calculate_taxes()
|
|
||||||
self.calculate_totals()
|
|
||||||
self._cleanup()
|
|
||||||
|
|
||||||
def calculate_item_values(self):
|
def calculate_item_values(self):
|
||||||
if not self.discount_amount_applied:
|
if not self.discount_amount_applied:
|
||||||
for item in self.doc.get("items"):
|
for item in self.doc.get("items"):
|
||||||
@ -55,21 +52,22 @@ class calculate_taxes_and_totals(object):
|
|||||||
if item.discount_percentage == 100:
|
if item.discount_percentage == 100:
|
||||||
item.rate = 0.0
|
item.rate = 0.0
|
||||||
elif not item.rate:
|
elif not item.rate:
|
||||||
item.rate = flt(item.price_list_rate * (1.0 - (item.discount_percentage / 100.0)),
|
item.rate = flt(item.price_list_rate *
|
||||||
self.doc.precision("rate", item))
|
(1.0 - (item.discount_percentage / 100.0)), item.precision("rate"))
|
||||||
|
|
||||||
item.amount = flt(item.rate * item.qty, self.doc.precision("amount", item))
|
item.net_rate = item.rate
|
||||||
item.item_tax_amount = 0.0;
|
item.amount = flt(item.rate * item.qty, item.precision("amount"))
|
||||||
|
item.net_amount = item.amount
|
||||||
|
|
||||||
self._set_in_company_currency(item, "price_list_rate", "base_price_list_rate")
|
self._set_in_company_currency(item, ["price_list_rate", "rate", "net_rate", "amount", "net_amount"])
|
||||||
self._set_in_company_currency(item, "rate", "base_rate")
|
|
||||||
self._set_in_company_currency(item, "amount", "base_amount")
|
|
||||||
|
|
||||||
def _set_in_company_currency(self, item, print_field, base_field):
|
item.item_tax_amount = 0.0
|
||||||
|
|
||||||
|
def _set_in_company_currency(self, doc, fields):
|
||||||
"""set values in base currency"""
|
"""set values in base currency"""
|
||||||
value_in_company_currency = flt(self.doc.conversion_rate *
|
for f in fields:
|
||||||
flt(item.get(print_field), self.doc.precision(print_field, item)), self.doc.precision(base_field, item))
|
val = flt(flt(doc.get(f), doc.precision(f)) * self.doc.conversion_rate, doc.precision("base_" + f))
|
||||||
item.set(base_field, value_in_company_currency)
|
doc.set("base_" + f, val)
|
||||||
|
|
||||||
def initialize_taxes(self):
|
def initialize_taxes(self):
|
||||||
for tax in self.doc.get("taxes"):
|
for tax in self.doc.get("taxes"):
|
||||||
@ -116,8 +114,8 @@ class calculate_taxes_and_totals(object):
|
|||||||
_on_previous_row_error("1 - %d" % (tax.row_id,))
|
_on_previous_row_error("1 - %d" % (tax.row_id,))
|
||||||
|
|
||||||
def determine_exclusive_rate(self):
|
def determine_exclusive_rate(self):
|
||||||
if not any((cint(tax.included_in_print_rate) for tax in self.doc.get("taxes"))):
|
if not any((cint(tax.included_in_print_rate) for tax in self.doc.get("taxes"))) or \
|
||||||
# no inclusive tax
|
self.doc.doctype not in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
|
||||||
return
|
return
|
||||||
|
|
||||||
for item in self.doc.get("items"):
|
for item in self.doc.get("items"):
|
||||||
@ -136,18 +134,24 @@ class calculate_taxes_and_totals(object):
|
|||||||
cumulated_tax_fraction += tax.tax_fraction_for_current_item
|
cumulated_tax_fraction += tax.tax_fraction_for_current_item
|
||||||
|
|
||||||
if cumulated_tax_fraction and not self.discount_amount_applied and item.qty:
|
if cumulated_tax_fraction and not self.discount_amount_applied and item.qty:
|
||||||
item.base_amount = flt((item.amount * self.doc.conversion_rate) /
|
item.net_amount = flt(item.amount / (1 + cumulated_tax_fraction), item.precision("net_amount"))
|
||||||
(1 + cumulated_tax_fraction), self.doc.precision("base_amount", item))
|
item.net_rate = flt(item.net_amount / item.qty, item.precision("net_rate"))
|
||||||
|
item.discount_percentage = flt(item.discount_percentage, item.precision("discount_percentage"))
|
||||||
|
|
||||||
item.base_rate = flt(item.base_amount / item.qty, self.doc.precision("base_rate", item))
|
|
||||||
item.discount_percentage = flt(item.discount_percentage, self.doc.precision("discount_percentage", item))
|
|
||||||
|
|
||||||
if item.discount_percentage == 100:
|
self._set_in_company_currency(item, ["net_rate", "net_amount"])
|
||||||
item.base_price_list_rate = item.base_rate
|
|
||||||
item.base_rate = 0.0
|
# below part need to be fixed???
|
||||||
else:
|
|
||||||
item.base_price_list_rate = flt(item.base_rate / (1 - (item.discount_percentage / 100.0)),
|
# if item.discount_percentage == 100:
|
||||||
self.doc.precision("base_price_list_rate", item))
|
# item.price_list_rate = item.net_rate
|
||||||
|
# item.base_price_list_rate = flt(item.price_list_rate*self.doc.conversion_rate,
|
||||||
|
# self.doc.precision("base_price_list_rate", item))
|
||||||
|
# item.rate = item.base_rate = item.net_rate = item.base_net_rate = 0.0
|
||||||
|
# else:
|
||||||
|
# item.base_price_list_rate = flt(item.net_rate / (1 - (item.discount_percentage / 100.0)),
|
||||||
|
# self.doc.precision("price_list_rate", item))
|
||||||
|
|
||||||
|
|
||||||
def _load_item_tax_rate(self, item_tax_rate):
|
def _load_item_tax_rate(self, item_tax_rate):
|
||||||
return json.loads(item_tax_rate) if item_tax_rate else {}
|
return json.loads(item_tax_rate) if item_tax_rate else {}
|
||||||
@ -182,17 +186,19 @@ class calculate_taxes_and_totals(object):
|
|||||||
return tax.rate
|
return tax.rate
|
||||||
|
|
||||||
def calculate_net_total(self):
|
def calculate_net_total(self):
|
||||||
self.doc.base_net_total = self.doc.net_total = 0.0
|
self.doc.print_total = self.doc.base_print_total = self.doc.net_total = self.doc.base_net_total = 0.0
|
||||||
|
|
||||||
for item in self.doc.get("items"):
|
for item in self.doc.get("items"):
|
||||||
self.doc.base_net_total += item.base_amount
|
self.doc.print_total += item.amount
|
||||||
self.doc.net_total += item.amount
|
self.doc.base_print_total += item.base_amount
|
||||||
|
self.doc.net_total += item.net_amount
|
||||||
|
self.doc.base_net_total += item.base_net_amount
|
||||||
|
|
||||||
self.doc.round_floats_in(self.doc, ["base_net_total", "net_total"])
|
self.doc.round_floats_in(self.doc, ["print_total", "base_print_total", "net_total", "base_net_total"])
|
||||||
|
|
||||||
def calculate_taxes(self):
|
def calculate_taxes(self):
|
||||||
# maintain actual tax rate based on idx
|
# maintain actual tax rate based on idx
|
||||||
actual_tax_dict = dict([[tax.idx, flt(tax.rate, self.doc.precision("tax_amount", tax))]
|
actual_tax_dict = dict([[tax.idx, flt(tax.tax_amount, tax.precision("tax_amount"))]
|
||||||
for tax in self.doc.get("taxes") if tax.charge_type == "Actual"])
|
for tax in self.doc.get("taxes") if tax.charge_type == "Actual"])
|
||||||
|
|
||||||
for n, item in enumerate(self.doc.get("items")):
|
for n, item in enumerate(self.doc.get("items")):
|
||||||
@ -230,12 +236,10 @@ class calculate_taxes_and_totals(object):
|
|||||||
# note: grand_total_for_current_item contains the contribution of
|
# note: grand_total_for_current_item contains the contribution of
|
||||||
# item's amount, previously applied tax and the current tax on that item
|
# item's amount, previously applied tax and the current tax on that item
|
||||||
if i==0:
|
if i==0:
|
||||||
tax.grand_total_for_current_item = flt(item.base_amount + current_tax_amount,
|
tax.grand_total_for_current_item = flt(item.net_amount + current_tax_amount)
|
||||||
self.doc.precision("total", tax))
|
|
||||||
else:
|
else:
|
||||||
tax.grand_total_for_current_item = \
|
tax.grand_total_for_current_item = \
|
||||||
flt(self.doc.get("taxes")[i-1].grand_total_for_current_item +
|
self.doc.get("taxes")[i-1].grand_total_for_current_item + current_tax_amount
|
||||||
current_tax_amount, self.doc.precision("total", tax))
|
|
||||||
|
|
||||||
# in tax.total, accumulate grand total of each item
|
# in tax.total, accumulate grand total of each item
|
||||||
tax.total += tax.grand_total_for_current_item
|
tax.total += tax.grand_total_for_current_item
|
||||||
@ -254,12 +258,11 @@ class calculate_taxes_and_totals(object):
|
|||||||
|
|
||||||
if tax.charge_type == "Actual":
|
if tax.charge_type == "Actual":
|
||||||
# distribute the tax amount proportionally to each item row
|
# distribute the tax amount proportionally to each item row
|
||||||
actual = flt(tax.rate, self.doc.precision("tax_amount", tax))
|
actual = flt(tax.tax_amount, tax.precision("tax_amount"))
|
||||||
current_tax_amount = (self.doc.base_net_total
|
current_tax_amount = item.net_amount*actual / self.doc.net_total if self.doc.net_total else 0.0
|
||||||
and ((item.base_amount / self.doc.base_net_total) * actual)
|
|
||||||
or 0)
|
|
||||||
elif tax.charge_type == "On Net Total":
|
elif tax.charge_type == "On Net Total":
|
||||||
current_tax_amount = (tax_rate / 100.0) * item.base_amount
|
current_tax_amount = (tax_rate / 100.0) * item.net_amount
|
||||||
elif tax.charge_type == "On Previous Row Amount":
|
elif tax.charge_type == "On Previous Row Amount":
|
||||||
current_tax_amount = (tax_rate / 100.0) * \
|
current_tax_amount = (tax_rate / 100.0) * \
|
||||||
self.doc.get("taxes")[cint(tax.row_id) - 1].tax_amount_for_current_item
|
self.doc.get("taxes")[cint(tax.row_id) - 1].tax_amount_for_current_item
|
||||||
@ -267,72 +270,66 @@ class calculate_taxes_and_totals(object):
|
|||||||
current_tax_amount = (tax_rate / 100.0) * \
|
current_tax_amount = (tax_rate / 100.0) * \
|
||||||
self.doc.get("taxes")[cint(tax.row_id) - 1].grand_total_for_current_item
|
self.doc.get("taxes")[cint(tax.row_id) - 1].grand_total_for_current_item
|
||||||
|
|
||||||
current_tax_amount = flt(current_tax_amount, self.doc.precision("tax_amount", tax))
|
# current_tax_amount = flt(current_tax_amount, tax.precision("tax_amount", tax))
|
||||||
|
|
||||||
# store tax breakup for each item
|
self.set_item_wise_tax(item, tax, tax_rate, current_tax_amount)
|
||||||
key = item.item_code or item.item_name
|
|
||||||
if tax.item_wise_tax_detail.get(key):
|
|
||||||
item_wise_tax_amount = tax.item_wise_tax_detail[key][1] + current_tax_amount
|
|
||||||
tax.item_wise_tax_detail[key] = [tax_rate,item_wise_tax_amount]
|
|
||||||
else:
|
|
||||||
tax.item_wise_tax_detail[key] = [tax_rate,current_tax_amount]
|
|
||||||
|
|
||||||
return current_tax_amount
|
return current_tax_amount
|
||||||
|
|
||||||
|
def set_item_wise_tax(self, item, tax, tax_rate, current_tax_amount):
|
||||||
|
# store tax breakup for each item
|
||||||
|
key = item.item_code or item.item_name
|
||||||
|
item_wise_tax_amount = current_tax_amount*self.doc.conversion_rate
|
||||||
|
if tax.item_wise_tax_detail.get(key):
|
||||||
|
item_wise_tax_amount += tax.item_wise_tax_detail[key][1]
|
||||||
|
|
||||||
|
tax.item_wise_tax_detail[key] = [tax_rate,flt(item_wise_tax_amount, tax.precision("base_tax_amount"))]
|
||||||
|
|
||||||
def round_off_totals(self, tax):
|
def round_off_totals(self, tax):
|
||||||
tax.total = flt(tax.total, self.doc.precision("total", tax))
|
tax.total = flt(tax.total, tax.precision("total"))
|
||||||
tax.tax_amount = flt(tax.tax_amount, self.doc.precision("tax_amount", tax))
|
tax.tax_amount = flt(tax.tax_amount, tax.precision("tax_amount"))
|
||||||
tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount,
|
tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount, tax.precision("tax_amount"))
|
||||||
self.doc.precision("tax_amount", tax))
|
|
||||||
|
|
||||||
def adjust_discount_amount_loss(self, tax):
|
def adjust_discount_amount_loss(self, tax):
|
||||||
discount_amount_loss = self.doc.base_grand_total - flt(self.doc.base_discount_amount) - tax.total
|
discount_amount_loss = self.doc.grand_total - flt(self.doc.discount_amount) - tax.total
|
||||||
tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount +
|
tax.tax_amount_after_discount_amount = flt(tax.tax_amount_after_discount_amount +
|
||||||
discount_amount_loss, self.doc.precision("tax_amount", tax))
|
discount_amount_loss, self.doc.precision("tax_amount", tax))
|
||||||
tax.total = flt(tax.total + discount_amount_loss, self.doc.precision("total", tax))
|
tax.total = flt(tax.total + discount_amount_loss, self.doc.precision("total", tax))
|
||||||
|
|
||||||
def calculate_totals(self):
|
def calculate_totals(self):
|
||||||
self.doc.base_grand_total = flt(self.doc.get("taxes")[-1].total
|
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total
|
||||||
if self.doc.get("taxes") else self.doc.base_net_total)
|
if self.doc.get("taxes") else self.doc.net_total)
|
||||||
|
|
||||||
self.doc.base_total_taxes_and_charges = flt(self.doc.base_grand_total - self.doc.base_net_total,
|
|
||||||
self.doc.precision("base_total_taxes_and_charges"))
|
|
||||||
|
|
||||||
if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
|
if self.doc.doctype in ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"]:
|
||||||
self.doc.grand_total = flt(self.doc.base_grand_total / self.doc.conversion_rate) \
|
self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \
|
||||||
if (self.doc.base_total_taxes_and_charges or self.doc.discount_amount) else self.doc.net_total
|
if self.doc.total_taxes_and_charges else self.doc.base_net_total
|
||||||
|
|
||||||
self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total +
|
|
||||||
flt(self.doc.discount_amount), self.doc.precision("total_taxes_and_charges"))
|
|
||||||
else:
|
else:
|
||||||
self.doc.base_taxes_and_charges_added, self.doc.base_taxes_and_charges_deducted = 0.0, 0.0
|
self.doc.taxes_and_charges_added, self.taxes_and_charges_deducted = 0.0, 0.0
|
||||||
for tax in self.doc.get("taxes"):
|
for tax in self.doc.get("taxes"):
|
||||||
if tax.category in ["Valuation and Total", "Total"]:
|
if tax.category in ["Valuation and Total", "Total"]:
|
||||||
if tax.add_deduct_tax == "Add":
|
if tax.add_deduct_tax == "Add":
|
||||||
self.doc.base_taxes_and_charges_added += flt(tax.tax_amount)
|
self.doc.taxes_and_charges_added += flt(tax.tax_amount)
|
||||||
else:
|
else:
|
||||||
self.doc.base_taxes_and_charges_deducted += flt(tax.tax_amount)
|
self.doc.taxes_and_charges_deducted += flt(tax.tax_amount)
|
||||||
|
|
||||||
self.doc.round_floats_in(self.doc, ["base_taxes_and_charges_added", "base_taxes_and_charges_deducted"])
|
self.doc.round_floats_in(self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"])
|
||||||
|
|
||||||
self.doc.grand_total = flt(self.doc.base_grand_total / self.doc.conversion_rate) \
|
self.doc.base_grand_total = flt(self.doc.grand_total * self.doc.conversion_rate) \
|
||||||
if (self.doc.base_taxes_and_charges_added or self.doc.base_taxes_and_charges_deducted) else self.doc.net_total
|
if (self.doc.taxes_and_charges_added or self.doc.taxes_and_charges_deducted) \
|
||||||
|
else self.doc.base_net_total
|
||||||
|
|
||||||
|
self._set_in_company_currency(self.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"])
|
||||||
|
|
||||||
self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total,
|
self.doc.total_taxes_and_charges = flt(self.doc.grand_total - self.doc.net_total,
|
||||||
self.doc.precision("total_taxes_and_charges"))
|
self.doc.precision("total_taxes_and_charges"))
|
||||||
|
|
||||||
self.doc.taxes_and_charges_added = flt(self.doc.base_taxes_and_charges_added / self.doc.conversion_rate,
|
self._set_in_company_currency(self.doc, ["total_taxes_and_charges"])
|
||||||
self.doc.precision("taxes_and_charges_added"))
|
self.doc.round_floats_in(self.doc, ["grand_total", "base_grand_total"])
|
||||||
self.doc.taxes_and_charges_deducted = flt(self.doc.base_taxes_and_charges_deducted / self.doc.conversion_rate,
|
|
||||||
self.doc.precision("taxes_and_charges_deducted"))
|
|
||||||
|
|
||||||
self.doc.base_grand_total = flt(self.doc.base_grand_total, self.doc.precision("base_grand_total"))
|
|
||||||
self.doc.grand_total = flt(self.doc.grand_total, self.doc.precision("grand_total"))
|
|
||||||
|
|
||||||
if self.doc.meta.get_field("base_rounded_total"):
|
|
||||||
self.doc.base_rounded_total = rounded(self.doc.base_grand_total)
|
|
||||||
if self.doc.meta.get_field("rounded_total"):
|
if self.doc.meta.get_field("rounded_total"):
|
||||||
self.doc.rounded_total = rounded(self.doc.grand_total)
|
self.doc.rounded_total = rounded(self.doc.grand_total)
|
||||||
|
if self.doc.meta.get_field("base_rounded_total"):
|
||||||
|
self.doc.base_rounded_total = rounded(self.doc.base_grand_total)
|
||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
for tax in self.doc.get("taxes"):
|
for tax in self.doc.get("taxes"):
|
||||||
@ -343,20 +340,26 @@ class calculate_taxes_and_totals(object):
|
|||||||
self.doc.base_discount_amount = flt(self.doc.discount_amount * self.doc.conversion_rate,
|
self.doc.base_discount_amount = flt(self.doc.discount_amount * self.doc.conversion_rate,
|
||||||
self.doc.precision("base_discount_amount"))
|
self.doc.precision("base_discount_amount"))
|
||||||
|
|
||||||
grand_total_for_discount_amount = self.get_grand_total_for_discount_amount()
|
total_for_discount_amount = self.get_total_for_discount_amount()
|
||||||
|
|
||||||
if grand_total_for_discount_amount:
|
if total_for_discount_amount:
|
||||||
# calculate item amount after Discount Amount
|
# calculate item amount after Discount Amount
|
||||||
for item in self.doc.get("items"):
|
for item in self.doc.get("items"):
|
||||||
distributed_amount = flt(self.doc.base_discount_amount) * item.base_amount / grand_total_for_discount_amount
|
distributed_amount = flt(self.doc.discount_amount) * item.net_amount / total_for_discount_amount
|
||||||
item.base_amount = flt(item.base_amount - distributed_amount, self.doc.precision("base_amount", item))
|
item.net_amount = flt(item.net_amount - distributed_amount, item.precision("net_amount"))
|
||||||
|
item.net_rate = flt(item.net_amount / item.qty, item.precision("net_rate"))
|
||||||
|
|
||||||
|
self._set_in_company_currency(item, ["net_rate", "net_amount"])
|
||||||
|
|
||||||
self.discount_amount_applied = True
|
self.discount_amount_applied = True
|
||||||
self._calculate()
|
self._calculate()
|
||||||
else:
|
else:
|
||||||
self.doc.base_discount_amount = 0
|
self.doc.base_discount_amount = 0
|
||||||
|
|
||||||
def get_grand_total_for_discount_amount(self):
|
def get_total_for_discount_amount(self):
|
||||||
|
if self.doc.apply_discount_on == "Print Total":
|
||||||
|
return self.net_total
|
||||||
|
else:
|
||||||
actual_taxes_dict = {}
|
actual_taxes_dict = {}
|
||||||
|
|
||||||
for tax in self.doc.get("taxes"):
|
for tax in self.doc.get("taxes"):
|
||||||
@ -366,17 +369,15 @@ class calculate_taxes_and_totals(object):
|
|||||||
actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100
|
actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100
|
||||||
actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
|
actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
|
||||||
|
|
||||||
grand_total_for_discount_amount = flt(self.doc.base_grand_total - sum(actual_taxes_dict.values()),
|
return flt(self.doc.grand_total - sum(actual_taxes_dict.values()), self.doc.precision("grand_total"))
|
||||||
self.doc.precision("base_grand_total"))
|
|
||||||
return grand_total_for_discount_amount
|
|
||||||
|
|
||||||
|
|
||||||
def calculate_total_advance(self):
|
def calculate_total_advance(self, parenttype, advance_parentfield):
|
||||||
if self.doc.docstatus < 2:
|
if self.docstatus < 2:
|
||||||
sum_of_allocated_amount = sum([flt(adv.allocated_amount, self.doc.precision("allocated_amount", adv))
|
total_allocated_amount = sum([flt(adv.allocated_amount, adv.precision("allocated_amount"))
|
||||||
for adv in self.doc.get("advances")])
|
for adv in self.doc.get("advances")])
|
||||||
|
|
||||||
self.doc.total_advance = flt(sum_of_allocated_amount, self.doc.precision("total_advance"))
|
self.doc.total_advance = flt(total_allocated_amount, self.doc.precision("total_advance"))
|
||||||
|
|
||||||
if self.doc.docstatus == 0:
|
if self.doc.docstatus == 0:
|
||||||
self.calculate_outstanding_amount()
|
self.calculate_outstanding_amount()
|
||||||
|
@ -38,22 +38,46 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
this.show_item_wise_taxes();
|
this.show_item_wise_taxes();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
validate_conversion_rate: function() {
|
||||||
|
this.frm.doc.conversion_rate = flt(this.frm.doc.conversion_rate, precision("conversion_rate"));
|
||||||
|
var conversion_rate_label = frappe.meta.get_label(this.frm.doc.doctype, "conversion_rate",
|
||||||
|
this.frm.doc.name);
|
||||||
|
var company_currency = this.get_company_currency();
|
||||||
|
|
||||||
|
if(!this.frm.doc.conversion_rate) {
|
||||||
|
frappe.throw(repl('%(conversion_rate_label)s' +
|
||||||
|
__(' is mandatory. Maybe Currency Exchange record is not created for ') +
|
||||||
|
'%(from_currency)s' + __(" to ") + '%(to_currency)s',
|
||||||
|
{
|
||||||
|
"conversion_rate_label": conversion_rate_label,
|
||||||
|
"from_currency": this.frm.doc.currency,
|
||||||
|
"to_currency": company_currency
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
calculate_item_values: function() {
|
calculate_item_values: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
if (!this.discount_amount_applied) {
|
if (!this.discount_amount_applied) {
|
||||||
$.each(this.frm.doc["items"] || [], function(i, item) {
|
$.each(this.frm.doc["items"] || [], function(i, item) {
|
||||||
frappe.model.round_floats_in(item);
|
frappe.model.round_floats_in(item);
|
||||||
|
item.net_rate = item.rate;
|
||||||
item.amount = flt(item.rate * item.qty, precision("amount", item));
|
item.amount = flt(item.rate * item.qty, precision("amount", item));
|
||||||
|
item.net_amount = item.amount;
|
||||||
item.item_tax_amount = 0.0;
|
item.item_tax_amount = 0.0;
|
||||||
|
|
||||||
$.each(["price_list_rate", "rate", "amount"], function(i, f) {
|
this.set_in_company_currency(item, ["price_list_rate", "rate", "amount", "net_rate", "net_amount"]);
|
||||||
item["base_" + f] = flt(item[f] * me.frm.doc.conversion_rate, precision("base_" + f, item));
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set_in_company_currency: function(doc, fields) {
|
||||||
|
$.each(fields, function(i, f) {
|
||||||
|
doc["base_"+f] = flt(flt(doc[f], precision(f, doc)) * me.frm.doc.conversion_rate, precision("base_" + f, doc));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
initialize_taxes: function() {
|
initialize_taxes: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
@ -75,7 +99,12 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
determine_exclusive_rate: function() {
|
determine_exclusive_rate: function() {
|
||||||
if(!in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"], this.frm.doc.doctype)) return;
|
var has_inclusive_tax = false;
|
||||||
|
$.each(me.frm.doc["taxes"] || [], function(i, row) {
|
||||||
|
if(cint(row.included_in_print_rate)) has_inclusive_tax = true;
|
||||||
|
})
|
||||||
|
if(has_inclusive_tax==false || !in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"], this.frm.doc.doctype))
|
||||||
|
return;
|
||||||
|
|
||||||
var me = this;
|
var me = this;
|
||||||
$.each(me.frm.doc["items"] || [], function(n, item) {
|
$.each(me.frm.doc["items"] || [], function(n, item) {
|
||||||
@ -97,19 +126,21 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if(cumulated_tax_fraction && !me.discount_amount_applied) {
|
if(cumulated_tax_fraction && !me.discount_amount_applied) {
|
||||||
item.base_amount = flt(
|
item.net_amount = flt(
|
||||||
(item.amount * me.frm.doc.conversion_rate) / (1 + cumulated_tax_fraction),
|
(item.amount * me.frm.doc.conversion_rate) / (1 + cumulated_tax_fraction),
|
||||||
precision("base_amount", item));
|
precision("net_amount", item));
|
||||||
|
|
||||||
item.base_rate = flt(item.base_amount / item.qty, precision("base_rate", item));
|
item.net_rate = flt(item.net_amount / item.qty, precision("net_rate", item));
|
||||||
|
|
||||||
if(item.discount_percentage == 100) {
|
this.set_in_company_currency(item, ["net_rate", "net_amount"]);
|
||||||
item.base_price_list_rate = item.base_rate;
|
|
||||||
item.base_rate = 0.0;
|
// if(item.discount_percentage == 100) {
|
||||||
} else {
|
// item.base_price_list_rate = item.base_rate;
|
||||||
item.base_price_list_rate = flt(item.base_rate / (1 - item.discount_percentage / 100.0),
|
// item.base_rate = 0.0;
|
||||||
precision("base_price_list_rate", item));
|
// } else {
|
||||||
}
|
// item.base_price_list_rate = flt(item.base_rate / (1 - item.discount_percentage / 100.0),
|
||||||
|
// precision("base_price_list_rate", item));
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -140,20 +171,21 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
|
|
||||||
_get_tax_rate: function(tax, item_tax_map) {
|
_get_tax_rate: function(tax, item_tax_map) {
|
||||||
return (keys(item_tax_map).indexOf(tax.account_head) != -1) ?
|
return (keys(item_tax_map).indexOf(tax.account_head) != -1) ?
|
||||||
flt(item_tax_map[tax.account_head], precision("rate", tax)) :
|
flt(item_tax_map[tax.account_head], precision("rate", tax)) : tax.rate;
|
||||||
tax.rate;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
calculate_net_total: function() {
|
calculate_net_total: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
this.frm.doc.base_net_total = this.frm.doc.net_total = 0.0;
|
this.frm.doc.print_total = this.frm.doc.base_print_total = this.frm.doc.net_total = this.frm.doc.base_net_total = 0.0;
|
||||||
|
|
||||||
$.each(this.frm.doc["items"] || [], function(i, item) {
|
$.each(this.frm.doc["items"] || [], function(i, item) {
|
||||||
me.frm.doc.base_net_total += item.base_amount;
|
me.frm.doc.print_total += item.amount;
|
||||||
me.frm.doc.net_total += item.amount;
|
me.frm.doc.base_print_total += item.base_amount;
|
||||||
|
me.frm.doc.net_total += item.net_amount;
|
||||||
|
me.frm.doc.base_net_total += item.base_net_amount;
|
||||||
});
|
});
|
||||||
|
|
||||||
frappe.model.round_floats_in(this.frm.doc, ["base_net_total", "net_total"]);
|
frappe.model.round_floats_in(this.frm.doc, ["print_total", "base_print_total", "net_total", "base_net_total"]);
|
||||||
},
|
},
|
||||||
|
|
||||||
calculate_taxes: function() {
|
calculate_taxes: function() {
|
||||||
@ -163,7 +195,7 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
// maintain actual tax rate based on idx
|
// maintain actual tax rate based on idx
|
||||||
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
||||||
if (tax.charge_type == "Actual") {
|
if (tax.charge_type == "Actual") {
|
||||||
actual_tax_dict[tax.idx] = flt(tax.rate, precision("tax_amount", tax));
|
actual_tax_dict[tax.idx] = flt(tax.tax_amount, precision("tax_amount", tax));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -205,12 +237,10 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
// note: grand_total_for_current_item contains the contribution of
|
// note: grand_total_for_current_item contains the contribution of
|
||||||
// item's amount, previously applied tax and the current tax on that item
|
// item's amount, previously applied tax and the current tax on that item
|
||||||
if(i==0) {
|
if(i==0) {
|
||||||
tax.grand_total_for_current_item = flt(item.base_amount + current_tax_amount,
|
tax.grand_total_for_current_item = flt(item.base_amount + current_tax_amount);
|
||||||
precision("total", tax));
|
|
||||||
} else {
|
} else {
|
||||||
tax.grand_total_for_current_item =
|
tax.grand_total_for_current_item =
|
||||||
flt(me.frm.doc["taxes"][i-1].grand_total_for_current_item + current_tax_amount,
|
flt(me.frm.doc["taxes"][i-1].grand_total_for_current_item + current_tax_amount);
|
||||||
precision("total", tax));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// in tax.total, accumulate grand total for each item
|
// in tax.total, accumulate grand total for each item
|
||||||
@ -238,12 +268,12 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
|
|
||||||
if(tax.charge_type == "Actual") {
|
if(tax.charge_type == "Actual") {
|
||||||
// distribute the tax amount proportionally to each item row
|
// distribute the tax amount proportionally to each item row
|
||||||
var actual = flt(tax.rate, precision("tax_amount", tax));
|
var actual = flt(tax.tax_amount, precision("tax_amount", tax));
|
||||||
current_tax_amount = this.frm.doc.base_net_total ?
|
current_tax_amount = this.frm.doc.net_total ?
|
||||||
((item.base_amount / this.frm.doc.base_net_total) * actual) : 0.0;
|
((item.net_amount / this.frm.doc.net_total) * actual) : 0.0;
|
||||||
|
|
||||||
} else if(tax.charge_type == "On Net Total") {
|
} else if(tax.charge_type == "On Net Total") {
|
||||||
current_tax_amount = (tax_rate / 100.0) * item.base_amount;
|
current_tax_amount = (tax_rate / 100.0) * item.net_amount;
|
||||||
|
|
||||||
} else if(tax.charge_type == "On Previous Row Amount") {
|
} else if(tax.charge_type == "On Previous Row Amount") {
|
||||||
current_tax_amount = (tax_rate / 100.0) *
|
current_tax_amount = (tax_rate / 100.0) *
|
||||||
@ -254,14 +284,24 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_for_current_item;
|
this.frm.doc["taxes"][cint(tax.row_id) - 1].grand_total_for_current_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_tax_amount = flt(current_tax_amount, precision("tax_amount", tax));
|
// current_tax_amount = flt(current_tax_amount, precision("tax_amount", tax));
|
||||||
|
|
||||||
// store tax breakup for each item
|
this.set_item_wise_tax(item, tax, tax_rate, current_tax_amount);
|
||||||
tax.item_wise_tax_detail[item.item_code || item.item_name] = [tax_rate, current_tax_amount];
|
|
||||||
|
|
||||||
return current_tax_amount;
|
return current_tax_amount;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set_item_wise_tax: function(item, tax, tax_rate, current_tax_amount) {
|
||||||
|
// store tax breakup for each item
|
||||||
|
var key = item.item_code || item.item_name;
|
||||||
|
var item_wise_tax_amount = current_tax_amount * this.frm.doc.conversion_rate;
|
||||||
|
if (tax.item_wise_tax_detail.get(key))
|
||||||
|
item_wise_tax_amount += tax.item_wise_tax_detail[key][1]
|
||||||
|
|
||||||
|
tax.item_wise_tax_detail[key] = [tax_rate,flt(item_wise_tax_amount, precision("base_tax_amount", tax))]
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
round_off_totals: function(tax) {
|
round_off_totals: function(tax) {
|
||||||
tax.total = flt(tax.total, precision("total", tax));
|
tax.total = flt(tax.total, precision("total", tax));
|
||||||
tax.tax_amount = flt(tax.tax_amount, precision("tax_amount", tax));
|
tax.tax_amount = flt(tax.tax_amount, precision("tax_amount", tax));
|
||||||
@ -276,9 +316,55 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
tax.total = flt(tax.total + discount_amount_loss, precision("total", tax));
|
tax.total = flt(tax.total + discount_amount_loss, precision("total", tax));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
calculate_totals: function() {
|
||||||
|
// Changing sequence can cause roundiing issue and on-screen discrepency
|
||||||
|
var me = this;
|
||||||
|
var tax_count = this.frm.doc["taxes"] ? this.frm.doc["taxes"].length : 0;
|
||||||
|
this.frm.doc.grand_total = flt(tax_count ? this.frm.doc["taxes"][tax_count - 1].total : this.frm.doc.net_total);
|
||||||
|
|
||||||
|
if(in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"], this.frm.doc.doctype)) {
|
||||||
|
this.frm.doc.base_grand_total = (this.frm.doc.base_total_taxes_and_charges) ?
|
||||||
|
flt(this.frm.doc.grand_total * this.frm.doc.conversion_rate) : this.frm.doc.base_net_total;
|
||||||
|
} else {
|
||||||
|
// other charges added/deducted
|
||||||
|
this.frm.doc.taxes_and_charges_added = this.frm.doc.taxes_and_charges_deducted = 0.0;
|
||||||
|
if(tax_count) {
|
||||||
|
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
|
||||||
|
if in_list(["Valuation and Total", "Total"], tax.category) {
|
||||||
|
if(tax.add_deduct_tax == "Add") {
|
||||||
|
me.frm.doc.taxes_and_charges_added += flt(tax.tax_amount);
|
||||||
|
} else {
|
||||||
|
me.frm.doc.taxes_and_charges_deducted += flt(tax.tax_amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
frappe.model.round_floats_in(this.frm.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.frm.doc.grand_total = flt((this.frm.doc.taxes_and_charges_added || this.frm.doc.taxes_and_charges_deducted) ?
|
||||||
|
flt(this.frm.doc.grand_total * this.frm.doc.conversion_rate) : this.frm.doc.base_net_total);
|
||||||
|
|
||||||
|
this.set_in_company_currency(this.frm.doc, ["taxes_and_charges_added", "taxes_and_charges_deducted"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.frm.doc.total_taxes_and_charges = flt(this.frm.doc.grand_total - this.frm.doc.net_total,
|
||||||
|
precision("total_taxes_and_charges"));
|
||||||
|
|
||||||
|
// Round grand total as per precision
|
||||||
|
frappe.model.round_floats_in(this.frm.doc, ["grand_total", "base_grand_total"]);
|
||||||
|
|
||||||
|
// rounded totals
|
||||||
|
if(frappe.meta.get_docfield(this.frm.doc.doctype, "rounded_total", this.frm.doc.name)) {
|
||||||
|
this.frm.doc.rounded_total = Math.round(this.frm.doc.grand_total);
|
||||||
|
}
|
||||||
|
if(frappe.meta.get_docfield(this.frm.doc.doctype, "base_rounded_total", this.frm.doc.name)) {
|
||||||
|
this.frm.doc.base_rounded_total = Math.round(this.frm.doc.base_grand_total);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
_cleanup: function() {
|
_cleanup: function() {
|
||||||
this.frm.doc.base_in_words = this.frm.doc.in_words = this.frm.doc.in_words = "";
|
this.frm.doc.base_in_words = this.frm.doc.in_words = "";
|
||||||
|
|
||||||
if(this.frm.doc["items"] && this.frm.doc["items"].length) {
|
if(this.frm.doc["items"] && this.frm.doc["items"].length) {
|
||||||
if(!frappe.meta.get_docfield(this.frm.doc["items"][0].doctype, "item_tax_amount", this.frm.doctype)) {
|
if(!frappe.meta.get_docfield(this.frm.doc["items"][0].doctype, "item_tax_amount", this.frm.doctype)) {
|
||||||
@ -288,7 +374,6 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(this.frm.doc["taxes"] && this.frm.doc["taxes"].length) {
|
if(this.frm.doc["taxes"] && this.frm.doc["taxes"].length) {
|
||||||
var temporary_fields = ["tax_amount_for_current_item", "grand_total_for_current_item",
|
var temporary_fields = ["tax_amount_for_current_item", "grand_total_for_current_item",
|
||||||
"tax_fraction_for_current_item", "grand_total_fraction_for_current_item"]
|
"tax_fraction_for_current_item", "grand_total_fraction_for_current_item"]
|
||||||
@ -307,65 +392,6 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
calculate_totals: function() {
|
|
||||||
// Changing sequence can cause roundiing issue and on-screen discrepency
|
|
||||||
|
|
||||||
var tax_count = this.frm.doc["taxes"] ? this.frm.doc["taxes"].length : 0;
|
|
||||||
this.frm.doc.base_grand_total = flt(tax_count ? this.frm.doc["taxes"][tax_count - 1].total : this.frm.doc.base_net_total);
|
|
||||||
|
|
||||||
this.frm.doc.base_total_taxes_and_charges = flt(this.frm.doc.base_grand_total - this.frm.doc.base_net_total,
|
|
||||||
precision("base_total_taxes_and_charges"));
|
|
||||||
|
|
||||||
if(in_list(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"], this.frm.doc.doctype)) {
|
|
||||||
this.frm.doc.grand_total = (this.frm.doc.base_total_taxes_and_charges || this.frm.doc.discount_amount) ?
|
|
||||||
flt(this.frm.doc.base_grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total;
|
|
||||||
|
|
||||||
this.frm.doc.total_taxes_and_charges = flt(this.frm.doc.grand_total - this.frm.doc.net_total
|
|
||||||
+ flt(this.frm.doc.discount_amount), precision("total_taxes_and_charges"));
|
|
||||||
} else {
|
|
||||||
// other charges added/deducted
|
|
||||||
this.frm.doc.base_taxes_and_charges_added = 0.0
|
|
||||||
this.frm.doc.base_taxes_and_charges_deducted = 0.0
|
|
||||||
if(tax_count) {
|
|
||||||
this.frm.doc.base_taxes_and_charges_added = frappe.utils.sum($.map(this.frm.doc["taxes"],
|
|
||||||
function(tax) { return (tax.add_deduct_tax == "Add"
|
|
||||||
&& in_list(["Valuation and Total", "Total"], tax.category)) ?
|
|
||||||
tax.tax_amount : 0.0; }));
|
|
||||||
|
|
||||||
this.frm.doc.base_taxes_and_charges_deducted = frappe.utils.sum($.map(this.frm.doc["taxes"],
|
|
||||||
function(tax) { return (tax.add_deduct_tax == "Deduct"
|
|
||||||
&& in_list(["Valuation and Total", "Total"], tax.category)) ?
|
|
||||||
tax.tax_amount : 0.0; }));
|
|
||||||
|
|
||||||
frappe.model.round_floats_in(this.frm.doc,
|
|
||||||
["base_taxes_and_charges_added", "base_taxes_and_charges_deducted"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.frm.doc.grand_total = flt((this.frm.doc.base_taxes_and_charges_added || this.frm.doc.base_taxes_and_charges_deducted) ?
|
|
||||||
flt(this.frm.doc.base_grand_total / this.frm.doc.conversion_rate) : this.frm.doc.net_total);
|
|
||||||
|
|
||||||
this.frm.doc.total_taxes_and_charges = flt(this.frm.doc.grand_total - this.frm.doc.net_total,
|
|
||||||
precision("total_taxes_and_charges"));
|
|
||||||
|
|
||||||
this.frm.doc.taxes_and_charges_added = flt(this.frm.doc.base_taxes_and_charges_added /
|
|
||||||
this.frm.doc.conversion_rate, precision("taxes_and_charges_added"));
|
|
||||||
this.frm.doc.taxes_and_charges_deducted = flt(this.frm.doc.base_taxes_and_charges_deducted /
|
|
||||||
this.frm.doc.conversion_rate, precision("taxes_and_charges_deducted"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Round grand total as per precision
|
|
||||||
this.frm.doc.base_grand_total = flt(this.frm.doc.base_grand_total, precision("base_grand_total"));
|
|
||||||
this.frm.doc.grand_total = flt(this.frm.doc.grand_total, precision("grand_total"));
|
|
||||||
|
|
||||||
// rounded totals
|
|
||||||
if(frappe.meta.get_docfield(this.frm.doc.doctype, "base_rounded_total", this.frm.doc.name)) {
|
|
||||||
this.frm.doc.base_rounded_total = Math.round(this.frm.doc.base_grand_total);
|
|
||||||
}
|
|
||||||
if(frappe.meta.get_docfield(this.frm.doc.doctype, "rounded_total", this.frm.doc.name)) {
|
|
||||||
this.frm.doc.rounded_total = Math.round(this.frm.doc.grand_total);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
apply_discount_amount: function() {
|
apply_discount_amount: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
var distributed_amount = 0.0;
|
var distributed_amount = 0.0;
|
||||||
@ -374,12 +400,15 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
this.frm.set_value("base_discount_amount",
|
this.frm.set_value("base_discount_amount",
|
||||||
flt(this.frm.doc.discount_amount * this.frm.doc.conversion_rate, precision("base_discount_amount")))
|
flt(this.frm.doc.discount_amount * this.frm.doc.conversion_rate, precision("base_discount_amount")))
|
||||||
|
|
||||||
var grand_total_for_discount_amount = this.get_grand_total_for_discount_amount();
|
var total_for_discount_amount = this.get_total_for_discount_amount();
|
||||||
// calculate item amount after Discount Amount
|
// calculate item amount after Discount Amount
|
||||||
if (grand_total_for_discount_amount) {
|
if (total_for_discount_amount) {
|
||||||
$.each(this.frm.doc["items"] || [], function(i, item) {
|
$.each(this.frm.doc["items"] || [], function(i, item) {
|
||||||
distributed_amount = flt(me.frm.doc.base_discount_amount) * item.base_amount / grand_total_for_discount_amount;
|
distributed_amount = flt(me.frm.doc.discount_amount) * item.net_amount / total_for_discount_amount;
|
||||||
item.base_amount = flt(item.base_amount - distributed_amount, precision("base_amount", item));
|
item.base_amount = flt(item.net_amount - distributed_amount, precision("base_amount", item));
|
||||||
|
item.net_rate = flt(item.net_amount / item.qty, precision("net_rate", item));
|
||||||
|
|
||||||
|
me.set_in_company_currency(item, ["net_rate", "net_amount"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.discount_amount_applied = true;
|
this.discount_amount_applied = true;
|
||||||
@ -390,8 +419,12 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
get_grand_total_for_discount_amount: function() {
|
get_total_for_discount_amount: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
|
|
||||||
|
if(this.apply_discount_amount == "Print Total") {
|
||||||
|
return this.net_total
|
||||||
|
} else {
|
||||||
var total_actual_tax = 0.0;
|
var total_actual_tax = 0.0;
|
||||||
var actual_taxes_dict = {};
|
var actual_taxes_dict = {};
|
||||||
|
|
||||||
@ -409,15 +442,15 @@ erpnext.taxes_and_totals = erpnext.stock.StockController.extend({
|
|||||||
total_actual_tax += value;
|
total_actual_tax += value;
|
||||||
});
|
});
|
||||||
|
|
||||||
grand_total_for_discount_amount = flt(this.frm.doc.base_grand_total - total_actual_tax,
|
return flt(this.frm.doc.grand_total - total_actual_tax, precision("grand_total"));
|
||||||
precision("base_grand_total"));
|
}
|
||||||
return grand_total_for_discount_amount;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
calculate_total_advance: function(update_paid_amount) {
|
calculate_total_advance: function(update_paid_amount) {
|
||||||
this.frm.doc.total_advance = flt(frappe.utils.sum(
|
var total_allocated_amount = frappe.utils.sum($.map(this.frm.doc["advances"] || [], function(adv) {
|
||||||
$.map(this.frm.doc["advances"] || [], function(adv) { return adv.allocated_amount })
|
return flt(adv.allocated_amount, precision("allocated_amount", adv))
|
||||||
), precision("total_advance"));
|
}));
|
||||||
|
this.frm.doc.total_advance = flt(total_allocated_amount, precision("total_advance"));
|
||||||
|
|
||||||
this.calculate_outstanding_amount(update_paid_amount);
|
this.calculate_outstanding_amount(update_paid_amount);
|
||||||
}
|
}
|
||||||
|
@ -560,24 +560,6 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
return valid;
|
return valid;
|
||||||
},
|
},
|
||||||
|
|
||||||
validate_conversion_rate: function() {
|
|
||||||
this.frm.doc.conversion_rate = flt(this.frm.doc.conversion_rate, precision("conversion_rate"));
|
|
||||||
var conversion_rate_label = frappe.meta.get_label(this.frm.doc.doctype, "conversion_rate",
|
|
||||||
this.frm.doc.name);
|
|
||||||
var company_currency = this.get_company_currency();
|
|
||||||
|
|
||||||
if(!this.frm.doc.conversion_rate) {
|
|
||||||
frappe.throw(repl('%(conversion_rate_label)s' +
|
|
||||||
__(' is mandatory. Maybe Currency Exchange record is not created for ') +
|
|
||||||
'%(from_currency)s' + __(" to ") + '%(to_currency)s',
|
|
||||||
{
|
|
||||||
"conversion_rate_label": conversion_rate_label,
|
|
||||||
"from_currency": this.frm.doc.currency,
|
|
||||||
"to_currency": company_currency
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get_terms: function() {
|
get_terms: function() {
|
||||||
var me = this;
|
var me = this;
|
||||||
if(this.frm.doc.tc_name) {
|
if(this.frm.doc.tc_name) {
|
||||||
|
@ -159,4 +159,6 @@ cur_frm.cscript.on_submit = function(doc, cdt, cdn) {
|
|||||||
cur_frm.email_doc(frappe.boot.notification_settings.quotation_message);
|
cur_frm.email_doc(frappe.boot.notification_settings.quotation_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frappe.ui.form.on("Quotation Item", "items_on_form_rendered", function(frm, cdt, cdn) {
|
||||||
|
// enable tax_amount field if Actual
|
||||||
|
})
|
||||||
|
@ -312,6 +312,16 @@
|
|||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"read_only": 0
|
"read_only": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "base_print_total",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Print Total (Company Currency)",
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "base_net_total",
|
"fieldname": "base_net_total",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
@ -331,6 +341,15 @@
|
|||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "print_total",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Print Total",
|
||||||
|
"options": "currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "net_total",
|
"fieldname": "net_total",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
@ -430,6 +449,15 @@
|
|||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
"permlevel": 0
|
"permlevel": 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"default": "Grand Total",
|
||||||
|
"fieldname": "apply_discount_on",
|
||||||
|
"fieldtype": "Select",
|
||||||
|
"label": "Apply Discount On",
|
||||||
|
"options": "\nGrand Total\nPrint Total",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "discount_amount",
|
"fieldname": "discount_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
|
@ -187,6 +187,14 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "net_rate",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Net Rate",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "amount",
|
"fieldname": "amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
@ -204,6 +212,16 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "net_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Net Amount",
|
||||||
|
"options": "currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "col_break3",
|
"fieldname": "col_break3",
|
||||||
"fieldtype": "Column Break",
|
"fieldtype": "Column Break",
|
||||||
@ -213,7 +231,7 @@
|
|||||||
"fieldname": "base_rate",
|
"fieldname": "base_rate",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"label": "Basic Rate (Company Currency)",
|
"label": "Rate (Company Currency)",
|
||||||
"oldfieldname": "basic_rate",
|
"oldfieldname": "basic_rate",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
@ -225,6 +243,14 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "base_net_rate",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Net Rate (Company Currency)",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "base_amount",
|
"fieldname": "base_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
@ -241,6 +267,16 @@
|
|||||||
"search_index": 0,
|
"search_index": 0,
|
||||||
"width": "100px"
|
"width": "100px"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "base_net_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Net Amount (Company Currency)",
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "pricing_rule",
|
"fieldname": "pricing_rule",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
@ -349,7 +385,7 @@
|
|||||||
],
|
],
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"modified": "2015-02-19 01:07:01.742936",
|
"modified": "2015-02-19 15:08:25.451407",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Selling",
|
"module": "Selling",
|
||||||
"name": "Quotation Item",
|
"name": "Quotation Item",
|
||||||
|
@ -53,7 +53,7 @@ class StockLedgerEntry(Document):
|
|||||||
|
|
||||||
def validate_item(self):
|
def validate_item(self):
|
||||||
item_det = frappe.db.sql("""select name, has_batch_no, docstatus,
|
item_det = frappe.db.sql("""select name, has_batch_no, docstatus,
|
||||||
is_stock_item, has_variants
|
is_stock_item, has_variants, stock_uom
|
||||||
from tabItem where name=%s""", self.item_code, as_dict=True)[0]
|
from tabItem where name=%s""", self.item_code, as_dict=True)[0]
|
||||||
|
|
||||||
if item_det.is_stock_item != 'Yes':
|
if item_det.is_stock_item != 'Yes':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user