Merge branch 'master' of github.com:webnotes/erpnext

This commit is contained in:
Rushabh Mehta
2013-01-17 18:23:07 +05:30
14 changed files with 268 additions and 128 deletions

View File

@@ -2,9 +2,9 @@
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-12-20 18:14:55",
"creation": "2013-01-16 14:48:56",
"modified_by": "Administrator",
"modified": "2012-12-24 19:37:34"
"modified": "2013-01-17 11:21:46"
},
{
"istable": 1,

View File

@@ -16,7 +16,7 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import cstr, flt, nowdate, get_defaults
from webnotes.utils import cstr, flt, cint, nowdate, add_days
from webnotes.model.doc import addchild, Document
from webnotes.model.wrapper import getlist
from webnotes.model.code import get_obj
@@ -210,7 +210,7 @@ class DocType:
"wip_warehouse" : "",
"fg_warehouse" : "",
"status" : "Draft",
"fiscal_year" : get_defaults()["fiscal_year"]
"fiscal_year" : webnotes.conn.get_default("fiscal_year")
}
return bom_dict, item_dict
@@ -239,18 +239,22 @@ class DocType:
return self.get_csv()
def get_raw_materials(self, bom_dict):
""" Get raw materials considering sub-assembly items """
""" Get raw materials considering sub-assembly items
{
"item_code": [qty_required, description, stock_uom]
}
"""
for bom in bom_dict:
if self.doc.use_multi_level_bom:
# get all raw materials with sub assembly childs
fl_bom_items = sql("""
select
item_code,ifnull(sum(qty_consumed_per_unit),0)*%s as qty,
description, stock_uom
description, stock_uom, min_order_qty
from
(
select distinct fb.name, fb.description, fb.item_code,
fb.qty_consumed_per_unit, fb.stock_uom
fb.qty_consumed_per_unit, fb.stock_uom, it.min_order_qty
from `tabBOM Explosion Item` fb,`tabItem` it
where it.name = fb.item_code
and ifnull(it.is_pro_applicable, 'No') = 'No'
@@ -263,18 +267,20 @@ class DocType:
# Get all raw materials considering SA items as raw materials,
# so no childs of SA items
fl_bom_items = sql("""
select item_code, ifnull(sum(qty_consumed_per_unit), 0) * '%s',
description, stock_uom
from `tabBOM Item`
where parent = '%s' and docstatus < 2
select bom_item.item_code,
ifnull(sum(bom_item.qty_consumed_per_unit), 0) * %s,
bom_item.description, bom_item.stock_uom, item.min_order_qty
from `tabBOM Item` bom_item, tabItem item
where bom_item.parent = %s and bom_item.docstatus < 2
and bom_item.item_code = item.name
group by item_code
""" % (flt(bom_dict[bom]), bom))
""", (flt(bom_dict[bom]), bom))
self.make_items_dict(fl_bom_items)
def make_items_dict(self, item_list):
for i in item_list:
self.item_dict[i[0]] = [(flt(self.item_dict.get(i[0], [0])[0]) + flt(i[1])), i[2], i[3]]
self.item_dict[i[0]] = [(flt(self.item_dict.get(i[0], [0])[0]) + flt(i[1])),
i[2], i[3], i[4]]
def get_csv(self):
@@ -291,4 +297,85 @@ class DocType:
if item_qty:
item_list.append(['', '', '', '', 'Total', i_qty, o_qty, a_qty])
return item_list
return item_list
def raise_purchase_request(self):
"""
Raise Purchase Request if projected qty is less than qty required
Requested qty should be shortage qty considering minimum order qty
"""
if not self.doc.purchase_request_for_warehouse:
webnotes.msgprint("Please enter Warehouse for which Purchase Request will be raised",
raise_exception=1)
bom_dict = self.get_distinct_items_and_boms()[0]
self.get_raw_materials(bom_dict)
item_projected_qty = self.get_projected_qty()
from accounts.utils import get_fiscal_year
fiscal_year = get_fiscal_year(nowdate())[0]
items_to_be_requested = webnotes._dict()
for item in self.item_dict:
if flt(self.item_dict[item][0]) > item_projected_qty[item]:
# shortage
requested_qty = flt(self.item_dict[item][0]) - item_projected_qty[item]
# comsider minimum order qty
requested_qty = requested_qty > flt(self.item_dict[item][3]) and \
requested_qty or flt(self.item_dict[item][3])
items_to_be_requested[item] = requested_qty
self.insert_purchase_request(items_to_be_requested, fiscal_year)
def get_projected_qty(self):
items = self.item_dict.keys()
item_projected_qty = webnotes.conn.sql("""select item_code, sum(projected_qty)
from `tabBin` where item_code in (%s) group by item_code""" %
(", ".join(["%s"]*len(items)),), tuple(items))
return dict(item_projected_qty)
def insert_purchase_request(self, items_to_be_requested, fiscal_year):
purchase_request_list = []
if items_to_be_requested:
for item in items_to_be_requested:
item_wrapper = webnotes.model_wrapper("Item", item)
pr_doclist = [
{
"doctype": "Purchase Request",
"__islocal": 1,
"naming_series": "IDT",
"transaction_date": nowdate(),
"status": "Draft",
"company": self.doc.company,
"fiscal_year": fiscal_year,
"requested_by": webnotes.session.user,
"remark": "Automatically raised from Production Planning Tool"
},
{
"doctype": "Purchase Request Item",
"__islocal": 1,
"parentfield": "indent_details",
"item_code": item,
"item_name": item_wrapper.doc.item_name,
"description": item_wrapper.doc.description,
"uom": item_wrapper.doc.stock_uom,
"item_group": item_wrapper.doc.item_group,
"brand": item_wrapper.doc.brand,
"qty": items_to_be_requested[item],
"schedule_date": add_days(nowdate(), cint(item_wrapper.doc.lead_time_days)),
"warehouse": self.doc.purchase_request_for_warehouse
}
]
pr_wrapper = webnotes.model_wrapper(pr_doclist)
pr_wrapper.ignore_permissions = 1
pr_wrapper.submit()
purchase_request_list.append(pr_wrapper.doc.name)
if purchase_request_list:
pur_req = ["""<a href="#Form/Purchase Request/%s" target="_blank">%s</a>""" % \
(p, p) for p in purchase_request_list]
webnotes.msgprint("Following Purchase Request created successfully: \n%s" %
"\n".join(pur_req))
else:
webnotes.msgprint("Nothing to request")

View File

@@ -2,9 +2,9 @@
{
"owner": "jai@webnotestech.com",
"docstatus": 0,
"creation": "2012-12-14 10:15:16",
"creation": "2013-01-16 14:48:56",
"modified_by": "Administrator",
"modified": "2012-12-14 11:37:40"
"modified": "2013-01-17 11:39:55"
},
{
"read_only": 1,
@@ -28,8 +28,10 @@
"parent": "Production Planning Tool",
"read": 1,
"create": 1,
"submit": 0,
"doctype": "DocPerm",
"write": 1,
"report": 0,
"parenttype": "DocType",
"permlevel": 0,
"parentfield": "permissions"
@@ -68,9 +70,9 @@
{
"doctype": "DocField",
"label": "Company",
"reqd": 1,
"fieldname": "company",
"fieldtype": "Link",
"reqd": 1,
"options": "Company"
},
{
@@ -154,10 +156,19 @@
"fieldtype": "Section Break",
"options": "Simple"
},
{
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
"default": "1",
"doctype": "DocField",
"label": "Use Multi-Level BOM",
"reqd": 0,
"fieldname": "use_multi_level_bom",
"fieldtype": "Check"
},
{
"doctype": "DocField",
"width": "50%",
"fieldname": "column_break5",
"fieldname": "cb5",
"fieldtype": "Column Break"
},
{
@@ -170,18 +181,9 @@
},
{
"doctype": "DocField",
"width": "50%",
"fieldname": "column_break6",
"fieldtype": "Column Break"
},
{
"description": "If checked, BOM for sub-assembly items will be considered for getting raw materials. Otherwise, all sub-assembly items will be treated as a raw material.",
"default": "1",
"doctype": "DocField",
"label": "Use Multi-Level BOM",
"fieldname": "use_multi_level_bom",
"fieldtype": "Check",
"reqd": 0
"fieldname": "sb5",
"fieldtype": "Section Break",
"options": "Simple"
},
{
"description": "Download a report containing all raw materials with their latest inventory status",
@@ -191,8 +193,25 @@
"fieldtype": "Button"
},
{
"role": "System Manager",
"doctype": "DocPerm"
"doctype": "DocField",
"width": "50%",
"fieldname": "column_break6",
"fieldtype": "Column Break"
},
{
"doctype": "DocField",
"label": "Purchase Request For Warehouse",
"fieldname": "purchase_request_for_warehouse",
"fieldtype": "Link",
"options": "Warehouse"
},
{
"description": "Items to be requested which are \"Out of Stock\" considering all warehouses based on projected qty and minimum order qty",
"doctype": "DocField",
"label": "Raise Purchase Request",
"fieldname": "raise_purchase_request",
"fieldtype": "Button",
"options": "raise_purchase_request"
},
{
"role": "Manufacturing User",