sub-contracting rewrite with testcases

This commit is contained in:
Nabin Hait 2013-02-27 18:11:17 +05:30
parent a1d4b78fbe
commit 5418d71fc0
7 changed files with 344 additions and 298 deletions

View File

@ -320,6 +320,7 @@ class DocType(BuyingController):
self.doc.posting_date,'Posting Date')
self.validate_write_off_account()
self.update_raw_material_cost()
def check_prev_docstatus(self):
for d in getlist(self.doclist,'entries'):
@ -494,3 +495,16 @@ class DocType(BuyingController):
def on_update(self):
pass
def update_raw_material_cost(self):
if self.sub_contracted_items:
for d in self.doclist.get({"parentfield": "entries"}):
rm_cost = webnotes.conn.sql(""" select raw_material_cost / quantity
from `tabBOM` where item = %s and is_default = 1 and docstatus = 1
and is_active = 1 """, (d.item_code,))
rm_cost = rm_cost and flt(rm_cost[0][0]) or 0
d.conversion_factor = d.conversion_factor or webnotes.conn.get_value(
"UOM Conversion Detail", {"parent": d.item_code, "uom": d.uom},
"conversion_factor") or 1
d.rm_supp_cost = rm_cost * flt(d.qty) * flt(d.conversion_factor)

View File

@ -1,8 +1,8 @@
[
{
"creation": "2013-01-29 20:53:00",
"creation": "2013-02-11 10:54:51",
"docstatus": 0,
"modified": "2013-02-08 14:06:17",
"modified": "2013-02-27 18:10:04",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -282,6 +282,35 @@
"search_index": 0,
"width": "150px"
},
{
"doctype": "DocField",
"fieldname": "valuation_rate",
"fieldtype": "Currency",
"hidden": 1,
"label": "Valuation Rate",
"no_copy": 1,
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
},
{
"doctype": "DocField",
"fieldname": "conversion_factor",
"fieldtype": "Float",
"label": "Conversion Factor",
"print_hide": 1
},
{
"doctype": "DocField",
"fieldname": "rm_supp_cost",
"fieldtype": "Currency",
"hidden": 1,
"label": "Raw Materials Supplied Cost",
"no_copy": 1,
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
},
{
"allow_on_submit": 1,
"doctype": "DocField",

View File

@ -232,7 +232,7 @@ class BuyingController(AccountsController):
else:
self.doc.grand_total = flt(self.doc.net_total,
self.precision.main.grand_total)
self.doc.grand_total_print = flt(
self.doc.grand_total_import = flt(
self.doc.grand_total / self.doc.conversion_rate,
self.precision.main.grand_total_import)
@ -336,3 +336,25 @@ class BuyingController(AccountsController):
self._precision.tax = self.meta.get_precision_map(parentfield = \
"purchase_tax_details")
return self._precision
@property
def sub_contracted_items(self):
if not hasattr(self, "_sub_contracted_items"):
item_codes = list(set(item.item_code for item in
self.doclist.get({"parentfield": self.fname})))
self._sub_contracted_items = [r[0] for r in webnotes.conn.sql("""select name
from `tabItem` where name in (%s) and is_sub_contracted_item='Yes'""" % \
(", ".join((["%s"]*len(item_codes))),), item_codes)]
return self._sub_contracted_items
@property
def purchase_items(self):
if not hasattr(self, "_purchase_items"):
item_codes = list(set(item.item_code for item in
self.doclist.get({"parentfield": self.fname})))
self._purchase_items = [r[0] for r in webnotes.conn.sql("""select name
from `tabItem` where name in (%s) and is_purchase_item='Yes'""" % \
(", ".join((["%s"]*len(item_codes))),), item_codes)]
return self._purchase_items

View File

@ -18,130 +18,164 @@
from __future__ import unicode_literals
import unittest
import webnotes
import webnotes.model
from webnotes.utils import nowdate, flt
from accounts.utils import get_fiscal_year
from webnotes.model.doclist import DocList
import copy
company = webnotes.conn.get_default("company")
def load_data():
# create default warehouse
if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
webnotes.insert({"doctype": "Warehouse",
"warehouse_name": "Default Warehouse",
"warehouse_type": "Stores"})
# create UOM: Nos.
if not webnotes.conn.exists("UOM", "Nos"):
webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
from webnotes.tests import insert_test_data
# create item groups and items
insert_test_data("Item Group",
sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
insert_test_data("Item")
base_bom_fg = [
{"doctype": "BOM", "item": "Android Jack D", "quantity": 1,
"is_active": "Yes", "is_default": 1, "uom": "Nos"},
{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
"opn_description": "Development", "hour_rate": 10, "time_in_mins": 90},
{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1,
"qty": 2, "rate": 20, "stock_uom": "Nos", "parentfield": "bom_materials"},
{"doctype": "BOM Item", "item_code": "Home Desktop 100", "operation_no": 1,
"qty": 1, "rate": 300, "stock_uom": "Nos", "parentfield": "bom_materials"},
{"doctype": "BOM Item", "item_code": "Nebula 7", "operation_no": 1,
"qty": 5, "stock_uom": "Nos", "parentfield": "bom_materials"},
]
base_bom_child = [
{"doctype": "BOM", "item": "Nebula 7", "quantity": 5,
"is_active": "Yes", "is_default": 1, "uom": "Nos"},
{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
"opn_description": "Development"},
{"doctype": "BOM Item", "item_code": "Android Jack S", "operation_no": 1,
"qty": 10, "stock_uom": "Nos", "parentfield": "bom_materials"}
]
base_bom_grandchild = [
{"doctype": "BOM", "item": "Android Jack S", "quantity": 1,
"is_active": "Yes", "is_default": 1, "uom": "Nos"},
{"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
"opn_description": "Development"},
{"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1,
"qty": 3, "rate": 10, "stock_uom": "Nos", "parentfield": "bom_materials"}
]
class TestPurchaseReceipt(unittest.TestCase):
def setUp(self):
webnotes.conn.begin()
load_data()
def test_bom_validation(self):
# show throw error bacause bom no missing for sub-assembly item
bom_fg = copy.deepcopy(base_bom_fg)
self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
# main item is not a manufacturing item
bom_fg = copy.deepcopy(base_bom_fg)
bom_fg[0]["item"] = "Home Desktop 200"
bom_fg.pop(4)
self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
# operation no mentioed in material table not matching with operation table
bom_fg = copy.deepcopy(base_bom_fg)
bom_fg.pop(4)
bom_fg[2]["operation_no"] = 2
self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
def test_bom(self):
gc_wrapper = webnotes.insert(DocList(base_bom_grandchild))
gc_wrapper.submit()
bom_child = copy.deepcopy(base_bom_child)
bom_child[2]["bom_no"] = gc_wrapper.doc.name
child_wrapper = webnotes.insert(DocList(bom_child))
child_wrapper.submit()
bom_fg = copy.deepcopy(base_bom_fg)
bom_fg[4]["bom_no"] = child_wrapper.doc.name
fg_wrapper = webnotes.insert(DocList(bom_fg))
fg_wrapper.load_from_db()
self.check_bom_cost(fg_wrapper)
self.check_flat_bom(fg_wrapper, child_wrapper, gc_wrapper)
def check_bom_cost(self, fg_wrapper):
expected_values = {
"operating_cost": 15,
"raw_material_cost": 640,
"total_cost": 655
test_records = [
[
{
"doctype": "BOM",
"item": "_Test FG Item",
"quantity": 1.0,
"is_active": 1,
"is_default": 1,
"docstatus": 1
},
{
"doctype": "BOM Item",
"item_code": "_Test Item",
"parentfield": "bom_materials",
"qty": 1.0,
"rate": 5000.0,
"amount": 5000.0,
"stock_uom": "No."
},
{
"doctype": "BOM Item",
"item_code": "_Test Item Home Desktop 100",
"parentfield": "bom_materials",
"qty": 2.0,
"rate": 1000.0,
"amount": 2000.0,
"stock_uom": "No."
}
]
]
for key in expected_values:
self.assertEqual(flt(expected_values[key]), flt(fg_wrapper.doc.fields.get(key)))
def check_flat_bom(self, fg_wrapper, child_wrapper, gc_wrapper):
expected_flat_bom_items = {
("Home Desktop 300", fg_wrapper.doc.name): (2, 20),
("Home Desktop 100", fg_wrapper.doc.name): (1, 300),
("Home Desktop 300", gc_wrapper.doc.name): (30, 10)
}
self.assertEqual(len(fg_wrapper.doclist.get({"parentfield": "flat_bom_details"})), 3)
for key, val in expected_flat_bom_items.items():
flat_bom = fg_wrapper.doclist.get({"parentfield": "flat_bom_details",
"item_code": key[0], "parent_bom": key[1]})[0]
self.assertEqual(val, (flat_bom.qty, flat_bom.rate))
def tearDown(self):
webnotes.conn.rollback()
# import webnotes.model
# from webnotes.utils import nowdate, flt
# from accounts.utils import get_fiscal_year
# from webnotes.model.doclist import DocList
# import copy
#
# company = webnotes.conn.get_default("company")
#
#
# def load_data():
#
# # create default warehouse
# if not webnotes.conn.exists("Warehouse", "Default Warehouse"):
# webnotes.insert({"doctype": "Warehouse",
# "warehouse_name": "Default Warehouse",
# "warehouse_type": "Stores"})
#
# # create UOM: Nos.
# if not webnotes.conn.exists("UOM", "Nos"):
# webnotes.insert({"doctype": "UOM", "uom_name": "Nos"})
#
# from webnotes.tests import insert_test_data
# # create item groups and items
# insert_test_data("Item Group",
# sort_fn=lambda ig: (ig[0].get('parent_item_group'), ig[0].get('name')))
# insert_test_data("Item")
#
# base_bom_fg = [
# {"doctype": "BOM", "item": "Android Jack D", "quantity": 1,
# "is_active": "Yes", "is_default": 1, "uom": "Nos"},
# {"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
# "opn_description": "Development", "hour_rate": 10, "time_in_mins": 90},
# {"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1,
# "qty": 2, "rate": 20, "stock_uom": "Nos", "parentfield": "bom_materials"},
# {"doctype": "BOM Item", "item_code": "Home Desktop 100", "operation_no": 1,
# "qty": 1, "rate": 300, "stock_uom": "Nos", "parentfield": "bom_materials"},
# {"doctype": "BOM Item", "item_code": "Nebula 7", "operation_no": 1,
# "qty": 5, "stock_uom": "Nos", "parentfield": "bom_materials"},
# ]
#
# base_bom_child = [
# {"doctype": "BOM", "item": "Nebula 7", "quantity": 5,
# "is_active": "Yes", "is_default": 1, "uom": "Nos"},
# {"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
# "opn_description": "Development"},
# {"doctype": "BOM Item", "item_code": "Android Jack S", "operation_no": 1,
# "qty": 10, "stock_uom": "Nos", "parentfield": "bom_materials"}
# ]
#
# base_bom_grandchild = [
# {"doctype": "BOM", "item": "Android Jack S", "quantity": 1,
# "is_active": "Yes", "is_default": 1, "uom": "Nos"},
# {"doctype": "BOM Operation", "operation_no": 1, "parentfield": "bom_operations",
# "opn_description": "Development"},
# {"doctype": "BOM Item", "item_code": "Home Desktop 300", "operation_no": 1,
# "qty": 3, "rate": 10, "stock_uom": "Nos", "parentfield": "bom_materials"}
# ]
#
#
# class TestPurchaseReceipt(unittest.TestCase):
# def setUp(self):
# webnotes.conn.begin()
# load_data()
#
# def test_bom_validation(self):
# # show throw error bacause bom no missing for sub-assembly item
# bom_fg = copy.deepcopy(base_bom_fg)
# self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
#
# # main item is not a manufacturing item
# bom_fg = copy.deepcopy(base_bom_fg)
# bom_fg[0]["item"] = "Home Desktop 200"
# bom_fg.pop(4)
# self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
#
# # operation no mentioed in material table not matching with operation table
# bom_fg = copy.deepcopy(base_bom_fg)
# bom_fg.pop(4)
# bom_fg[2]["operation_no"] = 2
# self.assertRaises(webnotes.ValidationError, webnotes.insert, DocList(bom_fg))
#
#
# def test_bom(self):
# gc_wrapper = webnotes.insert(DocList(base_bom_grandchild))
# gc_wrapper.submit()
#
# bom_child = copy.deepcopy(base_bom_child)
# bom_child[2]["bom_no"] = gc_wrapper.doc.name
# child_wrapper = webnotes.insert(DocList(bom_child))
# child_wrapper.submit()
#
# bom_fg = copy.deepcopy(base_bom_fg)
# bom_fg[4]["bom_no"] = child_wrapper.doc.name
# fg_wrapper = webnotes.insert(DocList(bom_fg))
# fg_wrapper.load_from_db()
#
# self.check_bom_cost(fg_wrapper)
#
# self.check_flat_bom(fg_wrapper, child_wrapper, gc_wrapper)
#
# def check_bom_cost(self, fg_wrapper):
# expected_values = {
# "operating_cost": 15,
# "raw_material_cost": 640,
# "total_cost": 655
# }
#
# for key in expected_values:
# self.assertEqual(flt(expected_values[key]), flt(fg_wrapper.doc.fields.get(key)))
#
# def check_flat_bom(self, fg_wrapper, child_wrapper, gc_wrapper):
# expected_flat_bom_items = {
# ("Home Desktop 300", fg_wrapper.doc.name): (2, 20),
# ("Home Desktop 100", fg_wrapper.doc.name): (1, 300),
# ("Home Desktop 300", gc_wrapper.doc.name): (30, 10)
# }
#
# self.assertEqual(len(fg_wrapper.doclist.get({"parentfield": "flat_bom_details"})), 3)
#
# for key, val in expected_flat_bom_items.items():
# flat_bom = fg_wrapper.doclist.get({"parentfield": "flat_bom_details",
# "item_code": key[0], "parent_bom": key[1]})[0]
# self.assertEqual(val, (flat_bom.qty, flat_bom.rate))
#
#
# def tearDown(self):
# webnotes.conn.rollback()

View File

@ -17,64 +17,8 @@
from __future__ import unicode_literals
import unittest
import webnotes
import copy
from webnotes.model.bean import Bean
from webnotes.model.doc import Document
from webnotes.utils import flt
sql = webnotes.conn.sql
class TestItem(unittest.TestCase):
def setUp(self):
webnotes.conn.begin()
def tearDown(self):
webnotes.conn.rollback()
def testInsert(self):
d = Bean()
count_before = flt(sql("select count(*) from tab"+_doctype)[0][0])
if docok:
for i in docok:
d.doc = i
d.children = None
d.doc.fields['__islocal']=1
d.save(1)
count_after = flt(sql("select count(*) from tab"+_doctype)[0][0])
self.assertTrue(count_before+len(docok)==count_after)
def testFailAssert(self):
if docnotok:
with self.assertRaises(Exception) as context:
d = Bean()
d.doc = docnotok[0]
d.children = None
d.doc.fields['__islocal']=1
d.save(1)
# Test Data
tabOK = [
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Ink', 'default_warehouse': None, 'item_name': 'Gel Ink', 'item_group': 'Ink', 'item_code': 'GELINK', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'},
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Refill', 'default_warehouse': None, 'item_name': 'Gel Refill', 'item_group': 'Refill', 'item_code': 'GELREF', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'},
{'is_purchase_item': None, 'is_pro_applicable': 'No', 'is_manufactured_item': None, 'description': 'Gel Pen', 'default_warehouse': None, 'item_name': 'Gel Pen', 'item_group': 'Pen', 'item_code': 'GELPEN', 'is_sub_contracted_item': None, 'is_stock_item': 'Yes', 'stock_uom': 'Nos', 'docstatus': '0'}
]
tabNotOK = [
{'is_purchase_item': None, 'is_pro_applicable': None, 'is_manufactured_item': None, 'description': 'F Ink', 'default_warehouse': None, 'item_name': 'F Ink', 'item_group': 'F Ink', 'item_code': None, 'is_sub_contracted_item': None, 'is_stock_item': 'No', 'stock_uom': 'Nos', 'docstatus': '0'}
]
_doctype = 'Item'
for i in tabOK: i['doctype']=_doctype
for i in tabNotOK: i['doctype']=_doctype
docok = [Document(fielddata=r) for r in tabOK]
docnotok = [Document(fielddata=r) for r in tabNotOK]
test_ignore = ["BOM"]
test_records = [
[{
@ -164,4 +108,23 @@ test_records = [
"is_sub_contracted_item": "No",
"stock_uom": "_Test UOM"
}],
[{
"doctype": "Item",
"item_code": "_Test FG Item",
"item_name": "_Test FG Item",
"description": "_Test FG Item",
"item_group": "_Test Item Group Desktops",
"is_stock_item": "Yes",
"is_asset_item": "No",
"has_batch_no": "No",
"has_serial_no": "No",
"is_purchase_item": "Yes",
"is_sales_item": "Yes",
"is_service_item": "No",
"is_sample_item": "No",
"inspection_required": "No",
"is_pro_applicable": "Yes",
"is_sub_contracted_item": "Yes",
"stock_uom": "_Test UOM"
}],
]

View File

@ -18,10 +18,10 @@ from __future__ import unicode_literals
import webnotes
from webnotes.utils import cstr, flt, cint
from webnotes.model.doc import addchild
from webnotes.model.bean import getlist
from webnotes.model.code import get_obj
from webnotes import msgprint
from webnotes.model.doc import Document
from webnotes import msgprint, _
sql = webnotes.conn.sql
@ -89,8 +89,6 @@ class DocType(BuyingController):
webnotes.msgprint("Another Purchase Receipt using the same Challan No. already exists.\
Please enter a valid Challan No.", raise_exception=1)
# update valuation rate
def update_valuation_rate(self):
for d in self.doclist.get({"parentfield": "purchase_receipt_details"}):
if d.qty:
@ -99,8 +97,6 @@ class DocType(BuyingController):
else:
d.valuation_rate = 0.0
#check in manage account if purchase order required or not.
# ====================================================================================
def po_required(self):
res = sql("select value from `tabSingles` where doctype = 'Global Defaults' and field = 'po_required'")
if res and res[0][0]== 'Yes':
@ -109,8 +105,6 @@ class DocType(BuyingController):
msgprint("Purchse Order No. required against item %s"%d.item_code)
raise Exception
# validate
def validate(self):
super(DocType, self).validate()
@ -136,16 +130,15 @@ class DocType(BuyingController):
# update valuation rate
self.update_valuation_rate()
# sub-contracting
self.validate_for_subcontracting()
self.update_raw_materials_supplied()
# On Update
# ----------------------------------------------------------------------------------------------------
def on_update(self):
if self.doc.rejected_warehouse:
for d in getlist(self.doclist,'purchase_receipt_details'):
d.rejected_warehouse = self.doc.rejected_warehouse
self.update_rw_material_detail()
get_obj('Stock Ledger').scrub_serial_nos(self)
self.scrub_rejected_serial_nos()
@ -303,118 +296,66 @@ class DocType(BuyingController):
self.make_gl_entries()
def validate_for_subcontracting(self):
if self.sub_contracted_items and self.purchase_items and not self.doc.is_subcontracted:
webnotes.msgprint(_("""Please enter whether Purchase Recipt is made for subcontracting
or purchasing, in 'Is Subcontracted' field"""), raise_exception=1)
if self.doc.is_subcontracted and not self.doc.supplier_warehouse:
webnotes.msgprint(_("Please Enter Supplier Warehouse for subcontracted Items"),
raise_exception=1)
def update_raw_materials_supplied(self):
self.doclist = self.doc.clear_table(self.doclist, 'pr_raw_material_details')
if self.sub_contracted_items:
for item in self.doclist.get({"parentfield": "purchase_receipt_details"}):
if item.item_code in self.sub_contracted_items:
self.add_bom_items(item)
def update_rw_material_detail(self):
def add_bom_items(self, d):
bom_items = self.get_items_from_default_bom(d.item_code)
raw_materials_cost = 0
for item in bom_items:
required_qty = flt(item.qty_consumed_per_unit) * flt(d.qty) * flt(d.conversion_factor)
self.doclist.append({
"parentfield": "pr_raw_material_details",
"doctype": "Purchase Receipt Item Supplied",
"reference_name": d.name,
"bom_detail_no": item.name,
"main_item_code": d.item_code,
"rm_item_code": item.item_code,
"description": item.description,
"stock_uom": item.stock_uom,
"required_qty": required_qty,
"consumed_qty": required_qty,
"conversion_factor": d.conversion_factor,
"rate": item.rate,
"amount": required_qty * flt(item.rate)
})
raw_materials_cost += required_qty * flt(item.rate)
d.rm_supp_cost = raw_materials_cost
for d in getlist(self.doclist,'purchase_receipt_details'):
item_det = sql("select is_sub_contracted_item, is_purchase_item from `tabItem` where name = '%s'"%(d.item_code))
if item_det[0][0] == 'Yes':
if item_det[0][1] == 'Yes':
if not self.doc.is_subcontracted:
msgprint("Please enter whether purchase receipt to be made for subcontracting or for purchase in 'Is Subcontracted' field .")
raise Exception
if self.doc.is_subcontracted == 'Yes':
if not self.doc.supplier_warehouse:
msgprint("Please Enter Supplier Warehouse for subcontracted Items")
raise Exception
self.add_bom(d)
else:
self.doclist = self.doc.clear_table(self.doclist,'pr_raw_material_details',1)
self.doc.save()
elif item_det[0][1] == 'No':
if not self.doc.supplier_warehouse:
msgprint("Please Enter Supplier Warehouse for subcontracted Items")
raise Exception
self.add_bom(d)
self.delete_irrelevant_raw_material()
#---------------calculate amt in Purchase Receipt Item Supplied-------------
self.calculate_amount(d)
def add_bom(self, d):
#----- fetching default bom from Bill of Materials instead of Item Master --
bom_det = sql("""select t1.item, t2.item_code, t2.qty_consumed_per_unit,
t2.moving_avg_rate, t2.value_as_per_mar, t2.stock_uom, t2.name, t2.description
def get_items_from_default_bom(self, item_code):
# print webnotes.conn.sql("""select name from `tabBOM` where item = '_Test FG Item'""")
bom_items = sql("""select t2.item_code, t2.qty_consumed_per_unit,
t2.rate, t2.stock_uom, t2.name, t2.description
from `tabBOM` t1, `tabBOM Item` t2
where t2.parent = t1.name and t1.item = %s and t1.is_default = 1
and t1.docstatus = 1 and t2.docstatus =1 and t1.is_active = 1""", d.item_code)
if not bom_det:
msgprint("No default BOM exists for item: %s" % d.item_code)
raise Exception
else:
#-------------- add child function--------------------
chgd_rqd_qty = []
for i in bom_det:
and t1.docstatus = 1 and t1.is_active = 1""", item_code, as_dict=1)
if not bom_items:
msgprint(_("No default BOM exists for item: ") + item_code, raise_exception=1)
return bom_items
if i and not sql("select name from `tabPurchase Receipt Item Supplied` where reference_name = '%s' and bom_detail_no = '%s' and parent = '%s' " %(d.name, i[6], self.doc.name)):
rm_child = addchild(self.doc, 'pr_raw_material_details', 'Purchase Receipt Item Supplied', self.doclist)
rm_child.reference_name = d.name
rm_child.bom_detail_no = i and i[6] or ''
rm_child.main_item_code = i and i[0] or ''
rm_child.rm_item_code = i and i[1] or ''
rm_child.description = i and i[7] or ''
rm_child.stock_uom = i and i[5] or ''
rm_child.rate = i and flt(i[3]) or flt(i[4])
rm_child.conversion_factor = d.conversion_factor
rm_child.required_qty = flt(i and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
rm_child.consumed_qty = flt(i and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
rm_child.amount = flt(flt(rm_child.consumed_qty)*flt(rm_child.rate))
rm_child.save()
chgd_rqd_qty.append(cstr(i[1]))
else:
act_qty = flt(i and flt(i[2]) or 0) * flt(d.qty) * flt(d.conversion_factor)
for pr_rmd in getlist(self.doclist, 'pr_raw_material_details'):
if i and i[6] == pr_rmd.bom_detail_no and (flt(act_qty) != flt(pr_rmd.required_qty) or i[1] != pr_rmd.rm_item_code or i[7] != pr_rmd.description):
chgd_rqd_qty.append(cstr(i[1]))
pr_rmd.main_item_code = i[0]
pr_rmd.rm_item_code = i[1]
pr_rmd.description = i[7]
pr_rmd.stock_uom = i[5]
pr_rmd.required_qty = flt(act_qty)
pr_rmd.consumed_qty = flt(act_qty)
pr_rmd.rate = i and flt(i[3]) or flt(i[4])
pr_rmd.amount = flt(flt(pr_rmd.consumed_qty)*flt(pr_rmd.rate))
pr_rmd.save()
if chgd_rqd_qty:
msgprint("Please check consumed quantity for Raw Material Item Code: '%s'in Raw materials Detail Table" % ((len(chgd_rqd_qty) > 1 and ','.join(chgd_rqd_qty[:-1]) +' and ' + cstr(chgd_rqd_qty[-1:][0]) ) or cstr(chgd_rqd_qty[0])))
# Delete irrelevant raw material from PR Raw material details
#--------------------------------------------------------------
def delete_irrelevant_raw_material(self):
for d in getlist(self.doclist,'pr_raw_material_details'):
if not sql("select name from `tabPurchase Receipt Item` where name = '%s' and parent = '%s' and item_code = '%s'" % (d.reference_name, self.doc.name, d.main_item_code)):
d.parent = 'old_par:'+self.doc.name
d.save()
def calculate_amount(self, d):
amt = 0
for i in getlist(self.doclist,'pr_raw_material_details'):
if(i.reference_name == d.name):
#if i.consumed_qty == 0:
# msgprint("consumed qty cannot be 0. Please Enter consumed qty ")
#raise Exception
i.amount = flt(i.consumed_qty)* flt(i.rate)
amt += i.amount
d.rm_supp_cost = amt
d.save()
# --------------- Back Flush function called on submit and on cancel from update stock
def bk_flush_supp_wh(self, is_submit):
for d in getlist(self.doclist, 'pr_raw_material_details'):
#--------- -ve quantity is passed as raw material qty has to be decreased when PR is submitted and it has to be increased when PR is cancelled
# negative quantity is passed as raw material qty has to be decreased
# when PR is submitted and it has to be increased when PR is cancelled
consumed_qty = - flt(d.consumed_qty)
self.make_sl_entry(d, self.doc.supplier_warehouse, flt(consumed_qty), 0, is_submit)
# get current_stock
# ----------------
def get_current_stock(self):
for d in getlist(self.doclist, 'pr_raw_material_details'):
if self.doc.supplier_warehouse:

View File

@ -64,6 +64,17 @@ class TestPurchaseReceipt(unittest.TestCase):
self.assertEquals(expected_values[i][2], gle.credit)
webnotes.defaults.set_global_default("auto_inventory_accounting", 0)
def test_subcontracting(self):
pr = webnotes.bean(copy=test_records[1])
pr.run_method("calculate_taxes_and_totals")
pr.insert()
self.assertEquals(pr.doclist[1].rm_supp_cost, 70000.0)
self.assertEquals(len(pr.doclist.get({"parentfield": "pr_raw_material_details"})), 2)
test_dependencies = ["BOM"]
test_records = [
[
@ -129,4 +140,36 @@ test_records = [
"tax_amount": 150.0,
},
],
[
{
"company": "_Test Company",
"conversion_rate": 1.0,
"currency": "INR",
"doctype": "Purchase Receipt",
"fiscal_year": "_Test Fiscal Year 2013",
"posting_date": "2013-02-12",
"posting_time": "15:33:30",
"is_subcontracted": "Yes",
"supplier_warehouse": "_Test Warehouse",
"supplier": "_Test Supplier",
"net_total": 5000.0,
"grand_total": 5000.0,
},
{
"conversion_factor": 1.0,
"description": "_Test FG Item",
"doctype": "Purchase Receipt Item",
"item_code": "_Test FG Item",
"item_name": "_Test FG Item",
"parentfield": "purchase_receipt_details",
"received_qty": 10.0,
"qty": 10.0,
"rejected_qty": 0.0,
"import_rate": 500.0,
"amount": 5000.0,
"warehouse": "_Test Warehouse",
"stock_uom": "Nos",
"uom": "_Test UOM",
}
],
]