Merge pull request #26011 from marination/subcontracted-rm-to-transfer-report

fix: Report Subcontracted Raw Materials to be Transferred
This commit is contained in:
Marica 2021-06-11 17:50:30 +05:30 committed by GitHub
commit d7d5c4c329
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 96 deletions

View File

@ -9,10 +9,10 @@ def execute(filters=None):
if filters.from_date >= filters.to_date: if filters.from_date >= filters.to_date:
frappe.msgprint(_("To Date must be greater than From Date")) frappe.msgprint(_("To Date must be greater than From Date"))
data = []
columns = get_columns() columns = get_columns()
get_data(data , filters) data = get_data(filters)
return columns, data
return columns, data or []
def get_columns(): def get_columns():
return [ return [
@ -21,13 +21,12 @@ def get_columns():
"fieldtype": "Link", "fieldtype": "Link",
"fieldname": "purchase_order", "fieldname": "purchase_order",
"options": "Purchase Order", "options": "Purchase Order",
"width": 150 "width": 200
}, },
{ {
"label": _("Date"), "label": _("Date"),
"fieldtype": "Date", "fieldtype": "Date",
"fieldname": "date", "fieldname": "date",
"hidden": 1,
"width": 150 "width": 150
}, },
{ {
@ -41,97 +40,58 @@ def get_columns():
"label": _("Item Code"), "label": _("Item Code"),
"fieldtype": "Data", "fieldtype": "Data",
"fieldname": "rm_item_code", "fieldname": "rm_item_code",
"width": 100 "width": 150
}, },
{ {
"label": _("Required Quantity"), "label": _("Required Quantity"),
"fieldtype": "Float", "fieldtype": "Float",
"fieldname": "r_qty", "fieldname": "reqd_qty",
"width": 100 "width": 150
}, },
{ {
"label": _("Transferred Quantity"), "label": _("Transferred Quantity"),
"fieldtype": "Float", "fieldtype": "Float",
"fieldname": "t_qty", "fieldname": "transferred_qty",
"width": 100 "width": 200
}, },
{ {
"label": _("Pending Quantity"), "label": _("Pending Quantity"),
"fieldtype": "Float", "fieldtype": "Float",
"fieldname": "p_qty", "fieldname": "p_qty",
"width": 100 "width": 150
} }
] ]
def get_data(data, filters): def get_data(filters):
po = get_po(filters) po_rm_item_details = get_po_items_to_supply(filters)
po_transferred_qty_map = frappe._dict(get_transferred_quantity([v.name for v in po]))
sub_items = get_purchase_order_item_supplied([v.name for v in po]) data = []
for row in po_rm_item_details:
transferred_qty = row.get("transferred_qty") or 0
if transferred_qty < row.get("reqd_qty", 0):
pending_qty = frappe.utils.flt(row.get("reqd_qty", 0) - transferred_qty)
row.p_qty = pending_qty if pending_qty > 0 else 0
data.append(row)
for order in po: return data
for item in sub_items:
if order.name == item.parent and order.name in po_transferred_qty_map and \
item.required_qty != po_transferred_qty_map.get(order.name).get(item.rm_item_code):
transferred_qty = po_transferred_qty_map.get(order.name).get(item.rm_item_code) \
if po_transferred_qty_map.get(order.name).get(item.rm_item_code) else 0
row ={
'purchase_order': item.parent,
'date': order.transaction_date,
'supplier': order.supplier,
'rm_item_code': item.rm_item_code,
'r_qty': item.required_qty,
't_qty':transferred_qty,
'p_qty':item.required_qty - transferred_qty
}
data.append(row) def get_po_items_to_supply(filters):
return frappe.db.get_all(
return(data) "Purchase Order",
fields=[
def get_po(filters): "name as purchase_order",
record_filters = [ "transaction_date as date",
["is_subcontracted", "=", "Yes"], "supplier as supplier",
["supplier", "=", filters.supplier], "`tabPurchase Order Item Supplied`.rm_item_code as rm_item_code",
["transaction_date", "<=", filters.to_date], "`tabPurchase Order Item Supplied`.required_qty as reqd_qty",
["transaction_date", ">=", filters.from_date], "`tabPurchase Order Item Supplied`.supplied_qty as transferred_qty"
["docstatus", "=", 1]
]
return frappe.get_all("Purchase Order", filters=record_filters, fields=["name", "transaction_date", "supplier"])
def get_transferred_quantity(po_name):
stock_entries = get_stock_entry(po_name)
stock_entries_detail = get_stock_entry_detail([v.name for v in stock_entries])
po_transferred_qty_map = {}
for entry in stock_entries:
for details in stock_entries_detail:
if details.parent == entry.name:
details["Purchase_order"] = entry.purchase_order
if entry.purchase_order not in po_transferred_qty_map:
po_transferred_qty_map[entry.purchase_order] = {}
po_transferred_qty_map[entry.purchase_order][details.item_code] = details.qty
else:
po_transferred_qty_map[entry.purchase_order][details.item_code] = po_transferred_qty_map[entry.purchase_order].get(details.item_code, 0) + details.qty
return po_transferred_qty_map
def get_stock_entry(po):
return frappe.get_all("Stock Entry", filters=[
('purchase_order', 'IN', po),
('stock_entry_type', '=', 'Send to Subcontractor'),
('docstatus', '=', 1)
], fields=["name", "purchase_order"])
def get_stock_entry_detail(se):
return frappe.get_all("Stock Entry Detail", filters=[
["parent", "in", se]
], ],
fields=["parent", "item_code", "qty"]) filters = [
["Purchase Order", "per_received", "<", "100"],
def get_purchase_order_item_supplied(po): ["Purchase Order", "is_subcontracted", "=", "Yes"],
return frappe.get_all("Purchase Order Item Supplied", filters=[ ["Purchase Order", "supplier", "=", filters.supplier],
('parent', 'IN', po) ["Purchase Order", "transaction_date", "<=", filters.to_date],
], fields=['parent', 'rm_item_code', 'required_qty']) ["Purchase Order", "transaction_date", ">=", filters.from_date],
["Purchase Order", "docstatus", "=", 1]
]
)

View File

@ -12,34 +12,68 @@ import json, frappe, unittest
class TestSubcontractedItemToBeTransferred(unittest.TestCase): class TestSubcontractedItemToBeTransferred(unittest.TestCase):
def test_pending_and_transferred_qty(self): def test_pending_and_transferred_qty(self):
po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes') po = create_purchase_order(item_code='_Test FG Item', is_subcontracted='Yes', supplier_warehouse="_Test Warehouse 1 - _TC")
# Material Receipt of RMs
make_stock_entry(item_code='_Test Item', target='_Test Warehouse - _TC', qty=100, basic_rate=100) make_stock_entry(item_code='_Test Item', target='_Test Warehouse - _TC', qty=100, basic_rate=100)
make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse - _TC', qty=100, basic_rate=100) make_stock_entry(item_code='_Test Item Home Desktop 100', target='_Test Warehouse - _TC', qty=100, basic_rate=100)
transfer_subcontracted_raw_materials(po.name)
col, data = execute(filters=frappe._dict({'supplier': po.supplier, se = transfer_subcontracted_raw_materials(po)
'from_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=-10)),
'to_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=10))})) col, data = execute(filters=frappe._dict(
self.assertEqual(data[0]['purchase_order'], po.name) {
self.assertIn(data[0]['rm_item_code'], ['_Test Item', '_Test Item Home Desktop 100']) 'supplier': po.supplier,
self.assertIn(data[0]['p_qty'], [9, 18]) 'from_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=-10)),
self.assertIn(data[0]['t_qty'], [1, 2]) 'to_date': frappe.utils.get_datetime(frappe.utils.add_to_date(po.transaction_date, days=10))
}
))
po.reload()
po_data = [row for row in data if row.get('purchase_order') == po.name]
self.assertEqual(len(po_data), 2)
self.assertIn(po_data[0]['rm_item_code'], ['_Test Item', '_Test Item Home Desktop 100'])
self.assertIn(po_data[0]['p_qty'], [9, 18])
self.assertIn(po_data[0]['transferred_qty'], [1, 2])
self.assertEqual(data[1]['purchase_order'], po.name) self.assertEqual(data[1]['purchase_order'], po.name)
self.assertIn(data[1]['rm_item_code'], ['_Test Item', '_Test Item Home Desktop 100']) self.assertIn(data[1]['rm_item_code'], ['_Test Item', '_Test Item Home Desktop 100'])
self.assertIn(data[1]['p_qty'], [9, 18]) self.assertIn(data[1]['p_qty'], [9, 18])
self.assertIn(data[1]['t_qty'], [1, 2]) self.assertIn(data[1]['transferred_qty'], [1, 2])
se.cancel()
po.cancel()
def transfer_subcontracted_raw_materials(po): def transfer_subcontracted_raw_materials(po):
rm_item = [ rm_item = [
{'item_code': '_Test Item', 'rm_item_code': '_Test Item', 'item_name': '_Test Item', 'qty': 1, {
'warehouse': '_Test Warehouse - _TC', 'rate': 100, 'amount': 100, 'stock_uom': 'Nos'}, 'name': po.supplied_items[0].name,
{'item_code': '_Test Item Home Desktop 100', 'rm_item_code': '_Test Item Home Desktop 100', 'item_name': '_Test Item Home Desktop 100', 'qty': 2, 'item_code': '_Test Item Home Desktop 100',
'warehouse': '_Test Warehouse - _TC', 'rate': 100, 'amount': 200, 'stock_uom': 'Nos'}] 'rm_item_code': '_Test Item Home Desktop 100',
'item_name': '_Test Item Home Desktop 100',
'qty': 2,
'warehouse': '_Test Warehouse - _TC',
'rate': 100,
'amount': 200,
'stock_uom': 'Nos'
},
{
'name': po.supplied_items[1].name,
'item_code': '_Test Item',
'rm_item_code': '_Test Item',
'item_name': '_Test Item',
'qty': 1,
'warehouse': '_Test Warehouse - _TC',
'rate': 100,
'amount': 100,
'stock_uom': 'Nos'
}
]
rm_item_string = json.dumps(rm_item) rm_item_string = json.dumps(rm_item)
se = frappe.get_doc(make_rm_stock_entry(po, rm_item_string)) se = frappe.get_doc(make_rm_stock_entry(po.name, rm_item_string))
se.from_warehouse = '_Test Warehouse 1 - _TC' se.from_warehouse = '_Test Warehouse - _TC'
se.to_warehouse = '_Test Warehouse 1 - _TC' se.to_warehouse = '_Test Warehouse - _TC'
se.stock_entry_type = 'Send to Subcontractor' se.stock_entry_type = 'Send to Subcontractor'
se.save() se.save()
se.submit() se.submit()
return se