Skip to content

Commit

Permalink
Merge pull request #32274 from s-aga-r/fix/stock-entry/subcontract-or…
Browse files Browse the repository at this point in the history
…der-item-reference

fix: `po_detail` or `sco_rm_detail` not getting set while while mapping SE
  • Loading branch information
s-aga-r authored Sep 19, 2022
2 parents efc9553 + a4db9ab commit 377576f
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 230 deletions.
121 changes: 1 addition & 120 deletions erpnext/buying/doctype/purchase_order/purchase_order.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,131 +295,12 @@ erpnext.buying.PurchaseOrderController = class PurchaseOrderController extends e
}

make_stock_entry() {
var items = $.map(cur_frm.doc.items, function(d) { return d.bom ? d.item_code : false; });
var me = this;

if(items.length >= 1){
me.raw_material_data = [];
me.show_dialog = 1;
let title = __('Transfer Material to Supplier');
let fields = [
{fieldtype:'Section Break', label: __('Raw Materials')},
{fieldname: 'sub_con_rm_items', fieldtype: 'Table', label: __('Items'),
fields: [
{
fieldtype:'Data',
fieldname:'item_code',
label: __('Item'),
read_only:1,
in_list_view:1
},
{
fieldtype:'Data',
fieldname:'rm_item_code',
label: __('Raw Material'),
read_only:1,
in_list_view:1
},
{
fieldtype:'Float',
read_only:1,
fieldname:'qty',
label: __('Quantity'),
read_only:1,
in_list_view:1
},
{
fieldtype:'Data',
read_only:1,
fieldname:'warehouse',
label: __('Reserve Warehouse'),
in_list_view:1
},
{
fieldtype:'Float',
read_only:1,
fieldname:'rate',
label: __('Rate'),
hidden:1
},
{
fieldtype:'Float',
read_only:1,
fieldname:'amount',
label: __('Amount'),
hidden:1
},
{
fieldtype:'Link',
read_only:1,
fieldname:'uom',
label: __('UOM'),
hidden:1
}
],
data: me.raw_material_data,
get_data: function() {
return me.raw_material_data;
}
}
]

me.dialog = new frappe.ui.Dialog({
title: title, fields: fields
});

if (me.frm.doc['supplied_items']) {
me.frm.doc['supplied_items'].forEach((item, index) => {
if (item.rm_item_code && item.main_item_code && item.required_qty - item.supplied_qty != 0) {
me.raw_material_data.push ({
'name':item.name,
'item_code': item.main_item_code,
'rm_item_code': item.rm_item_code,
'item_name': item.rm_item_code,
'qty': item.required_qty - item.supplied_qty,
'warehouse':item.reserve_warehouse,
'rate':item.rate,
'amount':item.amount,
'stock_uom':item.stock_uom
});
me.dialog.fields_dict.sub_con_rm_items.grid.refresh();
}
})
}

me.dialog.get_field('sub_con_rm_items').check_all_rows()

me.dialog.show()
this.dialog.set_primary_action(__('Transfer'), function() {
me.values = me.dialog.get_values();
if(me.values) {
me.values.sub_con_rm_items.map((row,i) => {
if (!row.item_code || !row.rm_item_code || !row.warehouse || !row.qty || row.qty === 0) {
let row_id = i+1;
frappe.throw(__("Item Code, warehouse and quantity are required on row {0}", [row_id]));
}
})
me._make_rm_stock_entry(me.dialog.fields_dict.sub_con_rm_items.grid.get_selected_children())
me.dialog.hide()
}
});
}

me.dialog.get_close_btn().on('click', () => {
me.dialog.hide();
});

}

_make_rm_stock_entry(rm_items) {
frappe.call({
method:"erpnext.controllers.subcontracting_controller.make_rm_stock_entry",
args: {
subcontract_order: cur_frm.doc.name,
rm_items: rm_items,
order_doctype: cur_frm.doc.doctype
}
,
},
callback: function(r) {
var doclist = frappe.model.sync(r.message);
frappe.set_route("Form", doclist[0].doctype, doclist[0].name);
Expand Down
139 changes: 82 additions & 57 deletions erpnext/controllers/subcontracting_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@ def get_item_details(items):
item = frappe.qb.DocType("Item")
item_list = (
frappe.qb.from_(item)
.select(item.item_code, item.description, item.allow_alternative_item)
.select(item.item_code, item.item_name, item.description, item.allow_alternative_item)
.where(item.name.isin(items))
.run(as_dict=True)
)
Expand All @@ -783,68 +783,93 @@ def get_item_details(items):


@frappe.whitelist()
def make_rm_stock_entry(subcontract_order, rm_items, order_doctype="Subcontracting Order"):
rm_items_list = rm_items
def make_rm_stock_entry(
subcontract_order, rm_items=None, order_doctype="Subcontracting Order", target_doc=None
):
if subcontract_order:
subcontract_order = frappe.get_doc(order_doctype, subcontract_order)

if isinstance(rm_items, str):
rm_items_list = json.loads(rm_items)
elif not rm_items:
frappe.throw(_("No Items available for transfer"))
if not rm_items:
if not subcontract_order.supplied_items:
frappe.throw(_("No item available for transfer."))

if rm_items_list:
fg_items = list(set(item["item_code"] for item in rm_items_list))
else:
frappe.throw(_("No Items selected for transfer"))
rm_items = subcontract_order.supplied_items

if subcontract_order:
subcontract_order = frappe.get_doc(order_doctype, subcontract_order)
fg_item_code_list = list(
set(item.get("main_item_code") or item.get("item_code") for item in rm_items)
)

if fg_items:
items = tuple(set(item["rm_item_code"] for item in rm_items_list))
item_wh = get_item_details(items)
if fg_item_code_list:
rm_item_code_list = tuple(set(item.get("rm_item_code") for item in rm_items))
item_wh = get_item_details(rm_item_code_list)

stock_entry = frappe.new_doc("Stock Entry")
stock_entry.purpose = "Send to Subcontractor"
if order_doctype == "Purchase Order":
stock_entry.purchase_order = subcontract_order.name
else:
stock_entry.subcontracting_order = subcontract_order.name
stock_entry.supplier = subcontract_order.supplier
stock_entry.supplier_name = subcontract_order.supplier_name
stock_entry.supplier_address = subcontract_order.supplier_address
stock_entry.address_display = subcontract_order.address_display
stock_entry.company = subcontract_order.company
stock_entry.to_warehouse = subcontract_order.supplier_warehouse
stock_entry.set_stock_entry_type()

if order_doctype == "Purchase Order":
rm_detail_field = "po_detail"
else:
rm_detail_field = "sco_rm_detail"

for item_code in fg_items:
for rm_item_data in rm_items_list:
if rm_item_data["item_code"] == item_code:
rm_item_code = rm_item_data["rm_item_code"]
items_dict = {
rm_item_code: {
rm_detail_field: rm_item_data.get("name"),
"item_name": rm_item_data["item_name"],
"description": item_wh.get(rm_item_code, {}).get("description", ""),
"qty": rm_item_data["qty"],
"from_warehouse": rm_item_data["warehouse"],
"stock_uom": rm_item_data["stock_uom"],
"serial_no": rm_item_data.get("serial_no"),
"batch_no": rm_item_data.get("batch_no"),
"main_item_code": rm_item_data["item_code"],
"allow_alternative_item": item_wh.get(rm_item_code, {}).get("allow_alternative_item"),
field_no_map, rm_detail_field = "purchase_order", "sco_rm_detail"
if order_doctype == "Purchase Order":
field_no_map, rm_detail_field = "subcontracting_order", "po_detail"

if target_doc and target_doc.get("items"):
target_doc.items = []

stock_entry = get_mapped_doc(
order_doctype,
subcontract_order.name,
{
order_doctype: {
"doctype": "Stock Entry",
"field_map": {
"to_warehouse": "supplier_warehouse",
},
"field_no_map": [field_no_map],
"validation": {
"docstatus": ["=", 1],
},
},
},
target_doc,
ignore_child_tables=True,
)

stock_entry.purpose = "Send to Subcontractor"

if order_doctype == "Purchase Order":
stock_entry.purchase_order = subcontract_order.name
else:
stock_entry.subcontracting_order = subcontract_order.name

stock_entry.set_stock_entry_type()

for fg_item_code in fg_item_code_list:
for rm_item in rm_items:

if rm_item.get("main_item_code") or rm_item.get("item_code") == fg_item_code:
rm_item_code = rm_item.get("rm_item_code")

items_dict = {
rm_item_code: {
rm_detail_field: rm_item.get("name"),
"item_name": rm_item.get("item_name")
or item_wh.get(rm_item_code, {}).get("item_name", ""),
"description": item_wh.get(rm_item_code, {}).get("description", ""),
"qty": rm_item.get("qty")
or max(rm_item.get("required_qty") - rm_item.get("total_supplied_qty"), 0),
"from_warehouse": rm_item.get("warehouse") or rm_item.get("reserve_warehouse"),
"to_warehouse": subcontract_order.supplier_warehouse,
"stock_uom": rm_item.get("stock_uom"),
"serial_no": rm_item.get("serial_no"),
"batch_no": rm_item.get("batch_no"),
"main_item_code": fg_item_code,
"allow_alternative_item": item_wh.get(rm_item_code, {}).get("allow_alternative_item"),
}
}
}
stock_entry.add_to_stock_entry_detail(items_dict)
return stock_entry.as_dict()
else:
frappe.throw(_("No Items selected for transfer"))
return subcontract_order.name

stock_entry.add_to_stock_entry_detail(items_dict)

if target_doc:
return stock_entry
else:
return stock_entry.as_dict()
else:
frappe.throw(_("No Items selected for transfer."))


def add_items_in_ste(
Expand Down
8 changes: 7 additions & 1 deletion erpnext/stock/doctype/stock_entry/stock_entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -625,14 +625,20 @@ frappe.ui.form.on('Stock Entry', {
purchase_order: (frm) => {
if (frm.doc.purchase_order) {
frm.set_value("subcontracting_order", "");
erpnext.utils.map_current_doc({
method: 'erpnext.stock.doctype.stock_entry.stock_entry.get_items_from_subcontract_order',
source_name: frm.doc.purchase_order,
target_doc: frm,
freeze: true,
});
}
},

subcontracting_order: (frm) => {
if (frm.doc.subcontracting_order) {
frm.set_value("purchase_order", "");
erpnext.utils.map_current_doc({
method: 'erpnext.stock.doctype.stock_entry.stock_entry.get_items_from_subcontracting_order',
method: 'erpnext.stock.doctype.stock_entry.stock_entry.get_items_from_subcontract_order',
source_name: frm.doc.subcontracting_order,
target_doc: frm,
freeze: true,
Expand Down
51 changes: 9 additions & 42 deletions erpnext/stock/doctype/stock_entry/stock_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -1945,6 +1945,8 @@ def add_to_stock_entry_detail(self, item_dict, bom_no=None):
se_child.is_finished_item = item_row.get("is_finished_item", 0)
se_child.is_scrap_item = item_row.get("is_scrap_item", 0)
se_child.is_process_loss = item_row.get("is_process_loss", 0)
se_child.po_detail = item_row.get("po_detail")
se_child.sco_rm_detail = item_row.get("sco_rm_detail")

for field in [
self.subcontract_data.rm_detail_field,
Expand Down Expand Up @@ -2591,50 +2593,15 @@ def get_supplied_items(


@frappe.whitelist()
def get_items_from_subcontracting_order(source_name, target_doc=None):
def post_process(source, target):
target.stock_entry_type = target.purpose = "Send to Subcontractor"
target.subcontracting_order = source_name
def get_items_from_subcontract_order(source_name, target_doc=None):
from erpnext.controllers.subcontracting_controller import make_rm_stock_entry

if target.items:
target.items = []
if isinstance(target_doc, str):
target_doc = frappe.get_doc(json.loads(target_doc))

warehouses = {}
for item in source.items:
warehouses[item.name] = item.warehouse

for item in source.supplied_items:
target.append(
"items",
{
"s_warehouse": warehouses.get(item.reference_name),
"t_warehouse": source.supplier_warehouse,
"subcontracted_item": item.main_item_code,
"item_code": item.rm_item_code,
"qty": max(item.required_qty - item.total_supplied_qty, 0),
"transfer_qty": item.required_qty,
"uom": item.stock_uom,
"stock_uom": item.stock_uom,
"conversion_factor": 1,
"sco_rm_detail": item.name,
},
)

target_doc = get_mapped_doc(
"Subcontracting Order",
source_name,
{
"Subcontracting Order": {
"doctype": "Stock Entry",
"field_no_map": ["purchase_order"],
"validation": {
"docstatus": ["=", 1],
},
},
},
target_doc,
post_process,
ignore_child_tables=True,
order_doctype = "Purchase Order" if target_doc.purchase_order else "Subcontracting Order"
target_doc = make_rm_stock_entry(
subcontract_order=source_name, order_doctype=order_doctype, target_doc=target_doc
)

return target_doc
Expand Down
Loading

0 comments on commit 377576f

Please sign in to comment.