[fixes] set warehouse group wise reorder level, validate ledger (leaf warehouse) on sle and bin
This commit is contained in:
parent
554f6f70aa
commit
3d6aecd618
@ -71,7 +71,11 @@ $.extend(erpnext.queries, {
|
|||||||
|
|
||||||
warehouse: function(doc) {
|
warehouse: function(doc) {
|
||||||
return {
|
return {
|
||||||
filters: [["Warehouse", "company", "in", ["", cstr(doc.company)]]]
|
filters: [
|
||||||
|
["Warehouse", "company", "in", ["", cstr(doc.company)]],
|
||||||
|
["Warehouse", "is_group", "=", "No"]
|
||||||
|
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
from frappe import _
|
||||||
from frappe.utils import flt, nowdate
|
from frappe.utils import flt, nowdate
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
@ -17,12 +18,20 @@ class Bin(Document):
|
|||||||
self.projected_qty = flt(self.actual_qty) + flt(self.ordered_qty) + \
|
self.projected_qty = flt(self.actual_qty) + flt(self.ordered_qty) + \
|
||||||
flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
|
flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
|
||||||
|
|
||||||
|
self.validate_leaf_warehouse()
|
||||||
|
|
||||||
def validate_mandatory(self):
|
def validate_mandatory(self):
|
||||||
qf = ['actual_qty', 'reserved_qty', 'ordered_qty', 'indented_qty']
|
qf = ['actual_qty', 'reserved_qty', 'ordered_qty', 'indented_qty']
|
||||||
for f in qf:
|
for f in qf:
|
||||||
if (not getattr(self, f, None)) or (not self.get(f)):
|
if (not getattr(self, f, None)) or (not self.get(f)):
|
||||||
self.set(f, 0.0)
|
self.set(f, 0.0)
|
||||||
|
|
||||||
|
def validate_leaf_warehouse(self):
|
||||||
|
from erpnext.stock.utils import is_leaf_warehouse
|
||||||
|
|
||||||
|
if not is_leaf_warehouse(self.warehouse):
|
||||||
|
frappe.throw(_("Group node warehouse is not allowed to select for transactions"))
|
||||||
|
|
||||||
def update_stock(self, args, allow_negative_stock=False, via_landed_cost_voucher=False):
|
def update_stock(self, args, allow_negative_stock=False, via_landed_cost_voucher=False):
|
||||||
self.update_qty(args)
|
self.update_qty(args)
|
||||||
|
|
||||||
|
@ -161,6 +161,28 @@ $.extend(erpnext.item, {
|
|||||||
return { query: "erpnext.controllers.queries.supplier_query" }
|
return { query: "erpnext.controllers.queries.supplier_query" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frm.fields_dict['default_warehouse'].get_query = function(doc) {
|
||||||
|
return {
|
||||||
|
filters: { "is_group": "No" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frm.fields_dict.reorder_levels.grid.get_field("warehouse_group").get_query = function(doc, cdt, cdn) {
|
||||||
|
return {
|
||||||
|
filters: { "is_group": "Yes" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frm.fields_dict.reorder_levels.grid.get_field("warehouse").get_query = function(doc, cdt, cdn) {
|
||||||
|
var d = locals[cdt][cdn];
|
||||||
|
return {
|
||||||
|
filters: {
|
||||||
|
"is_group": "No",
|
||||||
|
"parent_warehouse": d.warehouse_group
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
make_dashboard: function(frm) {
|
make_dashboard: function(frm) {
|
||||||
|
@ -3,11 +3,39 @@
|
|||||||
"allow_import": 0,
|
"allow_import": 0,
|
||||||
"allow_rename": 0,
|
"allow_rename": 0,
|
||||||
"autoname": "hash",
|
"autoname": "hash",
|
||||||
|
"beta": 0,
|
||||||
"creation": "2013-03-07 11:42:59",
|
"creation": "2013-03-07 11:42:59",
|
||||||
"custom": 0,
|
"custom": 0,
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
|
"document_type": "Setup",
|
||||||
"fields": [
|
"fields": [
|
||||||
|
{
|
||||||
|
"allow_on_submit": 0,
|
||||||
|
"bold": 0,
|
||||||
|
"collapsible": 0,
|
||||||
|
"fieldname": "warehouse_group",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 0,
|
||||||
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
|
"in_filter": 0,
|
||||||
|
"in_list_view": 0,
|
||||||
|
"label": "Warehouse Group",
|
||||||
|
"length": 0,
|
||||||
|
"no_copy": 0,
|
||||||
|
"options": "Warehouse",
|
||||||
|
"permlevel": 0,
|
||||||
|
"precision": "",
|
||||||
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"report_hide": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"search_index": 0,
|
||||||
|
"set_only_once": 0,
|
||||||
|
"unique": 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"allow_on_submit": 0,
|
"allow_on_submit": 0,
|
||||||
"bold": 0,
|
"bold": 0,
|
||||||
@ -16,6 +44,7 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Warehouse",
|
"label": "Warehouse",
|
||||||
@ -24,6 +53,7 @@
|
|||||||
"options": "Warehouse",
|
"options": "Warehouse",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
@ -39,6 +69,7 @@
|
|||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Re-order Level",
|
"label": "Re-order Level",
|
||||||
@ -46,6 +77,7 @@
|
|||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
@ -61,6 +93,7 @@
|
|||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Re-order Qty",
|
"label": "Re-order Qty",
|
||||||
@ -68,6 +101,7 @@
|
|||||||
"no_copy": 0,
|
"no_copy": 0,
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
@ -83,6 +117,7 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
|
"ignore_xss_filter": 0,
|
||||||
"in_filter": 0,
|
"in_filter": 0,
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Material Request Type",
|
"label": "Material Request Type",
|
||||||
@ -91,6 +126,7 @@
|
|||||||
"options": "Purchase\nTransfer",
|
"options": "Purchase\nTransfer",
|
||||||
"permlevel": 0,
|
"permlevel": 0,
|
||||||
"print_hide": 0,
|
"print_hide": 0,
|
||||||
|
"print_hide_if_no_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"report_hide": 0,
|
"report_hide": 0,
|
||||||
"reqd": 1,
|
"reqd": 1,
|
||||||
@ -102,18 +138,21 @@
|
|||||||
"hide_heading": 0,
|
"hide_heading": 0,
|
||||||
"hide_toolbar": 0,
|
"hide_toolbar": 0,
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
|
"image_view": 0,
|
||||||
"in_create": 1,
|
"in_create": 1,
|
||||||
"in_dialog": 0,
|
"in_dialog": 0,
|
||||||
"is_submittable": 0,
|
"is_submittable": 0,
|
||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2015-11-16 06:29:48.492627",
|
"modified": "2016-06-20 15:52:01.978593",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Stock",
|
"module": "Stock",
|
||||||
"name": "Item Reorder",
|
"name": "Item Reorder",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"permissions": [],
|
"permissions": [],
|
||||||
|
"quick_entry": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"read_only_onload": 0
|
"read_only_onload": 0,
|
||||||
|
"track_seen": 0
|
||||||
}
|
}
|
@ -25,6 +25,7 @@ class StockLedgerEntry(Document):
|
|||||||
validate_warehouse_company(self.warehouse, self.company)
|
validate_warehouse_company(self.warehouse, self.company)
|
||||||
self.scrub_posting_time()
|
self.scrub_posting_time()
|
||||||
self.validate_and_set_fiscal_year()
|
self.validate_and_set_fiscal_year()
|
||||||
|
self.validate_leaf_warehouse()
|
||||||
|
|
||||||
from erpnext.accounts.utils import validate_fiscal_year
|
from erpnext.accounts.utils import validate_fiscal_year
|
||||||
validate_fiscal_year(self.posting_date, self.fiscal_year, self.meta.get_label("posting_date"), self)
|
validate_fiscal_year(self.posting_date, self.fiscal_year, self.meta.get_label("posting_date"), self)
|
||||||
@ -117,6 +118,11 @@ class StockLedgerEntry(Document):
|
|||||||
if not self.fiscal_year:
|
if not self.fiscal_year:
|
||||||
self.fiscal_year = get_fiscal_year(self.posting_date, company=self.company)[0]
|
self.fiscal_year = get_fiscal_year(self.posting_date, company=self.company)[0]
|
||||||
|
|
||||||
|
def validate_leaf_warehouse(self):
|
||||||
|
from erpnext.stock.utils import is_leaf_warehouse
|
||||||
|
|
||||||
|
if not is_leaf_warehouse(self.warehouse):
|
||||||
|
frappe.throw(_("Group node warehouse is not allowed to select for transactions"))
|
||||||
|
|
||||||
def on_doctype_update():
|
def on_doctype_update():
|
||||||
if not frappe.db.sql("""show index from `tabStock Ledger Entry`
|
if not frappe.db.sql("""show index from `tabStock Ledger Entry`
|
||||||
|
@ -198,9 +198,15 @@ def add_node():
|
|||||||
name_field = ctype.lower().replace(' ', '_') + '_name'
|
name_field = ctype.lower().replace(' ', '_') + '_name'
|
||||||
|
|
||||||
doc = frappe.new_doc(ctype)
|
doc = frappe.new_doc(ctype)
|
||||||
|
|
||||||
|
parent = frappe.form_dict['parent']
|
||||||
|
|
||||||
|
if cint(frappe.form_dict['is_root']):
|
||||||
|
parent = None
|
||||||
|
|
||||||
doc.update({
|
doc.update({
|
||||||
name_field: frappe.form_dict['name_field'],
|
name_field: frappe.form_dict['name_field'],
|
||||||
parent_field: frappe.form_dict['parent'],
|
parent_field: parent,
|
||||||
"is_group": frappe.form_dict['is_group']
|
"is_group": frappe.form_dict['is_group']
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ def _reorder_item():
|
|||||||
|
|
||||||
item_warehouse_projected_qty = get_item_warehouse_projected_qty(items_to_consider)
|
item_warehouse_projected_qty = get_item_warehouse_projected_qty(items_to_consider)
|
||||||
|
|
||||||
def add_to_material_request(item_code, warehouse, reorder_level, reorder_qty, material_request_type):
|
def add_to_material_request(item_code, warehouse, reorder_level, reorder_qty, material_request_type, warehouse_group=None):
|
||||||
if warehouse not in warehouse_company:
|
if warehouse not in warehouse_company:
|
||||||
# a disabled warehouse
|
# a disabled warehouse
|
||||||
return
|
return
|
||||||
@ -46,6 +46,9 @@ def _reorder_item():
|
|||||||
reorder_qty = flt(reorder_qty)
|
reorder_qty = flt(reorder_qty)
|
||||||
|
|
||||||
# projected_qty will be 0 if Bin does not exist
|
# projected_qty will be 0 if Bin does not exist
|
||||||
|
if warehouse_group:
|
||||||
|
projected_qty = flt(item_warehouse_projected_qty.get(item_code, {}).get(warehouse_group))
|
||||||
|
else:
|
||||||
projected_qty = flt(item_warehouse_projected_qty.get(item_code, {}).get(warehouse))
|
projected_qty = flt(item_warehouse_projected_qty.get(item_code, {}).get(warehouse))
|
||||||
|
|
||||||
if (reorder_level or reorder_qty) and projected_qty < reorder_level:
|
if (reorder_level or reorder_qty) and projected_qty < reorder_level:
|
||||||
@ -70,7 +73,7 @@ def _reorder_item():
|
|||||||
if item.get("reorder_levels"):
|
if item.get("reorder_levels"):
|
||||||
for d in item.get("reorder_levels"):
|
for d in item.get("reorder_levels"):
|
||||||
add_to_material_request(item_code, d.warehouse, d.warehouse_reorder_level,
|
add_to_material_request(item_code, d.warehouse, d.warehouse_reorder_level,
|
||||||
d.warehouse_reorder_qty, d.material_request_type)
|
d.warehouse_reorder_qty, d.material_request_type, warehouse_group=d.warehouse_group)
|
||||||
|
|
||||||
if material_requests:
|
if material_requests:
|
||||||
return create_material_request(material_requests)
|
return create_material_request(material_requests)
|
||||||
@ -85,6 +88,14 @@ def get_item_warehouse_projected_qty(items_to_consider):
|
|||||||
|
|
||||||
item_warehouse_projected_qty.setdefault(item_code, {})[warehouse] = flt(projected_qty)
|
item_warehouse_projected_qty.setdefault(item_code, {})[warehouse] = flt(projected_qty)
|
||||||
|
|
||||||
|
warehouse_doc = frappe.get_doc("Warehouse", warehouse)
|
||||||
|
|
||||||
|
if warehouse_doc.parent_warehouse:
|
||||||
|
if not item_warehouse_projected_qty.get(item_code, {}).get(warehouse_doc.parent_warehouse):
|
||||||
|
item_warehouse_projected_qty.setdefault(item_code, {})[warehouse_doc.parent_warehouse] = flt(projected_qty)
|
||||||
|
else:
|
||||||
|
item_warehouse_projected_qty[item_code][warehouse_doc.parent_warehouse] += flt(projected_qty)
|
||||||
|
|
||||||
return item_warehouse_projected_qty
|
return item_warehouse_projected_qty
|
||||||
|
|
||||||
def create_material_request(material_requests):
|
def create_material_request(material_requests):
|
||||||
|
@ -187,3 +187,9 @@ def validate_warehouse_company(warehouse, company):
|
|||||||
if warehouse_company and warehouse_company != company:
|
if warehouse_company and warehouse_company != company:
|
||||||
frappe.throw(_("Warehouse {0} does not belong to company {1}").format(warehouse, company),
|
frappe.throw(_("Warehouse {0} does not belong to company {1}").format(warehouse, company),
|
||||||
InvalidWarehouseCompany)
|
InvalidWarehouseCompany)
|
||||||
|
|
||||||
|
def is_leaf_warehouse(warehouse):
|
||||||
|
if frappe.db.get_value("Warehouse", warehouse, "is_group") == "No":
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user