fixes related to Material Request; added button to make Stock Entry of type Material Transfer; calculate ordered_qty and per_ordered in Material Request using observer pattern when Stock Entry against it is submitted or cancelled
This commit is contained in:
parent
7ce7d7cad4
commit
cf05580f8e
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"creation": "2011-05-20 10:07:55",
|
"creation": "2011-05-20 10:07:55",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-02-18 13:41:21",
|
"modified": "2013-02-20 18:20:27",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -40,6 +40,13 @@
|
|||||||
"match_id": 0,
|
"match_id": 0,
|
||||||
"to_field": "transaction_date"
|
"to_field": "transaction_date"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "eval:\"Purchase\"",
|
||||||
|
"map": "Yes",
|
||||||
|
"match_id": 0,
|
||||||
|
"to_field": "material_request_type"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checking_operator": "=",
|
"checking_operator": "=",
|
||||||
"doctype": "Field Mapper Detail",
|
"doctype": "Field Mapper Detail",
|
||||||
|
@ -109,7 +109,11 @@ cur_frm.fields_dict['po_details'].grid.get_field('project_name').get_query = fun
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.fields_dict['indent_no'].get_query = function(doc) {
|
cur_frm.fields_dict['indent_no'].get_query = function(doc) {
|
||||||
return 'SELECT DISTINCT `tabMaterial Request`.`name` FROM `tabMaterial Request` WHERE `tabMaterial Request`.company = "' + doc.company + '" and `tabMaterial Request`.`docstatus` = 1 and `tabMaterial Request`.`status` != "Stopped" and ifnull(`tabMaterial Request`.`per_ordered`,0) < 99.99 and `tabMaterial Request`.%(key)s LIKE "%s" ORDER BY `tabMaterial Request`.`name` DESC LIMIT 50';
|
return 'SELECT DISTINCT `name` FROM `tabMaterial Request` \
|
||||||
|
WHERE material_request_type="Purchase" and company = "' + doc.company
|
||||||
|
+ '" and `docstatus` = 1 and `status` != "Stopped" \
|
||||||
|
and ifnull(`per_ordered`,0) < 99.99 and %(key)s LIKE "%s" \
|
||||||
|
ORDER BY `name` DESC LIMIT 50';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,7 +261,6 @@ class DocType(BuyingController):
|
|||||||
|
|
||||||
self.delete_irrelevant_raw_material()
|
self.delete_irrelevant_raw_material()
|
||||||
#---------------calculate amt in Purchase Order Item Supplied-------------
|
#---------------calculate amt in Purchase Order Item Supplied-------------
|
||||||
self.calculate_amount(d)
|
|
||||||
|
|
||||||
def add_bom(self, d):
|
def add_bom(self, d):
|
||||||
#----- fetching default bom from Bill of Materials instead of Item Master --
|
#----- fetching default bom from Bill of Materials instead of Item Master --
|
||||||
@ -314,15 +313,6 @@ class DocType(BuyingController):
|
|||||||
d.parent = 'old_par:'+self.doc.name
|
d.parent = 'old_par:'+self.doc.name
|
||||||
d.save()
|
d.save()
|
||||||
|
|
||||||
def calculate_amount(self, d):
|
|
||||||
amt = 0
|
|
||||||
for i in getlist(self.doclist,'po_raw_material_details'):
|
|
||||||
|
|
||||||
if(i.reference_name == d.name):
|
|
||||||
i.amount = flt(i.required_qty)* flt(i.rate)
|
|
||||||
amt += i.amount
|
|
||||||
d.rm_supp_cost = amt
|
|
||||||
|
|
||||||
# On Update
|
# On Update
|
||||||
# ----------------------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------------------
|
||||||
def on_update(self):
|
def on_update(self):
|
||||||
|
@ -88,13 +88,11 @@ cur_frm.fields_dict['quotation_items'].grid.get_field('project_name').get_query
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.fields_dict['indent_no'].get_query = function(doc) {
|
cur_frm.fields_dict['indent_no'].get_query = function(doc) {
|
||||||
return "select distinct `tabMaterial Request`.`name` from `tabMaterial Request` \
|
return "select distinct `name` from `tabMaterial Request` \
|
||||||
where `tabMaterial Request`.company = \"" + doc.company +
|
where material_request_type='Purchase' and company = \"" + doc.company +
|
||||||
"\" and `tabMaterial Request`.`docstatus` = 1 and \
|
"\" and `docstatus` = 1 and `status` != \"Stopped\" and \
|
||||||
`tabMaterial Request`.`status` != \"Stopped\" and \
|
ifnull(`per_ordered`,0) < 99.99 and \
|
||||||
ifnull(`tabMaterial Request`.`per_ordered`,0) < 99.99 and \
|
%(key)s LIKE \"%s\" order by `name` desc limit 50";
|
||||||
`tabMaterial Request`.%(key)s LIKE \"%s\" \
|
|
||||||
order by `tabMaterial Request`.`name` desc limit 50";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.supplier_address = function(doc, dt, dn) {
|
cur_frm.cscript.supplier_address = function(doc, dt, dn) {
|
||||||
|
@ -350,7 +350,8 @@ class DocType:
|
|||||||
"company": self.doc.company,
|
"company": self.doc.company,
|
||||||
"fiscal_year": fiscal_year,
|
"fiscal_year": fiscal_year,
|
||||||
"requested_by": webnotes.session.user,
|
"requested_by": webnotes.session.user,
|
||||||
"remark": "Automatically raised from Production Planning Tool"
|
"remark": "Automatically raised from Production Planning Tool",
|
||||||
|
"material_request_type": "Purchase"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "Material Request Item",
|
"doctype": "Material Request Item",
|
||||||
|
@ -17,5 +17,7 @@
|
|||||||
observer_map = {
|
observer_map = {
|
||||||
"*:on_update": "home.update_feed",
|
"*:on_update": "home.update_feed",
|
||||||
"*:on_submit": "home.update_feed",
|
"*:on_submit": "home.update_feed",
|
||||||
|
"Stock Entry:on_submit": "stock.doctype.material_request.material_request.update_completed_qty",
|
||||||
|
"Stock Entry:on_cancel": "stock.doctype.material_request.material_request.update_completed_qty",
|
||||||
# "*:on_update": "webnotes.widgets.moduleview.update_count"
|
# "*:on_update": "webnotes.widgets.moduleview.update_count"
|
||||||
}
|
}
|
@ -117,7 +117,8 @@ data_map = {
|
|||||||
"(ifnull(qty, 0) - ifnull(ordered_qty, 0)) as qty"],
|
"(ifnull(qty, 0) - ifnull(ordered_qty, 0)) as qty"],
|
||||||
"from": "`tabMaterial Request Item` item, `tabMaterial Request` main",
|
"from": "`tabMaterial Request Item` item, `tabMaterial Request` main",
|
||||||
"conditions": ["item.parent = main.name", "main.docstatus=1", "main.status != 'Stopped'",
|
"conditions": ["item.parent = main.name", "main.docstatus=1", "main.status != 'Stopped'",
|
||||||
"ifnull(warehouse, '')!=''", "ifnull(qty, 0) > ifnull(ordered_qty, 0)"],
|
"material_request_type = 'Purchase'", "ifnull(warehouse, '')!=''",
|
||||||
|
"ifnull(qty, 0) > ifnull(ordered_qty, 0)"],
|
||||||
"links": {
|
"links": {
|
||||||
"item_code": ["Item", "name"],
|
"item_code": ["Item", "name"],
|
||||||
"warehouse": ["Warehouse", "name"]
|
"warehouse": ["Warehouse", "name"]
|
||||||
|
@ -0,0 +1,107 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"creation": "2013-02-20 16:54:17",
|
||||||
|
"docstatus": 0,
|
||||||
|
"modified": "2013-02-20 16:54:17",
|
||||||
|
"modified_by": "Administrator",
|
||||||
|
"owner": "Administrator"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Table Mapper Detail",
|
||||||
|
"name": "__common__",
|
||||||
|
"parent": "Material Request-Stock Entry",
|
||||||
|
"parentfield": "table_mapper_details",
|
||||||
|
"parenttype": "DocType Mapper"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"map": "Yes",
|
||||||
|
"name": "__common__",
|
||||||
|
"parent": "Material Request-Stock Entry",
|
||||||
|
"parentfield": "field_mapper_details",
|
||||||
|
"parenttype": "DocType Mapper"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocType Mapper",
|
||||||
|
"from_doctype": "Material Request",
|
||||||
|
"module": "Stock",
|
||||||
|
"name": "__common__",
|
||||||
|
"ref_doc_submitted": 1,
|
||||||
|
"to_doctype": "Stock Entry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocType Mapper",
|
||||||
|
"name": "Material Request-Stock Entry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "eval:\"Material Transfer\"",
|
||||||
|
"match_id": 0,
|
||||||
|
"to_field": "purpose"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checking_operator": "=",
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "company",
|
||||||
|
"match_id": 0,
|
||||||
|
"to_field": "company"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "parent",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "material_request"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "name",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "material_request_item"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "uom",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "stock_uom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "eval:flt(1)",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "conversion_factor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "eval:flt(obj.qty) - flt(obj.ordered_qty)",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "transfer_qty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "eval:flt(obj.qty) - flt(obj.ordered_qty)",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "qty"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Field Mapper Detail",
|
||||||
|
"from_field": "warehouse",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "t_warehouse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Table Mapper Detail",
|
||||||
|
"from_table": "Material Request",
|
||||||
|
"match_id": 0,
|
||||||
|
"to_table": "Stock Entry",
|
||||||
|
"validation_logic": "docstatus = 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "Table Mapper Detail",
|
||||||
|
"from_field": "indent_details",
|
||||||
|
"from_table": "Material Request Item",
|
||||||
|
"match_id": 1,
|
||||||
|
"to_field": "mtn_details",
|
||||||
|
"to_table": "Stock Entry Detail",
|
||||||
|
"validation_logic": "qty > ifnull(ordered_qty,0) and docstatus =1"
|
||||||
|
}
|
||||||
|
]
|
@ -111,12 +111,15 @@ class DocType:
|
|||||||
if item_reorder:
|
if item_reorder:
|
||||||
reorder_level = item_reorder.warehouse_reorder_level
|
reorder_level = item_reorder.warehouse_reorder_level
|
||||||
reorder_qty = item_reorder.warehouse_reorder_qty
|
reorder_qty = item_reorder.warehouse_reorder_qty
|
||||||
|
material_request_type = item_reorder.material_request_type
|
||||||
else:
|
else:
|
||||||
reorder_level, reorder_qty = webnotes.conn.get_value("Item", self.doc.item_code,
|
reorder_level, reorder_qty = webnotes.conn.get_value("Item", self.doc.item_code,
|
||||||
["re_order_level", "re_order_qty"])
|
["re_order_level", "re_order_qty"])
|
||||||
|
material_request_type = "Purchase"
|
||||||
|
|
||||||
if flt(reorder_qty) and flt(self.doc.projected_qty) < flt(reorder_level):
|
if flt(reorder_qty) and flt(self.doc.projected_qty) < flt(reorder_level):
|
||||||
self.create_material_request(doc_type, doc_name, reorder_level, reorder_qty, item_reorder.material_request_type)
|
self.create_material_request(doc_type, doc_name, reorder_level, reorder_qty,
|
||||||
|
material_request_type)
|
||||||
|
|
||||||
def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty, material_request_type):
|
def create_material_request(self, doc_type, doc_name, reorder_level, reorder_qty, material_request_type):
|
||||||
""" Create indent on reaching reorder level """
|
""" Create indent on reaching reorder level """
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-02-18 13:36:21",
|
"creation": "2013-02-20 13:26:14",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-02-18 13:46:29",
|
"modified": "2013-02-20 18:14:06",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -301,6 +301,7 @@
|
|||||||
"options": "UOM"
|
"options": "UOM"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"description": "Auto-raise Material Request if quantity goes below re-order level in a warehouse",
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "reorder_section",
|
"fieldname": "reorder_section",
|
||||||
"fieldtype": "Section Break",
|
"fieldtype": "Section Break",
|
||||||
|
@ -25,9 +25,16 @@ erpnext.buying.MaterialRequestController = erpnext.buying.BuyingController.exten
|
|||||||
this._super();
|
this._super();
|
||||||
|
|
||||||
if(doc.docstatus == 1 && doc.status != 'Stopped'){
|
if(doc.docstatus == 1 && doc.status != 'Stopped'){
|
||||||
cur_frm.add_custom_button("Make Supplier Quotation", cur_frm.cscript.make_supplier_quotation);
|
if(doc.material_request_type === "Purchase")
|
||||||
|
cur_frm.add_custom_button("Make Supplier Quotation", cur_frm.cscript.make_supplier_quotation);
|
||||||
|
|
||||||
|
if(doc.material_request_type === "Transfer" && doc.status === "Submitted")
|
||||||
|
cur_frm.add_custom_button("Transfer Material", cur_frm.cscript.make_stock_entry);
|
||||||
|
|
||||||
if(flt(doc.per_ordered, 2) < 100) {
|
if(flt(doc.per_ordered, 2) < 100) {
|
||||||
cur_frm.add_custom_button('Make Purchase Order', cur_frm.cscript['Make Purchase Order']);
|
if(doc.material_request_type === "Purchase")
|
||||||
|
cur_frm.add_custom_button('Make Purchase Order', cur_frm.cscript['Make Purchase Order']);
|
||||||
|
|
||||||
cur_frm.add_custom_button('Stop Material Request', cur_frm.cscript['Stop Material Request']);
|
cur_frm.add_custom_button('Stop Material Request', cur_frm.cscript['Stop Material Request']);
|
||||||
}
|
}
|
||||||
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
cur_frm.add_custom_button('Send SMS', cur_frm.cscript.send_sms);
|
||||||
@ -85,22 +92,6 @@ cur_frm.cscript.qty = function(doc, cdt, cdn) {
|
|||||||
// On Button Click Functions
|
// On Button Click Functions
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Make Purchase Order
|
|
||||||
cur_frm.cscript['Make Purchase Order'] = function() {
|
|
||||||
var doc = cur_frm.doc;
|
|
||||||
n = wn.model.make_new_doc_and_get_name('Purchase Order');
|
|
||||||
$c('dt_map', args={
|
|
||||||
'docs':wn.model.compress([locals['Purchase Order'][n]]),
|
|
||||||
'from_doctype':doc.doctype,
|
|
||||||
'to_doctype':'Purchase Order',
|
|
||||||
'from_docname':doc.name,
|
|
||||||
'from_to_list':"[['Material Request','Purchase Order'],['Material Request Item','Purchase Order Item']]"
|
|
||||||
}, function(r,rt) {
|
|
||||||
loaddoc('Purchase Order', n);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stop INDENT
|
// Stop INDENT
|
||||||
// ==================================================================================================
|
// ==================================================================================================
|
||||||
cur_frm.cscript['Stop Material Request'] = function() {
|
cur_frm.cscript['Stop Material Request'] = function() {
|
||||||
@ -128,14 +119,14 @@ cur_frm.cscript['Unstop Material Request'] = function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_frm.cscript.make_supplier_quotation = function() {
|
cur_frm.cscript['Make Purchase Order'] = function() {
|
||||||
var new_sq_name = wn.model.make_new_doc_and_get_name("Supplier Quotation");
|
cur_frm.map([["Material Request", "Purchase Order"], ["Material Request Item", "Purchase Order Item"]]);
|
||||||
$c("dt_map", {
|
}
|
||||||
"docs": wn.model.compress([locals['Supplier Quotation'][new_sq_name]]),
|
|
||||||
"from_doctype": cur_frm.doc.doctype,
|
cur_frm.cscript.make_supplier_quotation = function() {
|
||||||
"to_doctype": "Supplier Quotation",
|
cur_frm.map([["Material Request", "Supplier Quotation"], ["Material Request Item", "Supplier Quotation Item"]]);
|
||||||
"from_docname": cur_frm.doc.name,
|
}
|
||||||
"from_to_list": JSON.stringify([['Material Request', 'Supplier Quotation'],
|
|
||||||
['Material Request Item', 'Supplier Quotation Item']]),
|
cur_frm.cscript.make_stock_entry = function() {
|
||||||
}, function(r, rt) { loaddoc("Supplier Quotation", new_sq_name) });
|
cur_frm.map([["Material Request", "Stock Entry"], ["Material Request Item", "Stock Entry Detail"]]);
|
||||||
}
|
}
|
@ -118,24 +118,24 @@ class DocType(BuyingController):
|
|||||||
|
|
||||||
|
|
||||||
def update_bin(self, is_submit, is_stopped):
|
def update_bin(self, is_submit, is_stopped):
|
||||||
""" Update Quantity Requested for Purchase in Bin"""
|
""" Update Quantity Requested for Purchase in Bin for Material Request of type 'Purchase'"""
|
||||||
|
if self.doc.material_request_type == "Purchase":
|
||||||
|
for d in getlist(self.doclist, 'indent_details'):
|
||||||
|
if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
|
||||||
|
if not d.warehouse:
|
||||||
|
msgprint("Please Enter Warehouse for Item %s as it is stock item"
|
||||||
|
% cstr(d.item_code), raise_exception=1)
|
||||||
|
|
||||||
for d in getlist(self.doclist, 'indent_details'):
|
qty =flt(d.qty)
|
||||||
if webnotes.conn.get_value("Item", d.item_code, "is_stock_item") == "Yes":
|
if is_stopped:
|
||||||
if not d.warehouse:
|
qty = (d.qty > d.ordered_qty) and flt(flt(d.qty) - flt(d.ordered_qty)) or 0
|
||||||
msgprint("Please Enter Warehouse for Item %s as it is stock item"
|
|
||||||
% cstr(d.item_code), raise_exception=1)
|
|
||||||
|
|
||||||
qty =flt(d.qty)
|
args = {
|
||||||
if is_stopped:
|
"item_code": d.item_code,
|
||||||
qty = (d.qty > d.ordered_qty) and flt(flt(d.qty) - flt(d.ordered_qty)) or 0
|
"indented_qty": (is_submit and 1 or -1) * flt(qty),
|
||||||
|
"posting_date": self.doc.transaction_date
|
||||||
args = {
|
}
|
||||||
"item_code": d.item_code,
|
get_obj('Warehouse', d.warehouse).update_bin(args)
|
||||||
"indented_qty": (is_submit and 1 or -1) * flt(qty),
|
|
||||||
"posting_date": self.doc.transaction_date
|
|
||||||
}
|
|
||||||
get_obj('Warehouse', d.warehouse).update_bin(args)
|
|
||||||
|
|
||||||
def on_submit(self):
|
def on_submit(self):
|
||||||
purchase_controller = webnotes.get_obj("Purchase Common")
|
purchase_controller = webnotes.get_obj("Purchase Common")
|
||||||
@ -169,7 +169,7 @@ class DocType(BuyingController):
|
|||||||
pc_obj = get_obj(dt='Purchase Common')
|
pc_obj = get_obj(dt='Purchase Common')
|
||||||
|
|
||||||
# Step 2:=> Check for stopped status
|
# Step 2:=> Check for stopped status
|
||||||
pc_obj.check_for_stopped_status( self.doc.doctype, self.doc.name)
|
pc_obj.check_for_stopped_status(self.doc.doctype, self.doc.name)
|
||||||
|
|
||||||
# Step 3:=> Check if Purchase Order has been submitted against current Material Request
|
# Step 3:=> Check if Purchase Order has been submitted against current Material Request
|
||||||
pc_obj.check_docstatus(check = 'Next', doctype = 'Purchase Order', docname = self.doc.name, detail_doctype = 'Purchase Order Item')
|
pc_obj.check_docstatus(check = 'Next', doctype = 'Purchase Order', docname = self.doc.name, detail_doctype = 'Purchase Order Item')
|
||||||
@ -178,3 +178,47 @@ class DocType(BuyingController):
|
|||||||
|
|
||||||
# Step 5:=> Set Status
|
# Step 5:=> Set Status
|
||||||
webnotes.conn.set(self.doc,'status','Cancelled')
|
webnotes.conn.set(self.doc,'status','Cancelled')
|
||||||
|
|
||||||
|
def update_completed_qty(self, mr_items=None):
|
||||||
|
if self.doc.material_request_type != "Transfer":
|
||||||
|
return
|
||||||
|
|
||||||
|
item_doclist = self.doclist.get({"parentfield": "indent_details"})
|
||||||
|
|
||||||
|
if not mr_items:
|
||||||
|
mr_items = [d.name for d in item_doclist]
|
||||||
|
|
||||||
|
per_ordered = 0.0
|
||||||
|
for d in item_doclist:
|
||||||
|
if d.name in mr_items:
|
||||||
|
d.ordered_qty = flt(webnotes.conn.sql("""select sum(transfer_qty)
|
||||||
|
from `tabStock Entry Detail` where material_request = %s
|
||||||
|
and material_request_item = %s and docstatus = 1""",
|
||||||
|
(self.doc.name, d.name))[0][0])
|
||||||
|
d.save()
|
||||||
|
|
||||||
|
# note: if qty is 0, its row is still counted in len(item_doclist)
|
||||||
|
# hence adding 1 to per_ordered
|
||||||
|
if (d.ordered_qty > d.qty) or not d.qty:
|
||||||
|
per_ordered += 1.0
|
||||||
|
elif d.qty > 0:
|
||||||
|
per_ordered += flt(d.ordered_qty / flt(d.qty))
|
||||||
|
|
||||||
|
if per_ordered:
|
||||||
|
self.doc.per_ordered = flt((per_ordered / flt(len(item_doclist))) * 100.0, 2)
|
||||||
|
self.doc.save()
|
||||||
|
|
||||||
|
|
||||||
|
def update_completed_qty(controller, caller_method):
|
||||||
|
if controller.doc.doctype == "Stock Entry":
|
||||||
|
material_request_map = {}
|
||||||
|
|
||||||
|
for d in controller.doclist.get({"parentfield": "mtn_details"}):
|
||||||
|
if d.material_request:
|
||||||
|
if d.material_request not in material_request_map:
|
||||||
|
material_request_map[d.material_request] = []
|
||||||
|
material_request_map[d.material_request].append(d.material_request_item)
|
||||||
|
|
||||||
|
for mr_name, mr_items in material_request_map.items():
|
||||||
|
webnotes.get_obj("Material Request", mr_name, with_children=1).update_completed_qty(mr_items)
|
||||||
|
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-02-18 13:50:55",
|
"creation": "2013-02-20 13:25:31",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-02-18 14:41:41",
|
"modified": "2013-02-20 14:10:23",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -43,7 +43,8 @@
|
|||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Material Request Type",
|
"label": "Material Request Type",
|
||||||
"options": "Purchase\nTransfer"
|
"options": "Purchase\nTransfer",
|
||||||
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
@ -252,7 +253,7 @@
|
|||||||
"fieldname": "per_ordered",
|
"fieldname": "per_ordered",
|
||||||
"fieldtype": "Percent",
|
"fieldtype": "Percent",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "% Ordered",
|
"label": "% Completed",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "per_ordered",
|
"oldfieldname": "per_ordered",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
|
@ -1,16 +1,102 @@
|
|||||||
|
# ERPNext - web based ERP (http://erpnext.com)
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import webnotes, unittest
|
||||||
|
|
||||||
|
class TestMaterialRequest(unittest.TestCase):
|
||||||
|
def _test_expected(self, doclist, expected_values):
|
||||||
|
for i, expected in enumerate(expected_values):
|
||||||
|
for fieldname, val in expected.items():
|
||||||
|
self.assertEquals(val, doclist[i].fields.get(fieldname))
|
||||||
|
|
||||||
|
def test_completed_qty_for_purchase(self):
|
||||||
|
# submit material request of type Purchase
|
||||||
|
mr = webnotes.bean(copy=test_records[0])
|
||||||
|
mr.insert()
|
||||||
|
mr.submit()
|
||||||
|
|
||||||
|
# check if per complete is None
|
||||||
|
self._test_expected(mr.doclist, [{"per_ordered": None}, {"ordered_qty": None}, {"ordered_qty": None}])
|
||||||
|
|
||||||
|
# map a purchase order
|
||||||
|
po = webnotes.map_doclist([["Material Request", "Purchase Order"],
|
||||||
|
["Material Request Item", "Purchase Order Item"]], mr.doc.name)
|
||||||
|
po = webnotes.bean(po)
|
||||||
|
po.doc.fields.update({
|
||||||
|
"supplier": "_Test Supplier",
|
||||||
|
"supplier_name": "_Test Supplier",
|
||||||
|
"transaction_date": mr.doc.transaction_date,
|
||||||
|
"fiscal_year": "_Test Fiscal Year 2013",
|
||||||
|
"currency": "INR",
|
||||||
|
"conversion_rate": 1.0,
|
||||||
|
"grand_total_import": 0.0
|
||||||
|
})
|
||||||
|
po.doclist[1].qty = 27.0
|
||||||
|
po.doclist[2].qty = 1.5
|
||||||
|
po.insert()
|
||||||
|
po.submit()
|
||||||
|
|
||||||
|
# check if per complete is as expected
|
||||||
|
mr.load_from_db()
|
||||||
|
self._test_expected(mr.doclist, [{"per_ordered": 50}, {"ordered_qty": 27.0}, {"ordered_qty": 1.5}])
|
||||||
|
|
||||||
|
po.cancel()
|
||||||
|
# check if per complete is as expected
|
||||||
|
mr.load_from_db()
|
||||||
|
self._test_expected(mr.doclist, [{"per_ordered": 0}, {"ordered_qty": 0}, {"ordered_qty": 0}])
|
||||||
|
|
||||||
|
def test_completed_qty_for_transfer(self):
|
||||||
|
# submit material request of type Purchase
|
||||||
|
mr = webnotes.bean(copy=test_records[0])
|
||||||
|
mr.doc.material_request_type = "Transfer"
|
||||||
|
mr.insert()
|
||||||
|
mr.submit()
|
||||||
|
|
||||||
|
# check if per complete is None
|
||||||
|
self._test_expected(mr.doclist, [{"per_ordered": None}, {"ordered_qty": None}, {"ordered_qty": None}])
|
||||||
|
|
||||||
|
# map a stock entry
|
||||||
|
se = webnotes.map_doclist([["Material Request", "Stock Entry"],
|
||||||
|
["Material Request Item", "Stock Entry Detail"]], mr.doc.name)
|
||||||
|
se = webnotes.bean(se)
|
||||||
|
se.doc.fields.update({
|
||||||
|
"posting_date": "2013-03-01",
|
||||||
|
"posting_time": "00:00"
|
||||||
|
})
|
||||||
|
se.doclist[1].fields.update({
|
||||||
|
"qty": 27.0,
|
||||||
|
"transfer_qty": 27.0,
|
||||||
|
"s_warehouse": "_Test Warehouse 1",
|
||||||
|
"incoming_rate": 1.0
|
||||||
|
})
|
||||||
|
se.doclist[2].fields.update({
|
||||||
|
"qty": 1.5,
|
||||||
|
"transfer_qty": 1.5,
|
||||||
|
"s_warehouse": "_Test Warehouse 1",
|
||||||
|
"incoming_rate": 1.0
|
||||||
|
})
|
||||||
|
se.insert()
|
||||||
|
se.submit()
|
||||||
|
|
||||||
|
# check if per complete is as expected
|
||||||
|
mr.load_from_db()
|
||||||
|
self._test_expected(mr.doclist, [{"per_ordered": 50}, {"ordered_qty": 27.0}, {"ordered_qty": 1.5}])
|
||||||
|
|
||||||
test_records = [
|
test_records = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"company": "_Test Company",
|
"company": "_Test Company",
|
||||||
"doctype": "Material Request",
|
"doctype": "Material Request",
|
||||||
"fiscal_year": "_Test Fiscal Year 2013",
|
"fiscal_year": "_Test Fiscal Year 2013",
|
||||||
"transaction_date": "2013-02-18"
|
"transaction_date": "2013-02-18",
|
||||||
|
"material_request_type": "Purchase"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "A 6",
|
"description": "_Test Item Home Desktop 100",
|
||||||
"doctype": "Material Request Item",
|
"doctype": "Material Request Item",
|
||||||
"item_code": "_Test Item Home Desktop 100",
|
"item_code": "_Test Item Home Desktop 100",
|
||||||
"item_name": "A 6",
|
"item_name": "_Test Item Home Desktop 100",
|
||||||
"parentfield": "indent_details",
|
"parentfield": "indent_details",
|
||||||
"qty": 54.0,
|
"qty": 54.0,
|
||||||
"schedule_date": "2013-02-18",
|
"schedule_date": "2013-02-18",
|
||||||
@ -18,10 +104,10 @@ test_records = [
|
|||||||
"warehouse": "_Test Warehouse"
|
"warehouse": "_Test Warehouse"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"description": "Value 3.5",
|
"description": "_Test Item Home Desktop 200",
|
||||||
"doctype": "Material Request Item",
|
"doctype": "Material Request Item",
|
||||||
"item_code": "_Test Item Home Desktop 200",
|
"item_code": "_Test Item Home Desktop 200",
|
||||||
"item_name": "Valve 3.5",
|
"item_name": "_Test Item Home Desktop 200",
|
||||||
"parentfield": "indent_details",
|
"parentfield": "indent_details",
|
||||||
"qty": 3.0,
|
"qty": 3.0,
|
||||||
"schedule_date": "2013-02-19",
|
"schedule_date": "2013-02-19",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-02-04 10:34:46",
|
"creation": "2013-02-20 13:25:31",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-02-18 13:12:44",
|
"modified": "2013-02-20 14:06:58",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -177,7 +177,7 @@
|
|||||||
"doctype": "DocField",
|
"doctype": "DocField",
|
||||||
"fieldname": "ordered_qty",
|
"fieldname": "ordered_qty",
|
||||||
"fieldtype": "Float",
|
"fieldtype": "Float",
|
||||||
"label": "Ordered Qty",
|
"label": "Completed Qty",
|
||||||
"no_copy": 1,
|
"no_copy": 1,
|
||||||
"oldfieldname": "ordered_qty",
|
"oldfieldname": "ordered_qty",
|
||||||
"oldfieldtype": "Currency",
|
"oldfieldtype": "Currency",
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# ERPNext - web based ERP (http://erpnext.com)
|
||||||
|
# For license information, please see license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
import webnotes, unittest
|
import webnotes, unittest
|
||||||
|
|
||||||
class TestStockEntry(unittest.TestCase):
|
class TestStockEntry(unittest.TestCase):
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"creation": "2013-01-14 16:33:34",
|
"creation": "2013-01-29 19:25:45",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"modified": "2013-01-29 16:27:57",
|
"modified": "2013-02-20 16:46:26",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"owner": "Administrator"
|
"owner": "Administrator"
|
||||||
},
|
},
|
||||||
@ -195,5 +195,28 @@
|
|||||||
"options": "BOM",
|
"options": "BOM",
|
||||||
"print_hide": 1,
|
"print_hide": 1,
|
||||||
"read_only": 0
|
"read_only": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Material Request used to make this Stock Entry",
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "material_request",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Material Request",
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Material Request",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"doctype": "DocField",
|
||||||
|
"fieldname": "material_request_item",
|
||||||
|
"fieldtype": "Link",
|
||||||
|
"hidden": 1,
|
||||||
|
"label": "Material Request Item",
|
||||||
|
"no_copy": 1,
|
||||||
|
"options": "Material Request Item",
|
||||||
|
"print_hide": 1,
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
]
|
]
|
Loading…
x
Reference in New Issue
Block a user