Changed UOM validation for Item Master
This commit is contained in:
parent
7e4b93f48e
commit
9a73b7a319
@ -48,7 +48,7 @@ class Item(WebsiteGenerator):
|
|||||||
self.website_image = self.image
|
self.website_image = self.image
|
||||||
|
|
||||||
self.check_warehouse_is_set_for_stock_item()
|
self.check_warehouse_is_set_for_stock_item()
|
||||||
self.check_stock_uom_with_bin()
|
self.validate_uom()
|
||||||
self.add_default_uom_in_conversion_factor_table()
|
self.add_default_uom_in_conversion_factor_table()
|
||||||
self.validate_conversion_factor()
|
self.validate_conversion_factor()
|
||||||
self.validate_item_type()
|
self.validate_item_type()
|
||||||
@ -105,35 +105,6 @@ class Item(WebsiteGenerator):
|
|||||||
|
|
||||||
[self.remove(d) for d in to_remove]
|
[self.remove(d) for d in to_remove]
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
else:
|
|
||||||
bin_list = frappe.db.sql("select * from tabBin where item_code=%s",
|
|
||||||
self.item_code, as_dict=1)
|
|
||||||
for bin in bin_list:
|
|
||||||
if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \
|
|
||||||
or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(self.stock_uom):
|
|
||||||
matched = False
|
|
||||||
break
|
|
||||||
|
|
||||||
if matched and bin_list:
|
|
||||||
frappe.db.sql("""update tabBin set stock_uom=%s where item_code=%s""",
|
|
||||||
(self.stock_uom, self.name))
|
|
||||||
|
|
||||||
if not matched:
|
|
||||||
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):
|
def update_template_tables(self):
|
||||||
template = frappe.get_doc("Item", self.variant_of)
|
template = frappe.get_doc("Item", self.variant_of)
|
||||||
|
|
||||||
@ -345,6 +316,17 @@ class Item(WebsiteGenerator):
|
|||||||
if stock_in:
|
if stock_in:
|
||||||
frappe.throw(_("Item Template cannot have stock or Open Sales/Purchase/Production Orders."), ItemTemplateCannotHaveStock)
|
frappe.throw(_("Item Template cannot have stock or Open Sales/Purchase/Production Orders."), ItemTemplateCannotHaveStock)
|
||||||
|
|
||||||
|
def validate_uom(self):
|
||||||
|
if not self.get("__islocal"):
|
||||||
|
check_stock_uom_with_bin(self.name, self.stock_uom)
|
||||||
|
if self.has_variants:
|
||||||
|
for d in frappe.db.get_all("Item", filters= {"variant_of": self.name}):
|
||||||
|
check_stock_uom_with_bin(d.name, self.stock_uom)
|
||||||
|
if self.variant_of:
|
||||||
|
template_uom = frappe.db.get_value("Item", self.variant_of, "stock_uom")
|
||||||
|
if template_uom != self.stock_uom:
|
||||||
|
frappe.throw(_("Default Unit of Measure for Variant must be same as Template"))
|
||||||
|
|
||||||
def validate_end_of_life(item_code, end_of_life=None, verbose=1):
|
def validate_end_of_life(item_code, end_of_life=None, verbose=1):
|
||||||
if not end_of_life:
|
if not end_of_life:
|
||||||
end_of_life = frappe.db.get_value("Item", item_code, "end_of_life")
|
end_of_life = frappe.db.get_value("Item", item_code, "end_of_life")
|
||||||
@ -449,3 +431,30 @@ def invalidate_cache_for_item(doc):
|
|||||||
|
|
||||||
if doc.get("old_item_group") and doc.get("old_item_group") != doc.item_group:
|
if doc.get("old_item_group") and doc.get("old_item_group") != doc.item_group:
|
||||||
invalidate_cache_for(doc, doc.old_item_group)
|
invalidate_cache_for(doc, doc.old_item_group)
|
||||||
|
|
||||||
|
def check_stock_uom_with_bin(item, stock_uom):
|
||||||
|
if stock_uom == frappe.db.get_value("Item", item, "stock_uom"):
|
||||||
|
return
|
||||||
|
|
||||||
|
matched=True
|
||||||
|
ref_uom = frappe.db.get_value("Stock Ledger Entry",
|
||||||
|
{"item_code": item}, "stock_uom")
|
||||||
|
|
||||||
|
if ref_uom:
|
||||||
|
if cstr(ref_uom) != cstr(stock_uom):
|
||||||
|
matched = False
|
||||||
|
else:
|
||||||
|
bin_list = frappe.db.sql("select * from tabBin where item_code=%s", item, as_dict=1)
|
||||||
|
for bin in bin_list:
|
||||||
|
if (bin.reserved_qty > 0 or bin.ordered_qty > 0 or bin.indented_qty > 0 \
|
||||||
|
or bin.planned_qty > 0) and cstr(bin.stock_uom) != cstr(stock_uom):
|
||||||
|
matched = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if matched and bin_list:
|
||||||
|
frappe.db.sql("""update tabBin set stock_uom=%s where item_code=%s""", (stock_uom, item))
|
||||||
|
|
||||||
|
if not matched:
|
||||||
|
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(item))
|
||||||
|
@ -10,6 +10,28 @@ from frappe import _
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class StockUOMReplaceUtility(Document):
|
class StockUOMReplaceUtility(Document):
|
||||||
|
|
||||||
|
# Update Stock UOM
|
||||||
|
def update_stock_uom(self):
|
||||||
|
self.validate_item()
|
||||||
|
self.validate_mandatory()
|
||||||
|
self.validate_uom_integer_type()
|
||||||
|
|
||||||
|
update_stock_ledger_entry(self.item_code, self.new_stock_uom, self.conversion_factor)
|
||||||
|
update_bin(self.item_code, self.new_stock_uom, self.conversion_factor)
|
||||||
|
update_item_master(self.item_code, self.new_stock_uom, self.conversion_factor)
|
||||||
|
|
||||||
|
#if item is template change UOM for all associated variants
|
||||||
|
if frappe.db.get_value("Item", self.item_code, "has_variants"):
|
||||||
|
for d in frappe.db.get_all("Item", filters= {"variant_of": self.item_code}):
|
||||||
|
update_stock_ledger_entry(d.name, self.new_stock_uom, self.conversion_factor)
|
||||||
|
update_bin(d.name, self.new_stock_uom, self.conversion_factor)
|
||||||
|
update_item_master(d.name, self.new_stock_uom, self.conversion_factor)
|
||||||
|
|
||||||
|
def validate_item(self):
|
||||||
|
if frappe.db.get_value("Item", self.item_code, "variant_of"):
|
||||||
|
frappe.throw(_("You cannot change default UOM of Variant. To change default UOM for Variant change default UOM of the Template"))
|
||||||
|
|
||||||
def validate_mandatory(self):
|
def validate_mandatory(self):
|
||||||
if not cstr(self.item_code):
|
if not cstr(self.item_code):
|
||||||
frappe.throw(_("Item is required"))
|
frappe.throw(_("Item is required"))
|
||||||
@ -28,71 +50,6 @@ class StockUOMReplaceUtility(Document):
|
|||||||
if cstr(self.new_stock_uom) == cstr(stock_uom):
|
if cstr(self.new_stock_uom) == cstr(stock_uom):
|
||||||
frappe.throw(_("Item is updated"))
|
frappe.throw(_("Item is updated"))
|
||||||
|
|
||||||
def update_item_master(self):
|
|
||||||
item_doc = frappe.get_doc("Item", self.item_code)
|
|
||||||
item_doc.stock_uom = self.new_stock_uom
|
|
||||||
item_doc.save()
|
|
||||||
|
|
||||||
frappe.msgprint(_("Stock UOM updated for Item {0}").format(self.item_code))
|
|
||||||
|
|
||||||
def update_bin(self):
|
|
||||||
# update bin
|
|
||||||
if flt(self.conversion_factor) != flt(1):
|
|
||||||
frappe.db.sql("""update `tabBin`
|
|
||||||
set stock_uom = %s,
|
|
||||||
indented_qty = ifnull(indented_qty,0) * %s,
|
|
||||||
ordered_qty = ifnull(ordered_qty,0) * %s,
|
|
||||||
reserved_qty = ifnull(reserved_qty,0) * %s,
|
|
||||||
planned_qty = ifnull(planned_qty,0) * %s,
|
|
||||||
projected_qty = actual_qty + ordered_qty + indented_qty +
|
|
||||||
planned_qty - reserved_qty
|
|
||||||
where item_code = %s""", (self.new_stock_uom, self.conversion_factor,
|
|
||||||
self.conversion_factor, self.conversion_factor,
|
|
||||||
self.conversion_factor, self.item_code))
|
|
||||||
else:
|
|
||||||
frappe.db.sql("update `tabBin` set stock_uom = %s where item_code = %s",
|
|
||||||
(self.new_stock_uom, self.item_code) )
|
|
||||||
|
|
||||||
# acknowledge user
|
|
||||||
frappe.msgprint(_("Stock balances updated"))
|
|
||||||
|
|
||||||
def update_stock_ledger_entry(self):
|
|
||||||
# update stock ledger entry
|
|
||||||
from erpnext.stock.stock_ledger import update_entries_after
|
|
||||||
|
|
||||||
if flt(self.conversion_factor) != flt(1):
|
|
||||||
frappe.db.sql("""update `tabStock Ledger Entry`
|
|
||||||
set stock_uom = %s, actual_qty = ifnull(actual_qty,0) * %s
|
|
||||||
where item_code = %s""",
|
|
||||||
(self.new_stock_uom, self.conversion_factor, self.item_code))
|
|
||||||
else:
|
|
||||||
frappe.db.sql("""update `tabStock Ledger Entry` set stock_uom=%s
|
|
||||||
where item_code=%s""", (self.new_stock_uom, self.item_code))
|
|
||||||
|
|
||||||
# acknowledge user
|
|
||||||
frappe.msgprint(_("Stock Ledger entries balances updated"))
|
|
||||||
|
|
||||||
# update item valuation
|
|
||||||
if flt(self.conversion_factor) != flt(1):
|
|
||||||
wh = frappe.db.sql("select name from `tabWarehouse`")
|
|
||||||
for w in wh:
|
|
||||||
update_entries_after({"item_code": self.item_code, "warehouse": w[0]})
|
|
||||||
|
|
||||||
# acknowledge user
|
|
||||||
frappe.msgprint(_("Item valuation updated"))
|
|
||||||
|
|
||||||
# Update Stock UOM
|
|
||||||
def update_stock_uom(self):
|
|
||||||
self.validate_mandatory()
|
|
||||||
self.validate_uom_integer_type()
|
|
||||||
|
|
||||||
self.update_stock_ledger_entry()
|
|
||||||
|
|
||||||
self.update_bin()
|
|
||||||
|
|
||||||
self.update_item_master()
|
|
||||||
|
|
||||||
|
|
||||||
def validate_uom_integer_type(self):
|
def validate_uom_integer_type(self):
|
||||||
current_is_integer = frappe.db.get_value("UOM", self.current_stock_uom, "must_be_whole_number")
|
current_is_integer = frappe.db.get_value("UOM", self.current_stock_uom, "must_be_whole_number")
|
||||||
new_is_integer = frappe.db.get_value("UOM", self.new_stock_uom, "must_be_whole_number")
|
new_is_integer = frappe.db.get_value("UOM", self.new_stock_uom, "must_be_whole_number")
|
||||||
@ -103,6 +60,53 @@ class StockUOMReplaceUtility(Document):
|
|||||||
if current_is_integer and new_is_integer and cint(self.conversion_factor)!=self.conversion_factor:
|
if current_is_integer and new_is_integer and cint(self.conversion_factor)!=self.conversion_factor:
|
||||||
frappe.throw(_("Conversion factor cannot be in fractions"))
|
frappe.throw(_("Conversion factor cannot be in fractions"))
|
||||||
|
|
||||||
|
def update_item_master(item_code, new_stock_uom, conversion_factor):
|
||||||
|
frappe.db.set_value("Item", item_code, "stock_uom", new_stock_uom)
|
||||||
|
frappe.msgprint(_("Stock UOM updated for Item {0}").format(item_code))
|
||||||
|
|
||||||
|
def update_bin(item_code, new_stock_uom, conversion_factor):
|
||||||
|
# update bin
|
||||||
|
if flt(conversion_factor) != flt(1):
|
||||||
|
frappe.db.sql("""update `tabBin`
|
||||||
|
set stock_uom = %s,
|
||||||
|
indented_qty = ifnull(indented_qty,0) * %s,
|
||||||
|
ordered_qty = ifnull(ordered_qty,0) * %s,
|
||||||
|
reserved_qty = ifnull(reserved_qty,0) * %s,
|
||||||
|
planned_qty = ifnull(planned_qty,0) * %s,
|
||||||
|
projected_qty = actual_qty + ordered_qty + indented_qty +
|
||||||
|
planned_qty - reserved_qty
|
||||||
|
where item_code = %s""", (new_stock_uom, conversion_factor,
|
||||||
|
conversion_factor, conversion_factor,
|
||||||
|
conversion_factor, item_code))
|
||||||
|
else:
|
||||||
|
frappe.db.sql("update `tabBin` set stock_uom = %s where item_code = %s",
|
||||||
|
(new_stock_uom, item_code) )
|
||||||
|
|
||||||
|
def update_stock_ledger_entry(item_code, new_stock_uom, conversion_factor):
|
||||||
|
# update stock ledger entry
|
||||||
|
from erpnext.stock.stock_ledger import update_entries_after
|
||||||
|
|
||||||
|
if flt(conversion_factor) != flt(1):
|
||||||
|
frappe.db.sql("""update `tabStock Ledger Entry`
|
||||||
|
set stock_uom = %s, actual_qty = ifnull(actual_qty,0) * %s
|
||||||
|
where item_code = %s""",
|
||||||
|
(new_stock_uom, conversion_factor, item_code))
|
||||||
|
else:
|
||||||
|
frappe.db.sql("""update `tabStock Ledger Entry` set stock_uom=%s
|
||||||
|
where item_code=%s""", (new_stock_uom, item_code))
|
||||||
|
|
||||||
|
# acknowledge user
|
||||||
|
frappe.msgprint(_("Stock Ledger entries balances updated"))
|
||||||
|
|
||||||
|
# update item valuation
|
||||||
|
if flt(conversion_factor) != flt(1):
|
||||||
|
wh = frappe.db.sql("select name from `tabWarehouse`")
|
||||||
|
for w in wh:
|
||||||
|
update_entries_after({"item_code": item_code, "warehouse": w[0]})
|
||||||
|
|
||||||
|
# acknowledge user
|
||||||
|
frappe.msgprint(_("Item valuation updated"))
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_stock_uom(item_code):
|
def get_stock_uom(item_code):
|
||||||
return { 'current_stock_uom': cstr(frappe.db.get_value('Item', item_code, 'stock_uom')) }
|
return { 'current_stock_uom': cstr(frappe.db.get_value('Item', item_code, 'stock_uom')) }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user