Merge pull request #3767 from nabinhait/tax_calc
[fix] Tax calculation while discount applied on net total
diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py
index 1623f3f..bb8c65b 100644
--- a/erpnext/controllers/accounts_controller.py
+++ b/erpnext/controllers/accounts_controller.py
@@ -11,6 +11,8 @@
from erpnext.controllers.recurring_document import convert_to_recurring, validate_recurring_document
from erpnext.controllers.sales_and_purchase_return import validate_return
+force_item_fields = ("item_name", "item_group", "barcode", "brand", "stock_uom")
+
class CustomerFrozen(frappe.ValidationError): pass
class AccountsController(TransactionBase):
@@ -18,12 +20,12 @@
if self.get("_action") and self._action != "update_after_submit":
self.set_missing_values(for_validate=True)
self.validate_date_with_fiscal_year()
-
+
if self.meta.get_field("currency"):
self.calculate_taxes_and_totals()
if not self.meta.get_field("is_return") or not self.is_return:
self.validate_value("base_grand_total", ">=", 0)
-
+
validate_return(self)
self.set_total_in_words()
@@ -35,7 +37,7 @@
if self.meta.get_field("taxes_and_charges"):
self.validate_enabled_taxes_and_charges()
-
+
self.validate_party()
def on_submit(self):
@@ -86,7 +88,7 @@
if self.doctype == "Sales Invoice":
if not self.due_date:
frappe.throw(_("Due Date is mandatory"))
-
+
validate_due_date(self.posting_date, self.due_date, "Customer", self.customer, self.company)
elif self.doctype == "Purchase Invoice":
validate_due_date(self.posting_date, self.due_date, "Supplier", self.supplier, self.company)
@@ -142,7 +144,8 @@
for fieldname, value in ret.items():
if item.meta.get_field(fieldname) and \
- item.get(fieldname) is None and value is not None:
+ (item.get(fieldname) is None or fieldname in force_item_fields) \
+ and value is not None:
item.set(fieldname, value)
if fieldname == "cost_center" and item.meta.get_field("cost_center") \
@@ -349,14 +352,14 @@
frozen_accounts_modifier = frappe.db.get_value( 'Accounts Settings', None,'frozen_accounts_modifier')
if frozen_accounts_modifier in frappe.get_roles():
return
-
+
party_type = None
if self.meta.get_field("customer"):
party_type = 'Customer'
elif self.meta.get_field("supplier"):
party_type = 'Supplier'
-
+
if party_type:
party = self.get(party_type.lower())
if frappe.db.get_value(party_type, party, "is_frozen"):
diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py
index cebeaf5..cfde04b 100644
--- a/erpnext/controllers/stock_controller.py
+++ b/erpnext/controllers/stock_controller.py
@@ -218,7 +218,7 @@
tuple(item_codes))
return serialized_items
-
+
def get_incoming_rate_for_sales_return(self, item_code, against_document):
incoming_rate = 0.0
if against_document and item_code:
@@ -229,12 +229,12 @@
incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
return incoming_rate
-
+
def update_reserved_qty(self, d):
if d['reserved_qty'] < 0 :
# Reduce reserved qty from reserved warehouse mentioned in so
if not d["reserved_warehouse"]:
- frappe.throw(_("Reserved Warehouse is missing in Sales Order"))
+ frappe.throw(_("Delivery Warehouse is missing in Sales Order"))
args = {
"item_code": d['item_code'],
diff --git a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
index c4cebb8..e302cc7 100644
--- a/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
+++ b/erpnext/manufacturing/doctype/production_planning_tool/production_planning_tool.py
@@ -44,31 +44,35 @@
""" Pull sales orders which are pending to deliver based on criteria selected"""
so_filter = item_filter = ""
if self.from_date:
- so_filter += ' and so.transaction_date >= "' + self.from_date + '"'
+ so_filter += " and so.transaction_date >= %(from_date)s"
if self.to_date:
- so_filter += ' and so.transaction_date <= "' + self.to_date + '"'
+ so_filter += " and so.transaction_date <= %(to_date)s"
if self.customer:
- so_filter += ' and so.customer = "' + self.customer + '"'
+ so_filter += " and so.customer = %(customer)s"
if self.fg_item:
- item_filter += ' and item.name = "' + self.fg_item + '"'
+ item_filter += " and item.name = %(item)s"
open_so = frappe.db.sql("""
select distinct so.name, so.transaction_date, so.customer, so.base_grand_total
from `tabSales Order` so, `tabSales Order Item` so_item
where so_item.parent = so.name
and so.docstatus = 1 and so.status != "Stopped"
- and so.company = %s
- and ifnull(so_item.qty, 0) > ifnull(so_item.delivered_qty, 0) %s
+ and so.company = %(company)s
+ and ifnull(so_item.qty, 0) > ifnull(so_item.delivered_qty, 0) {0}
and (exists (select name from `tabItem` item where item.name=so_item.item_code
- and (item.is_pro_applicable = 1
- or item.is_sub_contracted_item = 1 %s)
+ and (item.is_pro_applicable = 1 or item.is_sub_contracted_item = 1 {1}))
or exists (select name from `tabPacked Item` pi
where pi.parent = so.name and pi.parent_item = so_item.item_code
and exists (select name from `tabItem` item where item.name=pi.item_code
- and (item.is_pro_applicable = 1
- or item.is_sub_contracted_item = 1) %s)))
- """ % ('%s', so_filter, item_filter, item_filter), self.company, as_dict=1)
+ and (item.is_pro_applicable = 1 or item.is_sub_contracted_item = 1) {2})))
+ """.format(so_filter, item_filter, item_filter), {
+ "from_date": self.from_date,
+ "to_date": self.to_date,
+ "customer": self.customer,
+ "item": self.fg_item,
+ "company": self.company
+ }, as_dict=1)
self.add_so_in_table(open_so)
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index 608d01a..089c067 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -108,9 +108,13 @@
def check_stock_uom_with_bin(self):
if not self.get("__islocal"):
+ if self.stock_uom == frappe.db.get_value("Item", self.name, "stock_uom"):
+ return
+
matched=True
ref_uom = frappe.db.get_value("Stock Ledger Entry",
{"item_code": self.name}, "stock_uom")
+
if ref_uom:
if cstr(ref_uom) != cstr(self.stock_uom):
matched = False
@@ -128,7 +132,7 @@
(self.stock_uom, self.name))
if not matched:
- frappe.throw(_("Default Unit of Measure can not be changed directly because you have already made some transaction(s) with another UOM. To change default UOM, use 'UOM Replace Utility' tool under Stock module."))
+ frappe.throw(_("Default Unit of Measure for Item {0} cannot be changed directly because you have already made some transaction(s) with another UOM. To change default UOM, use 'UOM Replace Utility' tool under Stock module.").format(self.name))
def update_template_tables(self):
template = frappe.get_doc("Item", self.variant_of)
diff --git a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
index 249815f..797b2a0 100644
--- a/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
+++ b/erpnext/stock/doctype/stock_ledger_entry/stock_ledger_entry.py
@@ -82,8 +82,7 @@
frappe.throw(_("Stock cannot exist for Item {0} since has variants").format(self.item_code),
ItemTemplateCannotHaveStock)
- if not self.stock_uom:
- self.stock_uom = item_det.stock_uom
+ self.stock_uom = item_det.stock_uom
def check_stock_frozen_date(self):
stock_frozen_upto = frappe.db.get_value('Stock Settings', None, 'stock_frozen_upto') or ''